即使在用户输入中删除了所有“单引号”和“短划线字符”之后,任何人都可以在SQL注入时显示sql语句的 EXAMPLE 吗?
SELECT MyRecord FROM MyTable
WHERE MyEmail='susan@site.com' AND MyPassword='foo'
(此处不涉及任何INT。)
每个人似乎都说“是的,我能做到”......但当他们被迫接受e-x-a-m-p-l-e时......都没有出现过。
(您可以使用任何sql引擎的新旧版本:SQL Server,MySql,SqlLite,PostgreSQL,Oracle和无数其他版本。)
答案 0 :(得分:15)
你是如何“脱离用户的输入”的?如果您只是删除了所有出现的引号,那么对于无法使用您网站的susan.o'reilly@site.com
来说,这真的不公平。
如果您使用另一个引用that can cause problems as well 转义每个引号。如果你传入\'; DROP TABLE users; --
(至少在MySQL \'
中是转义引号的替代方法),那么转义单引号会导致SQL注入攻击会丢弃用户表:
SELECT MyRecord FROM MyTable
WHERE MyEmail='\''; DROP TABLE MyTable; --' AND MyPassword='foo'
消毒输入的唯一真正安全的方法是参数化:
SELECT MyRecord FROM MyTable
WHERE MyEmail=? AND MyPassword=?
然后使用您选择的语言添加参数值,例如在ps
为PreparedStatement
的java中:
ps.setString(1, "susan@site.com");
ps.setString(2, "foo");
ps.executeQuery();
答案 1 :(得分:8)
问题不在于您无法构建可以避免SQL注入的清理系统;您可以。问题是你不能构建一个现实的清理系统,它既保证没有SQL注入,可以用于任何但最简单的情况。
您提供的示例是在真实产品中永远无法使用的那些微不足道的案例之一。真正的产品需要支持用户名中的单引号和连字符,并且可能应该允许密码字段中的两个(至少连字符)。您的系统不允许以下内容:
名字中带撇号的用户,例如O'Reilly。
首先使用连字符(Jean-Pierre)或最后一个(Fortesque-Smythe)名称的用户。
电子邮件地址域包含连字符的用户。
用户遵循共同建议选择标点字符,并希望使用连字符或撇号的密码。
所以是的,您的清理对SQL注入非常安全。但是,系统只允许使用大写字母“A”。
答案 2 :(得分:0)
也许您应该尝试使用此字符串:valid@email.fu%BF%27 OR true; /*
请参阅this link了解