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方法里面,不要画蛇添足的自己去拼接,产生不必要的麻烦。

原文地址:https://www.cnblogs.com/liown/p/6900497.html