python拼接參數不確定的SQL時防注入問題--條件語句最后拼入


先貼完整代碼,個人寫的一般,請諒解。

  @coroutine
    def put(self):
        # 修改區域信息
        req_body = self.request.body
        assert req_body, 'request body is None'
        info = loads(req_body)
        _id = info.get('_id')
        name = info.get('name')
        address = info.get('address')
        assert _id, '_id argument not given'
        assert name or address, 'argument lost'
        _sql = "UPDATE area SET %s"
        param = []
        _param = []
        if name:
            param.append("name=%s")
            _param.append(name)
        if address:
            param.append("address=%s")
            _param.append(address)
        _param.append(_id)
        sql = _sql % (",".join(param)) + " WHERE _id=%s"
        with StoreContext() as store:
            ctx = yield store.begin()
            try:
                yield ctx.execute(sql, tuple(_param))
                yield ctx.commit()
            except:
                app_log.error("update area failed, body={0}, details: {1}".format(info, traceback.format_exc()))
                yield ctx.rollback()
        self.write_rows()

通常在寫代碼時會有以下幾個誤入點。

誤入點1:

由於需要修改的字段不確定,在初始化SQL時不要將WHERE條件加入,像下面這么會產生SQL注入

_sql = "UPDATE area SET %s WHERE _id=%s"
param.append("name=%s")
param.append("address=%s")
_sql % (",".join(param), _id)
# 如果_id傳入的是_id="1 or 1=1",_sql則會變成
'UPDATE area SET name=%s,address=%s WHERE _id=1 or 1=1'

誤入點2:

在拼接字段時,直接將傳入的值拼入字符串中,像下面這樣會有問題

param.append("name=%s" % name)
# 如果遇到中文時,字段的內容會變成下面這樣
"name=u'\\u534e\\u4e1c1',address=u'http://10.0.0.111'"
# 這樣就不說了,直接拋錯

最好的做法是將要拼入的字段和對應的值放在兩個不同的列表中,將SQL拼完整后,調用execute方法。

_sql = 'UPDATE area SET name=%s,address=%s WHERE _id=%s'
_param = ("xxx", "xxx", "xxx")
# execute方法會自己處理注入問題
ctx.execute(sql, _param)

今天主要是遇到拼接時出現中文亂碼問題,最好的處理方式是將所有的值放到execute方法里面,不要畫蛇添足的自己去拼接,產生不必要的麻煩。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM