考虑以下语句:
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM t WHERE id=?");
stmt.setInt(1, id);
以上被认为是安全的SQL注入攻击。如果知道id
是int
类型,那么下面这个也安全吗?
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM t WHERE id=" + id);
如果不是,会出什么问题呢?
我可以想到两件事可能会出错,即使id
是int,也不能是其他任何东西:
- 将来可能会有人将
id
类型更改为String
类型。 - 有人可能会复制粘贴您的代码到代码库的另一部分,然后修改SQL,使其与
String
连接,使该部分易受攻击。
前面的响应是正确的-作为一个经过验证/键入的int,这可能是不可利用的。但是它应该被更改以将来证明它并提高性能(DB可以更容易地缓存编译后的语句)。
与此相关的一点是——虽然int是安全的,但在某些情况下,实数和日期可以通过横向SQL注入来利用,即使这些值已经完全验证或来自强类型。此方法使用注入的格式化机制-请参阅http://www.davidlitchfield.com/Lateral_SQL_Injection_Revisited_Final.pdf。
如果你的语言不支持强类型或者输入验证很弱,一些恶意字符串(例如:"1 or 1=1")可能会进入你的请求。
首先,Java是强类型语言,因此,从实际意义上讲,sql注入是不可能进入这部分代码的。
但安全性不止于此。代码质量也是一个不可轻视的安全级别,如果你在sonar qube服务器中传递此代码片段,这将被撤销。
为什么?
首先,如果不考虑字符串连接,这不是一种性能友好的编码方式。
在大规模应用中,一切都很重要。其中技术债务也是一个漏洞