sql占位符
来源:互联网 发布:淘宝开店程序 编辑:程序博客网 时间:2024/06/05 19:15
http://blog.csdn.net/yan465942872/article/details/6753957
这两天在上课时被同学拿了一段代码问我,这段代码有什么问题,我看了一会说:Connection和PreparedStatement都没关。他说不止这方面的问题,还有sql注入的问题,我就坚决的说使用了占位符不存在sql注入的问题,但是他提出了一种情况,在我看来也很有道理的情况。
- pstmt = conn.prepareStatement("delete from user where user.id=?");
- pstmt = conn.prepareStatement("delete from user where user.id=?");
- pstmt.setString(1, "w' or '2'='2");
当时我看了只能告诉他一定不存在注入问题,因为在我的想法中我一直记得的是用占位符能解决注入问题,至于怎么解决的就不知道了,看了上面的代码也很有道理,感觉setString后的sql语句应该是
- delete from user where user.id='w' or '2'='2';
回到宿舍我专门写了程序测试一下,事实证明并不想我们想的这样,的确使用占位符不存在注入问题,所以解释是在执行的时候把一些字符给转义了,但这个转义的过程是在什么地方转义的呢,把上面的sql语句在mysql控制台上运行一下,查看一下数据看到所有数据都被删除完,那只能解释成在java程序中转义的,于是我就去看java的源代码,发现在java源码中PreparedStatement只是一个接口,而且是没有子类的接口,我就很纳闷,没实现怎么用的?所以一定有实现的地方,去网上查了一下,jdk直提供接口,而具体实现是由数据库厂商实现的,我们用的就是数据库厂商实现的类。于是我就又去查mysql的jar包源码,发现有个PreparedStatement实现了jdk中的PreparedStatement了。里面的setString方法如下实现:
- public void setString(int parameterIndex, String x) throws SQLException {
- // if the passed string is null, then set this column to null
- if (x == null) {
- setNull(parameterIndex, Types.CHAR);
- } else {
- StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
- buf.append('\'');
- int stringLength = x.length();
- //
- // Note: buf.append(char) is _faster_ than
- // appending in blocks, because the block
- // append requires a System.arraycopy()....
- // go figure...
- //
- for (int i = 0; i < stringLength; ++i) {
- char c = x.charAt(i);
- switch (c) {
- case 0: /* Must be escaped for 'mysql' */
- buf.append('\\');
- buf.append('0');
- break;
- case '\n': /* Must be escaped for logs */
- buf.append('\\');
- buf.append('n');
- break;
- case '\r':
- buf.append('\\');
- buf.append('r');
- break;
- case '\\':
- buf.append('\\');
- buf.append('\\');
- break;
- case '\'':
- buf.append('\\');
- buf.append('\'');
- break;
- case '"': /* Better safe than sorry */
- if (this.usingAnsiMode) {
- buf.append('\\');
- }
- buf.append('"');
- break;
- case '\032': /* This gives problems on Win32 */
- buf.append('\\');
- buf.append('Z');
- break;
- default:
- buf.append(c);
- }
- }
- buf.append('\'');
- String parameterAsString = buf.toString();
- byte[] parameterAsBytes = null;
- if (!this.isLoadDataQuery) {
- parameterAsBytes = StringUtils.getBytes(parameterAsString,
- this.charConverter, this.charEncoding, this.connection
- .getServerCharacterEncoding(), this.connection
- .parserKnowsUnicode());
- } else {
- // Send with platform character encoding 平台字符编码
- parameterAsBytes = parameterAsString.getBytes();
- }
- setInternal(parameterIndex, parameterAsBytes);
- }
- }
到此就告一段落,可以发现在setString时最外面的单引号被转义了,也就是说setString后的sql语句是这样的
- delete from user where user.id=\'w' or '2'='2\';
0 0
- SQL 占位符
- 占位符,SQL注入?
- sql占位符
- 占位符,SQL注入?
- 占位符防止sql注入
- sql占位符的作用
- sql语句中的#{}占位符和${}占位符
- DB2中sql语句占位符问题
- SQL和HQL占位符问题
- 关于SQL语句的占位符使用及动态SQL
- mybatis中的sql语句中的#{}占位符和${}占位符的区别及遇到的问题
- 占位符
- 占位符
- 占位符
- 占位符
- 占位符
- 占位符
- 占位符
- JavaScript中继承机制的实现
- EXT 3 上传文件控件浏览按钮国际化
- Deep Learning源代码收集
- iOS事件拦截处理
- Hadoop源码分析之DataNode的启动与停止
- sql占位符
- bootstrap
- arm的一些概念(ARM7、Cortex-M的区别)
- iOS上OCR SDK
- (四)单例设计模式
- url传中文参数乱码解决办法
- 举例讲解H3C配置三层交换机4个步骤详细用法
- 智能家居迎来发展 “窗口期”
- Golang用武之地-七牛云存储CEO许式伟