Python 中的 MySQL、MATCH 和注入攻击

发布于 2024-12-02 03:50:02 字数 775 浏览 2 评论 0原文

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

    <前><代码>"""选择 * 来自我的表 WHERE MATCH(myColumnName) AGAINST(%s) 按 ID 排序 LIMIT 20""" % 查询

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

  2. 如果是这样,我已经尝试了 - 以下是 Python 文档中的示例 -

    t = (查询,)
    语句=“”“选择* 
                     来自我的表 
                     哪里匹配(myColumnName)反对(?) 
                     按 ID 排序 
                     限制 20"""
    光标.执行(语句,t)
    

    但没有返回任何内容 - 即使字符串 query 返回了上面 (1) 中的结果。为什么会这样?

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

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

  1. Is MATCH from MySQL also vulnerable to injection attack?
    For example:

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

    seems to allow arbitrary strings, which looks bad.

  2. If so, I've instead tried - following examples in the Python docs -

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

    but nothing is returned - even when the string query returned hits in (1) above. Why is that?

  3. In 2), using the placeholder %s instead of ? returns results. Why is this safer than 1) (if at all)? E.g. with the query string I can always close off a string and parenthesis with query=')...' and continue query=') OR otherColumnName LIKE '%hello%' --.

Therefore, is it enough to strip query strings of everything but roman characters or numerals?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

阳光①夏 2024-12-09 03:50:02

什么运算符、函数、子句或任何其他主机并不重要您在注入时使用的语言术语。注入是混合数据和语言语句的问题,当您将数据插入到语句中时就会发生这种情况。准备好的语句参数将数据和语句分开,因此它们不易受到注入的影响。

至于 ?%s 的参数,MySQLdb 文档 Cursor.execute 表示以下内容:

执行(self,query,args=None)

[...]

注意:如果 args 是序列,则必须使用 %s 作为查询中的参数占位符。如果使用映射,则必须使用 %(key)s 作为占位符。

It doesn't much matter what operators, functions, clauses or any other host-language terms you're using when it comes to injection. Injection is a matter of mixing data and language statements, which happens when you interpolate data into a statement. Prepared statement parameters keep data and statements separate, so they're not vulnerable to injection.

As for ? versus %s for parameters, the MySQLdb documentation for Cursor.execute says the following:

    execute(self, query, args=None)

[...]

Note: If args is a sequence, then %s must be used as the parameter placeholder in the query. If a mapping is used, %(key)s must be used as the placeholder.

凉宸 2024-12-09 03:50:02

当使用带有参数的参数化语句时,MySQLdb 会转义参数并使用 Python 字符串格式将这些参数重新插入到参数化语句中。然后将单个字符串语句发送到服务器。
您依赖 MySQLdb 正确转义参数以防止 SQL 注入的能力:

MySQLdb/cursors.py:

def execute(self, query, args=None):
    ...
    if args is not None:
        query = query % db.literal(args)

相反, oursql 完全独立地将查询和数据发送到服务器
它不依赖于转义数据。这样应该更安全。

When using a parameterized statement with arguments, MySQLdb escapes the arguments and uses Python string formating to re-insert those arguments into the parametrized statement. A single string statement is then sent to the server.
You are relying on MySQLdb's ability to properly escape arguments to protect against SQL injection:

MySQLdb/cursors.py:

def execute(self, query, args=None):
    ...
    if args is not None:
        query = query % db.literal(args)

In contrast, oursql sends queries and data to the server completely separately.
It does not rely on escaping the data. This should be even safer.

情话墙 2024-12-09 03:50:02

第一种方法不正确,因为它使用基本的 python 字符串格式,不会转义查询字符串。

第二种方法是向服务器发送简单查询的首选方法,它将正确转义查询。

你只是有一个简单的错误。您需要将 AGAINST(?) 替换为 AGAINST(%s)

该信息也可以在 python DbApi 常见问题解答

The first method is not correct since it uses basic python string formatting, that will not escape the query string.

The second method is the preferred method of sending a simple query to the server and it will properly escape the query.

You just have a simple bug. You need to replace AGAINST(?) with AGAINST(%s)

The information is also found in the python DbApi FAQ

茶底世界 2024-12-09 03:50:02

就我的目的而言,清理 query 字符串就足够了 - 去除所有非字母数字字符(特别是 '))。

For my purposes it's enough to sanitise the query string - strip if of all non-alphanumeric characters (in particular ' and )).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文