簡體   English   中英

為什么 MySQL 連接器 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 綁定到操作中的變量。

由於他們不允許 params 包含除變量(例如列名)以外的任何內容,我想這是有原因的。

你能告訴我只允許變量作為參數傳遞的原因嗎? 我也想知道這個問題有沒有好的解決方法?

您希望用戶能夠生成三件事:

  • 字段(不能參數化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 注入,因為您在查詢 append 之前檢查了嚴格的白名單,並且您可以枚舉這些字符串的所有可能值。 您只需要非常警惕,您可以檢查所有可能的字段。

注意:雖然我認為這是做這樣的事情的唯一方法並且它是安全的,但我還沒有在使用它的生產系統上工作過,我非常想知道是否有人能找到上面的 function 的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM