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