提问人:Marilynb 提问时间:2/2/2022 更新时间:2/3/2022 访问量:194
如何正确保护 GUI 应用程序免受 SQL 注入
How to protect correctly GUI application from SQL injection
问:
我正在开发一个 GUI 应用程序 (pyQt),用户将在其中添加我想存储在本地数据库 (sqlite) 中的数据。我是这个领域的初学者,即使应用程序没有连接或存储的数据不敏感,我也很想知道如何阻止可能来自用户的“SQL 查询”。 例如,GUI 允许用户添加新物种的名称,我实现了一个控制器,该控制器获取输入的文本,将其传递给 re.sub 以删除任何特殊字符,然后我准备一个查询,传递干净的数据并执行。如果用户输入类似于“SELECT * FROM SPECIES”之类的东西,它就可以工作,用户不能访问数据库中 SPECIES 表中的所有数据存储,但我在我的数据库中得到“SELECTFROMSPECIES”作为新数据,这不是一个好的物种名称。我正在考虑在我的clean_data函数中实现条件,例如“如果条目中的'SELECT':做某事”。另一个问题是,如果用户条目是一个很好的物种名称,但有一些空格作为“Mus musculus”,我的clean_data函数会删除这个空格并存储在数据库“Musmusculus”中。我想知道是否有更干净的方法来避免这些行为并正确解析查询以允许新用户输入,同时保持数据库干净。 提前感谢您的建议。
在这里,我的控制器函数用于清理和存储数据库中的数据:
def clean_data(self, data):
clean_data = re.sub('[\W_]+', '', data)
return clean_data
def get_data(self, data):
clean_data = self.clean_data(data)
self.query.prepare("INSERT INTO SPECIES (specie_name) "
"VALUES (:s_name)")
self.query.bindValue(":s_name", str(clean_data))
self.query.exec()
答:
我不熟悉PyQt的数据库处理,但是单独调用和调用的全部意义在于它将为您清理值。任何信誉良好的数据库库都会这样做。prepare
bindValue
事实证明,找到PyQt文档非常困难,但我确实在Real Python上找到了一个页面,上面写着:
在 PyQt 中,结合 、 和 并完全保护您免受 SQL 注入攻击......
.prepare()
.bindValue()
.addBindValue()
这证实了我上面所说的话。
与此相关的是,如果您尝试使用删除非字母字符等技巧来清理数据,则可能会遇到麻烦。要么你会错过一些危险的东西,要么你会因为删除完全安全的文本而惹恼用户。第二个问题可能会导致更复杂的消毒尝试,这将使第一个问题更有可能发生。
以下是更多信息,主要是对评论的回应:
- 占位符的作用。使用占位符时,用户的数据仍会直接添加到查询中。但它并没有直接添加到 SQL 语句中:它被适当地引用在前面,以防止 SQL 注入攻击。
- 占位符名称。占位符名称是任意的(受 SQL 语法的限制)。它们可能与字段名称相对应,也可能不合适。他们不必这样做,但有时它使它更容易。事实上,在链接的示例中,占位符名称确实与字段名称相对应。
- 占位符名称作为键。占位符名称确实可以被视为键,并且在准备查询之前不需要定义(实际上,无法定义)。
- 验证。验证是一个与 SQL 注入完全不同的问题。后者可以由图书馆处理,但前者取决于你,因为只有你知道什么是有效的,什么是无效的。 (一旦你清楚地知道什么是有效的,你就可以编写代码来强制执行这一点,如果你需要帮助,请随时问另一个问题。
评论