【问题标题】:how to safely generate a SQL LIKE statement using python db-api如何使用 python db-api 安全地生成 SQL LIKE 语句
【发布时间】:2011-01-07 00:52:10
【问题描述】:

我正在尝试使用 python 的 db-api 组装以下 SQL 语句:

SELECT x FROM myTable WHERE x LIKE 'BEGINNING_OF_STRING%';

BEGINNING_OF_STRING 应该是一个 python var,可以通过 DB-API 安全地填写。我试过了

beginningOfString = 'abc'

cursor.execute('SELECT x FROM myTable WHERE x LIKE '%s%', beginningOfString) 
cursor.execute('SELECT x FROM myTable WHERE x LIKE '%s%%', beginningOfString)

我没有想法;这样做的正确方法是什么?

【问题讨论】:

    标签: python sql sql-like python-db-api


    【解决方案1】:

    编辑:

    正如 Brian 和 Thomas 所说,更好的方法是使用:

    beginningOfString += '%'
    cursor.execute("SELECT x FROM myTable WHERE x LIKE ?", (beginningOfString,) )
    

    因为第一种方法让您容易受到 SQL 注入攻击。


    留作历史:

    试试:

    cursor.execute("SELECT x FROM myTable WHERE x LIKE '%s%%'" % beginningOfString)
    

    【讨论】:

    • -1 "SELECT x FROM myTable WHERE x LIKE '%s%%'" % "doom' ; drop table x; select '" 哎呀?
    • @Brian;非常有效的观点!我专注于语法错误;我不应该认为beginning 是干净的数据。谢谢你的收获!
    • -1 已删除。但是,您仍然有语法错误。为您的字符串使用双引号,您无需转义单引号。
    • 已编辑以修复语法错误和 Thomas 指出的错误。
    • 我试过用?而不是 %s 与 mysql-connector-python 并没有
    【解决方案2】:

    注意Sqlite3 文档:

    通常您的 SQL 操作需要 使用 Python 变量中的值。 你不应该组合你的查询 使用 Python 的字符串操作 因为这样做是不安全的;它使 您的程序易受 SQL 攻击 注入攻击。

    改为使用 DB-API 的参数 替代。放 ?作为占位符 无论您想在哪里使用值,以及 然后提供一个值的元组作为 光标的第二个参数 执行()方法。 (其他数据库 模块可能使用不同的 占位符,例如 %s 或 :1。)对于 示例:

    # Never do this -- insecure!
    symbol = 'IBM'
    c.execute("... where symbol = '%s'" % symbol)
    
    # Do this instead
    t = (symbol,)
    c.execute('select * from stocks where symbol=?', t)
    
    # Larger example
    for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
              ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
              ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
             ]:
        c.execute('insert into stocks values (?,?,?,?,?)', t)
    

    我想你想要这个:

    cursor.execute('SELECT x FROM myTable WHERE x LIKE '%?%', (beginningOfString,) )
    

    【讨论】:

    • @Thomas:为什么?除了我使用'%?%' 而不是'?%'(他在他想要的查询中并不完全一致)之外,我看不出有什么问题。
    • 问题是 ?被您传递的实际参数的 quoted 版本替换。因此,例如 "';DROP TABLE x;SELECT '" (注意那里的单个 双引号),你最终会得到这个明显错误的查询: SELECT x FROM myTable WHERE x LIKE '% ';删除表 x;选择“%”
    • 我不关注。 DB-API 的参数替换不能解决这个问题吗?
    【解决方案3】:

    如果可以的话最好把参数和sql分开。 然后,您可以让 db 模块负责正确引用参数。

    sql='SELECT x FROM myTable WHERE x LIKE %s'
    args=[beginningOfString+'%']
    cursor.execute(sql,args)
    

    【讨论】:

    • @~unutbu:谢谢,就这样。我没有想到只是将 % 附加到字符串本身 之前 通过 db-api 将其作为 arg 传递。
    猜你喜欢
    • 2011-12-05
    • 1970-01-01
    • 2010-12-06
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多