为什么 MySQL Connector cursor.execute() 参数应该是变量?
Why should MySQL Connector cursor.execute() params be variables?
我正在尝试使用 python 的 MySQL 连接器为我的 API 创建一个过滤器。
我处理用户生成的查询,如下所示:
user_type_id > 1
并在 WHERE
子句中使用它们。
由于查询来自用户,我想将它们作为参数传递给 cursor.execute(query, params) 以避免注入。
当我运行
cursor.execute("SELECT * FROM table WHERE %s > %s", ('user_type_id', 1))
它没有像我想要的那样工作。
params are bound to the variables in the operation.
因为他们不让参数包含变量以外的任何东西(例如列名),我想这是有原因的。
你能告诉我为什么只允许变量作为参数传递吗?
我也想知道这个问题有没有好的解决方法?
您希望用户能够生成三样东西:
- 字段(不能参数化a,看起来那些对应于您数据库中的列名)
- 比较器(不能参数化)
- 字段的值
(可参数化)
幸运的是,字段和比较器的值集非常有限。您可以构建一个列表,然后在将它们连接到查询之前自己验证它们吗?
类似于:
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 注入,因为您在附加到查询之前要检查严格的白名单,并且您可以枚举这些字符串的所有可能值。您只需要非常警惕,您就可以检查所有可能的字段。
注意:虽然我认为这是执行此类操作的唯一方法并且它是安全的,但我还没有在使用它的生产系统上工作过,我非常想知道是否有人可以找到一个上面的函数有问题
我正在尝试使用 python 的 MySQL 连接器为我的 API 创建一个过滤器。 我处理用户生成的查询,如下所示:
user_type_id > 1
并在 WHERE
子句中使用它们。
由于查询来自用户,我想将它们作为参数传递给 cursor.execute(query, params) 以避免注入。
当我运行
cursor.execute("SELECT * FROM table WHERE %s > %s", ('user_type_id', 1))
它没有像我想要的那样工作。
params are bound to the variables in the operation.
因为他们不让参数包含变量以外的任何东西(例如列名),我想这是有原因的。
你能告诉我为什么只允许变量作为参数传递吗? 我也想知道这个问题有没有好的解决方法?
您希望用户能够生成三样东西:
- 字段(不能参数化a,看起来那些对应于您数据库中的列名)
- 比较器(不能参数化)
- 字段的值 (可参数化)
幸运的是,字段和比较器的值集非常有限。您可以构建一个列表,然后在将它们连接到查询之前自己验证它们吗?
类似于:
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 注入,因为您在附加到查询之前要检查严格的白名单,并且您可以枚举这些字符串的所有可能值。您只需要非常警惕,您就可以检查所有可能的字段。
注意:虽然我认为这是执行此类操作的唯一方法并且它是安全的,但我还没有在使用它的生产系统上工作过,我非常想知道是否有人可以找到一个上面的函数有问题