Python:连接 MySQL 和执行查询的最佳实践和最安全方法

发布于 2024-12-12 07:02:05 字数 195 浏览 0 评论 0原文

在 MySQL 上运行查询最安全的方法是什么?我知道 MySQL 和 SQL 注入所涉及的危险。

但是,我不知道应该如何运行查询以防止注入其他用户(网络客户端)可以操作的变量。我曾经编写过自己的转义函数,但显然这是“未完成”。

我应该使用什么以及如何使用它通过 python 在 MySQL 数据库上安全地查询和插入而不冒 MySQL 注入的风险?

What is the safest way to run queries on MySQL? I am aware of the dangers involved with MySQL and SQL injection.

However, I do not know how I should run my queries to prevent injection on the variables to which other users (webclients) can manipulate. I used to write my own escape function, but apparently this is "not-done".

What should I use and how should I use it to query and do inserts safely on a MySQL database through python without risking MySQL injection?

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

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

发布评论

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

评论(2

踏月而来 2024-12-19 07:02:05

为了避免注入,请使用 execute%s 代替每个变量,然后通过列表或元组传递值作为 execute 的第二个参数>。这是文档中的示例

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

请注意,这是使用 < strong>逗号,而不是%(这将是直接字符串替换,而不是转义)。 不要这样做

c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""" % (max_price,))

此外,如果参数是字符串,则不得在位置保持符周围使用单引号 ('%s'),因为驱动程序提供了这些字符串。

To avoid injections, use execute with %s in place of each variable, then pass the value via a list or tuple as the second parameter of execute. Here is an example from the documentation:

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

Note that this is using a comma, not % (which would be a direct string substitution, not escaped). Don't do this:

c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""" % (max_price,))

In addition, you must not use single quotes around the position holder ('%s') if the parameter is a string as the driver provides these.

最冷一天 2024-12-19 07:02:05

作为 Bruno 答案的扩展,您的 MySQL 客户端库可能支持几种不同格式中的任何一种来指定命名参数。从 PEP 249 (DB-API) 中,您可以编写如下查询:

'qmark'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = ?", (lumberjack,))

'numeric '

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :1", (lumberjack,))

'named'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :jack", {'jack': lumberjack})

'format'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %s", (lumberjack,))

'pyformat'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %(jack)s", {'jack': lumberjack})

您可以通过查看 paramstyle 模块级变量来了解您的客户端库支持哪些:

>>> clientlibrary.paramstyle
'pyformat'

上述任何选项都应该在处理您的可能不安全的数据。正如布鲁诺指出的那样,请不要尝试自己插入参数。常用的客户端库在正确处理数据方面比我们凡人要好得多。

As an expansion of Bruno's answer, your MySQL client library may support any of several different formats for specifying named parameters. From PEP 249 (DB-API), you could write your queries like:

'qmark'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = ?", (lumberjack,))

'numeric'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :1", (lumberjack,))

'named'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :jack", {'jack': lumberjack})

'format'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %s", (lumberjack,))

'pyformat'

>>> cursor.execute("SELECT spam FROM eggs WHERE lumberjack = %(jack)s", {'jack': lumberjack})

You can see which your client library supports by looking at the paramstyle module-level variable:

>>> clientlibrary.paramstyle
'pyformat'

Any of the above options should Do The Right Thing with regards to handling your possibly insecure data. As Bruno pointed out, please don't ever try to insert parameters yourself. The commonly-used client libraries are much better at processing data correctly than we mere mortals will ever be.

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