SQL 语句如下所示,
"SELECT * from XX where id = '" + id + "'"
该id变量直接来自GET名为 的参数id。
Java Web 应用程序明确禁止使用单引号。如果在该参数中找到单引号,服务器将立即停止处理并返回错误。
那么,这仍然可以利用吗?有postgresql和tomcat环境。
SQL 语句如下所示,
"SELECT * from XX where id = '" + id + "'"
该id变量直接来自GET名为 的参数id。
Java Web 应用程序明确禁止使用单引号。如果在该参数中找到单引号,服务器将立即停止处理并返回错误。
那么,这仍然可以利用吗?有postgresql和tomcat环境。
您可能想看看这篇论文(wayback machine 链接)。它详细介绍了绕过此类过滤器的一些方法。
例如,某些 SQL 过滤器将所有单引号替换为一对单引号。然而,给他们一个输入包含\'可以绕过这个。
此外,还有 Unicode 走私,您使用 Java(PHP/Ruby/Python/whatever)理解为与引号不同的 Unicode 字符,但数据库没有。
除非你有一个非常非常好的理由,否则我建议你使用内置的转义。
你说的是“防止已知的坏事”,它只会在有人想到新的坏事之前起作用。正如@Manishearth 所说,\'这是一种技术。对于一个 URL,%27是另一个。在 HTML 中,您可以拥有', ', ', ','是其他人。如果将这些技术组合为%40%230039%3B('url 编码)或%5C%27(\'url 编码)或\\\\'?
预防已知的不良行为始终是一个冒险的提议。当它是一个选项时,允许已知良好总是更好。因此,转换为整数类型总是比试图阻止特定字符串提供更多的安全性。Prepared Statements 提供了极好的保护层。
查看有关SQL 注入缓解的 Wikipedia 文章。
假设 GET 参数 'id' 仅包含数字,最好的办法是检查 ID 是否真的只包含数字,例如将其转换为 INT(如果有则捕获异常),而不是一些讨厌的东西,例如引号/斜杠/编码字符/等。
一般来说,我更喜欢使用真正的整数变量,因为我完全知道它只包含数字,而不是可能包含一些奇怪字符的转义字符串。