占位符,SQL注入?
这两天在上课时被同学拿了一段代码问我,这段代码有什么问题,我看了一会说: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注入?的更多相关文章
- 转:攻击JavaWeb应用[4]-SQL注入[2]
转:http://static.hx99.net/static/drops/tips-288.html 攻击JavaWeb应用[4]-SQL注入[2] 园长 · 2013/07/18 17:23 注: ...
- python-sqlite3之占位符
The sqlite3 module supports two kinds of placeholders: question marks (qmark style) and named placeh ...
- SQL注入、占位符拼接符
一.什么是SQL注入 官方: 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意 ...
- 为什么占位符可以防止sql注入?
先看下面用占位符来查询的一句话 String sql = "select * from administrator where adminname=?"; psm = con.pr ...
- SQl语句中使用占位符的优点
1.增加SQL代码可读性2.占位符可以预先编译,提高执行效率3.防止SQL注入4用占位符的目的是绑定变量,这样可以减少数据SQL的硬解析,所以执行效率会提高不少 绑定变量是Oracle解决硬解析的首要 ...
- Mybatis 中 sql 语句的占位符 #{} 和 ${}
#{} 表示一个占位符号,通过 #{} 可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换.#{} 可以有效防止 sql注入. #{} ...
- 在Java中编写带占位符的SQL语句
C#中SQL中带占位符的语句 假设有一张学员信息表Student,通过表中的ID来找学员,查询的SQL语句如下 string sql = string.Format("select * fr ...
- 深入Spring Boot:那些注入不了的Spring占位符(${}表达式)
Spring里的占位符 spring里的占位符通常表现的形式是: <bean id="dataSource" destroy-method="close" ...
- FMDB存储模型对象(以二进制存储)用NSKeyedArchiver archivedDataWithRootObject序列号,NSKeyedUnarchiver unarchiveObjectWithData反序列化(重点坑是sql语句@"insert into t_newsWithChannel (nwesName,newsType) values (?,?)")一定要用占位符
交友:微信号 dwjluck2013 一.封装FMDB单例 (1)JLFMDBHelp.h文件 #import <Foundation/Foundation.h> #import < ...
随机推荐
- Nginx:常用基本命令与异常处理
Nginx日志 - ./nginx-1.6.0-ems/logs/nginx.pid Nginx启动时应该使用cmd等命令行工具启动,双击启动同样会产生进程但会造成异常,判断条件是 ./nginx-1 ...
- 云真机兼容性自动化工具测试解决方案_www.alltesting.cn
问题和背景 不同类型的品牌和硬件环境.不同版本的android操作系统.IO操作系统,以及不同的分辨率,造成相同的APP在不同的设备可能存在缺陷. 兼容性测试,就是让APP.小程序.H5程序,在所有的 ...
- Java学习笔记--常用容器
容器 1. 出现原因 解决程序运行时需要创建新对象,在程序运行前不知道运行的所需的对象数量甚至是类型的问题. Java中提供了一套集合类来解决这些问题包括:List.Set.Queue.Map 2. ...
- C语言学习笔记---2.C语言数据类型
1.C语言基本数据类型 1.1 int类型 int类型是有符号整型,即int类型的值必须是整数,可以是正整数.负整数或零.其取值范围依计算机系统而异.一般而言,储存一个int要占用一个机器字长. 声明 ...
- Math.round真的是四舍五入吗?我不这么认为
public static long round(double a) 返回最接近参数的 long.结果将舍入为整数:加上 1/2,对结果调用 floor 并将所得结果强制转换为 long 类型.换句话 ...
- Dapr + .NET Core实战(四)发布和订阅
什么是发布-订阅 发布订阅是一种众所周知并被广泛使用的消息传送模式,常用在微服务架构的服务间通信,高并发削峰等情况.但是不同的消息中间件之间存在细微的差异,项目使用不同的产品需要实现不同的实现类,虽然 ...
- 做PPT总是很难找到好看、有质感的图片,怎么办?
1.制作PPT时,要想提升整体质感,就需要插入一些图片.当你进入到这个阶段,就意味着你剩下用来做PPT的时间,可能比较紧张了.所以,你的重中之重是,在最短的时间内找到合适的照片. 2.想快速找到好看. ...
- 怎么让jenkins保持后台运行
今天在腾讯云直接使用命令启动jenkins,java -jar jenkins.war --httpPort=8080,这样启动关掉shell窗口或退回shell窗口,进程就会结束,需要重新 启动,非 ...
- linux mint 18.1 安装备忘录
本次全新安装mint18.1,遇到一些问题,全部解决,怕日后忘记,再捣鼓琢磨,浪费时间,特记录在此: 一.楷体字体问题 安装完后的mint18.1,显示都是楷体,经请教薄荷论坛高手,可用以下办法解决: ...
- selenium--多窗口
多窗口/句柄 有些页面的链接打开后,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了.获取窗口的唯一标识用句柄表示,所以只需要切换句柄,我们就能在多个页面上灵活自如的操作了. 1. ...