首页 > 解决方案 > 当列是动态的,如何避免 UPDATE 语句中的 SQL 注入 SET %s=%s

问题描述

我尝试在 pymysql 中使用 UPDATE 语句来更新某些列的值,其中self.key, self.value,self.id是三个变量。

cur.execute("UPDATE environment_history SET {key}=%s WHERE id=%s".format(key=self.key),
                    (self.value, self.id)
                    )

在上面的代码中,这为 SQL 注入留下了机会。我们只需要发布一些这样的数据

{"id":"23151","key":"uuid='ac211';#","value":"abcde"}

这将更新所有行,这可能更危险。我必须阻止这种情况发生。

我尝试了一些不切实际的解决方案,其中之一是:

cur.execute("UPDATE environment_history SET %s=%s WHERE id=%s",
                    (self.key,self.value, self.id)
                    )

但是,pymysql 会将列名转义为\'uuid\'.

这是一个 SQL 语法错误,因为SET col_name=3SET `col_name`=3 是正确的。

那么,如何避免这种 SQL 注入呢?

尝试self.key手动替换和转义是我能想到的唯一选择,但这听起来不是一种优雅的方式。

我的数据库是 MySQL。

有任何想法吗?谢谢!

标签: pythonmysqlsql-injectionpymysql

解决方案


我建议过滤self.key到一个已知值,然后才将其用作列。例如:

keywords = ["uuid", "other", "keywords"]
if self.key in keywords:
    column_name = self.key
else:
    column_name = keywords[0]

推荐阅读