首页 > 代码库 > 为什么占位符可以防止sql注入?
为什么占位符可以防止sql注入?
先看下面用占位符来查询的一句话
String sql = "select * from administrator where adminname=?";
psm = con.prepareStatement(sql);
String s_name ="zhangsan‘ or ‘1‘=‘1";
psm.setString(1, s_name);
假设数据库表中并没有zhangsan这个用户名,
用plsql运行sql语句,可以查出来所有的用户名,但是在Java中并没有查出任何数据,这是为什么呢?
首先,setString()的源码中只有方法名字,并没有任何过程性处理,
那么答案肯定出现在Java到数据库这个过程中,也就是mysql和oracle驱动包中,在mysql驱动包中,PreparedStatement继承并实现了jdk中的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);
}
}
所以转义后的sql为‘zhangsan\‘ or \‘1\‘=\‘1‘;这个时候是查不出来的。
为什么占位符可以防止sql注入?
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。