来自MySQL的MATCH
是否容易受到注入攻击?
例如:
"""SELECT *
FROM myTable
WHERE MATCH(myColumnName) AGAINST(%s)
ORDER BY id
LIMIT 20""" % query
似乎允许任意字符串,这看起来很糟糕。
如果是这样,我反而尝试过 - 遵循Python文档中的示例 -
t = (query,)
statement = """SELECT *
FROM myTable
WHERE MATCH(myColumnName) AGAINST(?)
ORDER BY id
LIMIT 20"""
cursor.execute(statement, t)
但没有返回任何内容 - 即使字符串query
返回上面(1)中的命中。那是为什么?
在2)中,使用占位符%s
而不是?
会返回结果。为什么这比1)更安全(如果有的话)?例如。使用查询字符串,我总是可以用query=')...'
关闭字符串和括号,然后继续query=') OR otherColumnName LIKE '%hello%' --
。
因此,删除除罗马字符或数字之外的所有内容的查询字符串是否足够?
答案 0 :(得分:4)
在注射时,您使用的运算符,函数,从句或任何其他host-language项都没有多大关系。注入是混合数据和语言语句的问题,当您将数据插入到语句中时会发生这种情况。准备好的语句参数将数据和语句分开,因此它们不容易被注入。
对于参数的?
与%s
,Cursor.execute的MySQLdb文档说明如下:
execute(self, query, args=None)[...]
注意:如果args是序列,则必须将%s用作查询中的参数占位符。如果使用映射,则必须使用%(键)s作为占位符。
答案 1 :(得分:1)
当使用带参数的参数化语句时,MySQLdb会转义参数并使用Python字符串格式化将这些参数重新插入到参数化语句中。然后将单个字符串语句发送到服务器。 您依靠MySQLdb正确转义参数以防止SQL注入的能力:
MySQLdb的/ cursors.py:
def execute(self, query, args=None):
...
if args is not None:
query = query % db.literal(args)
相反,oursql sends queries and data to the server completely separately。 它不依赖于转义数据。这应该更安全。
答案 2 :(得分:1)
第一种方法不正确,因为它使用基本的python字符串格式,不会转义查询字符串。
第二种方法是向服务器发送简单查询的首选方法,它将正确地转义查询。
你只是有一个简单的错误。您需要将AGAINST(?)
替换为AGAINST(%s)
此信息也可在python DbApi FAQ
中找到答案 3 :(得分:0)
就我的目的而言,它足以消除query
字符串 - 如果包含所有非字母数字字符(特别是'
和)
)。