微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 准备语句如何比语句更好地防止SQL注入?

背景:我已经开始使用JDBC和MysqL来模拟书店,所有本地项目.为了连接到数据库,我开始使用Statement,但我开始读到,当多次使用查询只更改其参数时,为这些查询使用PreparedStatement会更有效.但是,我最常阅读的优点是PreparedStatements如何更好地防止sql注入.

资料来源:
这个帖子的答案here
谷歌
教授

我的问题:
在处理参数化查询时,PreparedStatements如何更好地阻止sql注入,甚至不同于语句?我很困惑,因为如果我理解正确,值仍然会被传递到执行的sql语句中,这只取决于程序员清理输入.

解决方法:

你是对的,你可以自己做所有的卫生,因此注射安全.但这更容易出错,因此不太安全.换句话说,自己动手会为可能导致注入漏洞的错误带来更多机会.

一个问题是转义规则可能因DB而异.例如,标准sql只允许使用单引号(‘foo’)中的字符串文字,因此您的卫生设施可能只会逃避那些;但是MysqL允许使用双引号(“foo”)中的字符串文字,如果你不对它们进行消毒,如果你使用MysqL,你将会受到注入攻击.

如果使用PreparedStatement,则该接口的实现由相应的JDBC驱动程序提供,该实现负责转义输入.这意味着清理代码是由编写JDBC驱动程序的人编写的,这些人可能知道数据库特定的转义规则的来龙去脉.他们也很可能比你测试手动转义函数更彻底地测试那些逃避规则.

因此,如果您编写preparedStatement.setString(1,name),该方法的实现(同样,由您正在使用的DB的JDBC驱动程序人员编写)可能大致如下:

public void setString(int idx, String value) {
    String sanitized = ourPrivateSanitizeMethod(value);
    internalSetString(idx, value);
}

(请记住,上面的代码一个非常粗略的草图;许多JDBC驱动程序实际上处理它的方式完全不同,但原理基本相同.)

一个问题是myUserInputvar是否已被清理可能是不明显的.请看以下代码段:

private void updateUser(int name, String id) throws sqlException {
    myStat.executeUpdate("UPDATE user SET name=" + name + " WHERE id=" + id);
}

这样安全吗?您不知道,因为代码中没有任何内容表明名称是否已被清理.而且你不能只是重新消毒“保持安全”,因为这会改变输入(例如,你好’世界会变成你好’世界).另一方面,UPDATE用户SET名称的准备语句=? WHERE id =?总是安全的,因为PreparedStatement的实现在将值插入?之前会转义输入.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐