删除所有单引号和短划线字符后的SQL注入

Sus*_*san 14 sql database database-design sql-injection

即使在所有"单引号"和"破折号字符"都被删除了用户的输入之后,任何人都可以在SQL注入时显示sql语句的示例吗?

SELECT MyRecord   FROM MyTable   
WHERE MyEmail='susan@site.com' AND MyPassword='foo'
Run Code Online (Sandbox Code Playgroud)

(此处不涉及INT.)

每个人似乎都说"是的,我能做到"......但当他们被迫举一个例子时......没有一个人能够表现出来.

(您可以使用任何sql引擎的任何版本,无论是新版本还是旧版本:SQL Server,MySql,SqlLite,PostgreSQL,Oracle以及其他无数版本.)

kro*_*ock 15

你是如何"脱离用户的输入"的?如果您只是删除了所有出现的引号,那么对于susan.o'reilly@site.com谁将无法使用您的网站而言,这真的不公平.

如果您使用另一个可能导致问题的报价来转义每个报价.如果你传入(至少在MySQL中是转义引号的替代方法),那么转义单引号会导致SQL注入攻击会丢弃users表:\'; DROP TABLE users; --\'

SELECT MyRecord FROM MyTable
WHERE MyEmail='\''; DROP TABLE MyTable; --' AND MyPassword='foo'
Run Code Online (Sandbox Code Playgroud)

清理输入的唯一真正安全的方法是参数化:

SELECT MyRecord FROM MyTable
WHERE MyEmail=? AND MyPassword=?
Run Code Online (Sandbox Code Playgroud)

然后使用您所选择的语言添加参数值,例如在Java中,其中psPreparedStatement:

ps.setString(1, "susan@site.com");
ps.setString(2, "foo");
ps.executeQuery();
Run Code Online (Sandbox Code Playgroud)


Lar*_*tig 8

问题不在于您无法构建可以避免SQL注入的清理系统; 您可以.问题是,你不能构建一个现实的消毒系统,既保证没有SQL注入,并可以在任何但是最平凡的情况下使用.

你给出的例子是那些在真实产品中永远无法使用的琐碎案例之一.真正的产品需要支持用户名中的单引号和连字符,并且可能应该允许密码字段中的两个(至少连字符).您的系统不允许以下内容:

  • 用户名撇号的用户,如O'Reilly.

  • 首先使用连字符(Jean-Pierre)或最后(Fortesque-Smythe)命名的用户.

  • 电子邮件地址域包含连字符的用户.

  • 用户遵循共同建议选择标点字符,并希望使用连字符或撇号的密码.

所以,是的,您的清理对SQL注入非常安全.但这样的系统只允许使用大写字母"A".