这两天在上课时被同学拿了一段代码问我,这段代码有什么问题,我看了一会说:Connection和PreparedStatement都没关。他说不止这方面的问题,还有sql注入的问题,我就坚决的说使用了占位符不存在sql注入的问题,但是他提出了一种情况,在我看来也很有道理的情况。

pstmt = conn.prepareStatement("delete from user where user.id=?");
pstmt.setString(1, "w");

他认为如果把代码写成这样就有注入问题了

pstmt = conn.prepareStatement("delete from user where user.id=?");
pstmt.setString(1, "w' or '2'='2");

当时我看了只能告诉他一定不存在注入问题,因为在我的想法中我一直记得的是用占位符能解决注入问题,至于怎么解决的就不知道了,看了上面的代码也很有道理,感觉setString后的sql语句应该是

回到宿舍我专门写了程序测试一下,事实证明并不想我们想的这样,的确使用占位符不存在注入问题,所以解释是在执行的时候把一些字符给转义了,但这个转义的过程是在什么地方转义的呢,把上面的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';

  

而且仔细看会发现在setString中是一个字符一个字符的解析,该转义的都已经转义,正如他一句注释中写的Better safe than sorry.所以最终,占位符确实不存在注入问题

转载于http://blog.csdn.net/yan465942872/article/details/6753957

占位符,SQL注入?的更多相关文章

  1. 转:攻击JavaWeb应用[4]-SQL注入[2]

    转:http://static.hx99.net/static/drops/tips-288.html 攻击JavaWeb应用[4]-SQL注入[2] 园长 · 2013/07/18 17:23 注: ...

  2. python-sqlite3之占位符

    The sqlite3 module supports two kinds of placeholders: question marks (qmark style) and named placeh ...

  3. SQL注入、占位符拼接符

    一.什么是SQL注入 官方: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意 ...

  4. 为什么占位符可以防止sql注入?

    先看下面用占位符来查询的一句话 String sql = "select * from administrator where adminname=?"; psm = con.pr ...

  5. SQl语句中使用占位符的优点

    1.增加SQL代码可读性2.占位符可以预先编译,提高执行效率3.防止SQL注入4用占位符的目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少 绑定变量是Oracle解决硬解析的首要 ...

  6. Mybatis 中 sql 语句的占位符 #{} 和 ${}

    #{} 表示一个占位符号,通过 #{} 可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换.#{} 可以有效防止   sql注入. #{}  ...

  7. 在Java中编写带占位符的SQL语句

    C#中SQL中带占位符的语句 假设有一张学员信息表Student,通过表中的ID来找学员,查询的SQL语句如下 string sql = string.Format("select * fr ...

  8. 深入Spring Boot:那些注入不了的Spring占位符(${}表达式)

    Spring里的占位符 spring里的占位符通常表现的形式是: <bean id="dataSource" destroy-method="close" ...

  9. FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符

    交友:微信号 dwjluck2013 一.封装FMDB单例 (1)JLFMDBHelp.h文件 #import <Foundation/Foundation.h> #import < ...

随机推荐

  1. Http协议 压缩

    先说结论:Request和Response可以设置gzip压缩从而节省流量/带宽,这是一个不常见的问题.具体可见连接:HTTP 协议之压缩 最近测试代理服务器时,意外的发现使用urlopen请求百度首 ...

  2. 20210826 Lighthouse,Miner,Lyk Love painting,Revive

    考场 T1 这不裸的容斥 T2 这不裸的欧拉路,先从奇数度点开始走,走不了就传送 T3 什么玩意,暴力都不会 T4 点分树??? 仔细想了一波,发现 T1 T2 都好做,T3 二分答案后可以暴力贪心, ...

  3. 20210807 Smooth,Six,Walker

    考场 开题,感觉 T1 很像 dky 讲过的一道中北大学 ACM 题,T3 一看就是随机化,具体不知道怎么做. T1 sb 题,直接取当前最小的光滑数,把它乘一个质因子放入候选集.类似<蚯蚓&g ...

  4. 《Go语言圣经》阅读笔记:第二章程序结构

    第二章 程序结构 2.1 命名 在GO语言中,所有的变量名.函数.常量.类型.语句标号.包名都遵循一个原则: 名字必须以字母或者下划线开头,后面紧跟任意数量的字母数字下划线.区分大小写. 在GO语言中 ...

  5. WinForm控件常用设置(转)

    本来想自己整理一份,但找到了一份挺全的,就直接用到直接找吧 A0 ---- 通用A1 ---- Form 类A2 ---- Control 类A3 ---- MessageBox 类A4 ---- B ...

  6. msf宏钓鱼

    kali下载python脚本,生成rtf文件: 下载脚本:git clone https://github.com/bhdresh/CVE-2017-8759.git 生成rtf文件: python ...

  7. 模板引挚 jade ejs

    // asl sum翡翠 后台使用如下: const jade = require('jade') //pretty 美化的意思,指的是渲染的布局会美化   2020-2-15 var str = j ...

  8. idea创建Maven项目没有src目录,且依赖也没有更新

    刚开始用idea的时候,重新配置安装了Maven,但是创建项目的时候发现创建的目录少了很多东西,今天重新查看了一下,发现了原因....... 话不多说,安装配置Maven的方法网上都有,我之前改路径的 ...

  9. 自制C++游戏 迷宫

    1 #include<bits/stdc++.h> 2 #include<conio.h> 3 using namespace std; 4 char mg[17][17]={ ...

  10. 38KHz,NEC红外模拟发送和接收程序

    /*************************************************************************************************/ ...