sql注入

作者: 简写_ | 来源:发表于2017-09-25 11:44 被阅读0次

    错误根源

    每次在将动态内容与sql语句拼接时都要考虑sql注入的风险。问题根源在于没有将数据与代码(sql语句)进行分离,这个和xss很类似。示例:

    sql = 'SELECT * FROM bugs WHERE bug_id = ' + '1; DELETE * FROM users;'
    session.execute(sql)
    

    防御方法

    1. 过滤输入

    过滤用户输入的不合法字符
    如整数类型转换

    bug_id = int(bug_id)
    sql = 'SELECT * FROM bugs WHERE bug_id = %d;' % bug_id
    

    如动态按列排序,假如表中字段名称只包含字母,数字和下划线

    import re
    order_by = re.sub(r'[^\w_]', '', order_by)
    sql = 'SELECT * FROM bugs ORDER BY %s;' % order_by
    # 用户即使输入 order_by = 'user; DELETE * FROM xxx;' 也会被转换为order_by = 'userDELETEFROMxxx'
    # 执行错误但没有安全问题
    

    2. 参数化动态内容

    强有力的防御手段,对于动态数据十分有效。使用查询参数将数据与SQL表达式分离。参数化查询,数据库先将带?的SQL表达式编译好之后,才套用参数执行。如sqlite:

    cursor.execute('INSERT INTO people VALUES (?, ?)', (who, age))
    

    3. 数据与代码隔离

    对于表名,字段名,sql关键字需要动态化的,可以使用隔离方式。建立用户输入与sql动态部分的映射关系,如字典。让用户界面与查询细节解耦,同时不将用户输入与sql语句拼接,降低风险。如:

      field_map = {
        'age': 'people_age',
        'gender': 'people_gender'
        ...
      }
      # order_by = 'age' 
      order_by = field_map.get(order_by, 'default')
      sql = 'SELECT * FROM people ORDER BY %s;' % order_by
    

    相关文章

      网友评论

          本文标题:sql注入

          本文链接:https://www.haomeiwen.com/subject/nzurextx.html