微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 MySQL Connector cursor.execute() params 应该是变量?

如何解决为什么 MySQL Connector cursor.execute() params 应该是变量?

我正在尝试使用 Python 的 MysqL 连接器为我的 API 创建过滤器。 我处理用户生成查询,如下所示:

user_type_id > 1 并在 WHERE 子句中使用它们。

由于查询来自用户,我想将它们作为参数传递给 cursor.execute(query,params) 以避免注入。

当我跑步时

cursor.execute("SELECT * FROM table WHERE %s > %s",('user_type_id',1))

它不能如我所愿。

Documentation 声明

params 绑定到操作中的变量。

因为他们不让 params 包含变量以外的任何东西(例如列名),我想这是有原因的。

你能告诉我只允许变量作为参数传递的原因吗? 我也想知道这个问题有没有好的解决方法

解决方法

您希望用户能够生成三样东西:

  • 字段(不能被参数化,看起来那些对应于你的数据库中的列名)
  • 比较器(不能参数化)
  • 字段的值 (可以参数化)

幸运的是,字段和比较器的值集非常有限。您可以构建一个列表,然后在将它们连接到查询之前自己验证它们吗?

类似于:

def create_query(
    field: str,comparator: str,field_value: int
) -> typing.Tuple[str,typing.Tuple]:
    allowed_fields = ("user_type_id","user_age")  # for example
    allowed_comparators = (">","<","=")
    if field not in allowed_fields:
        raise ValueError(f"{field!r} not in allowed_fields {allowed_fields!r}")
    if comparator not in allowed_comparators:
        raise ValueError(
            f"{comparator!r} not in allowed_comparators {allowed_comparators!r}"
        )

    return f"SELECT * FROM table WHERE {field} {comparator} %s",(field_value,)

以上内容不能被 SQL 注入,因为您在追加到查询之前要检查严格的白名单,并且您可以枚举这些字符串的所有可能值。您只需要非常警惕,您可以检查所有可能的字段。

注意:虽然我认为这是做这样的事情的唯一方法并且它是安全的,但我还没有在使用它的生产系统上工作过,我非常想知道是否有人可以找到问题上面的函数

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?