在创建黑名单功能时,作为我们针对SQL注入(包括参数化查询和输入长度和类型验证)的多管齐下的防御措施的一部分,我们创建了一个blacklist函数来检查来自.Net web表单的输入,以便在Server上运行。
成功的SQL注入是否需要分号(;)或注释(-,/* */)?
发布于 2020-12-12 10:47:08
在完全一般的情况下,绝对不是。例如,假设您的登录系统使用如下所示的SQL语句:"SELECT TOP(1) userId FROM Users WHERE username = '" + userName + "' AND password = '" + hashedPass + "'",其中userName由用户直接提供。如果攻击者提供' OR 1=1 OR 'a'='a (没有分号、注释甚至子查询),那么整个查询将是SELECT TOP(1) userId FROM Users WHERE username = '' OR 1=1 OR 'a'='a' AND password = 'f40a564107bad8ebf1b5ae73c350ebea' (假设哈希密码是'f40a564107bad8ebf1b5ae73c350ebea')。WHERE子句中的AND操作符优先,因此我们给它一个无意义的值来检查('a‘将等于'a’,但对于可能的每个用户来说,and仍然是错误的,因为密码是猜测的,这是可以的),而且在DB中可能没有'‘的用户名,但是... OR 1=1 OR ...部分意味着每一行都将匹配WHERE子句。数据库将返回表中的第一行,后者很可能是某种管理人员。此示例可以修改为以任何特定用户的身份登录,仍然不需要他们的密码。
一般来说,纵深防御是好的,但大片基本上是一文不值的.参数化您的查询(特别是对于Server,在使用时使用存储过程以获得perf增益),并对无法参数化或可能连接到SQL语句的任何内容使用特定于数据库的清理库。在实际可行的地方,继续验证类型和长度。试图阻止特定字符几乎肯定会过于激进(阻塞合法输入)或过于宽容(丢失可能有害的内容),甚至两者都会发生重叠;“如果将其解释为SQL代码将是危险的”和“可能合法地出现在用户数据中”之间经常存在重叠。
在最好的情况下,在某种程度上,你有一个完美的不破坏任何东西的重磅列表,如果你忘记对照它检查输入,它仍然会失败。这听起来可能是一个愚蠢的考虑,但参数化和转义都是完全足够的防御措施,如果正确使用,那么,如果想要获得相关的内容,你必须已经忘记了一些东西。除了封锁列表之外,您忘记每个安全控制的概率似乎都很低,因此它的期望值无论如何接近于零。
https://security.stackexchange.com/questions/242011
复制相似问题