MySQL中的Python,MATCH和注入攻击

时间:2011-08-31 08:37:26

标签: python mysql sql-injection match

  1. 来自MySQL的MATCH是否容易受到注入攻击? 例如:

    """SELECT * 
         FROM myTable 
         WHERE MATCH(myColumnName) AGAINST(%s) 
         ORDER BY id 
         LIMIT 20""" % query
    

    似乎允许任意字符串,这看起来很糟糕。

  2. 如果是这样,我反而尝试过 - 遵循Python文档中的示例 -

    t = (query,)
    statement = """SELECT * 
                     FROM myTable 
                     WHERE MATCH(myColumnName) AGAINST(?) 
                     ORDER BY id 
                     LIMIT 20"""
    cursor.execute(statement, t)
    

    但没有返回任何内容 - 即使字符串query返回上面(1)中的命中。那是为什么?

  3. 在2)中,使用占位符%s而不是?会返回结果。为什么这比1)更安全(如果有的话)?例如。使用查询字符串,我总是可以用query=')...'关闭字符串和括号,然后继续query=') OR otherColumnName LIKE '%hello%' --

  4. 因此,删除除罗马字符或数字之外的所有内容的查询字符串是否足够?

4 个答案:

答案 0 :(得分:4)

在注射时,您使用的运算符,函数,从句或任何其他host-language项都没有多大关系。注入是混合数据和语言语句的问题,当您将数据插入到语句中时会发生这种情况。准备好的语句参数将数据和语句分开,因此它们不容易被注入。

对于参数的?%sCursor.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字符串 - 如果包含所有非字母数字字符(特别是'))。