Python 防止 SQL 注入:过滤非法字符与参数化查询实践
本文探讨 Python 中防止 SQL 注入的两种常见方法:过滤非法字符与使用参数化查询。通过实例演示如何过滤特殊字符,并重点解析参数化查询中占位符的正确使用方式,确保数据库操作的安全性。
直接拼接字符串的风险
在 Python 开发中,向数据库插入数据时,如果直接将用户输入的字符串拼接到 SQL 语句中,会存在极大的安全隐患。特殊字符(如单引号 '、百分号 % 等)可能导致 SQL 注入攻击,从而破坏数据库的完整性。
方案一:过滤非法字符
一种基础的防御手段是过滤掉用户输入中的非法字符。以下代码定义了一个 sql_filter 函数,用于移除字符串中可能引发 SQL 注入的特殊符号:
#coding:utf8
#在开发过程中,要对前端传过来的数据进行验证,防止sql注入攻击,其中的一个方案就是过滤用户传过来的非法的字符
def sql_filter(sql, max_length=20):
dirty_stuff = ["\"", "\\", "/", "*", "'", "=", "-", "#", ";", "<", ">>", "+", "%", "$", "(", ")", "%", "@","!"]
for stuff in dirty_stuff:
sql = sql.replace(stuff, "")
return sql[:max_length]
username = "1234567890!@#!@#!@#$%======$%"
username = sql_filter(username) # SQL注入
print username
# 输出结果是:1234567890该函数通过遍历 dirty_stuff 列表,将字符串中的特殊字符替换为空字符串,并限制最大长度。虽然这种方法能过滤掉部分风险字符,但它并非防止 SQL 注入的最佳实践,且可能误伤合法的用户输入。
方案二:使用参数化查询
更推荐的做法是使用数据库驱动提供的参数化查询功能。参数化查询将 SQL 语句与数据分离,从根本上避免了 SQL 注入的风险。
错误的使用方式
许多开发者在使用参数化查询时,容易犯以下错误:在 SQL 语句中为占位符 %s 添加单引号,或者使用字符串格式化操作符 % 进行拼接。
cur=db.cursor()
sql = "INSERT INTO test2(cid, author, content) VALUES (1, '1', 'aa')"
cur.execute(sql,())上述代码虽然使用了 execute 方法,但 SQL 语句是硬编码的,没有体现参数化查询的优势。再看另一个常见错误:
cur=db.cursor()
sql = "INSERT INTO test2(cid, author, content) VALUES (%s, '%s', '%s')"
sql=sql%('2','2','bb')
cur.execute(sql,())这里在 %s 前后添加了单引号,并且使用了 Python 的字符串格式化操作符 % 进行拼接。这种做法会导致数据库驱动无法正确识别参数,甚至可能引发 SQL 注入漏洞。
正确的使用方式
正确的参数化查询应当将占位符 %s 直接放在 SQL 语句中,不要添加单引号,并将数据作为元组传递给 execute 方法:
cur=db.cursor()
sql = "INSERT INTO test2(cid, author, content) VALUES (%s, %s, %s)"
cur.execute(sql,('3','3','c%c'))在上述代码中,%s 前后没有单引号,数据 ('3','3','c%c') 作为元组传递给 execute 方法。数据库驱动会自动处理数据的转义和类型转换,确保 SQL 语句的安全性。

总结
防止 SQL 注入的关键在于使用参数化查询,而不是依赖手动过滤非法字符。在 Python 中,正确使用数据库驱动提供的参数化查询功能,可以有效避免 SQL 注入风险。开发者应当避免在 SQL 语句中为占位符添加单引号,也不要使用字符串格式化操作符进行拼接。
以上就是 Python 防止 SQL 注入:过滤非法字符与参数化查询实践的详细内容,更多关于 Python 数据库安全的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









