java的jdbc问号占位符可以防止注入吗
发布时间:2020-06-15 10:09:02
来源:亿速云
阅读:154
作者:Leah
java的jdbc问号占位符可以防止注入吗?如果你刚好也有这个困惑,不妨参照这篇文章。阅读完整文相信大家对java的占位符有了一定的认识。
其实,like是会注入的,也不建议用,用占位符实际查询效果不是like本身的意思,相当全匹配。
建议使用instr()函数,本文主要记录一下处理防止注入的源码,为什么用?可以防注入,而拼接的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(x == null) {
setNull(parameterIndex, 1);
} else {
checkClosed();
int stringLength = x.length();
if(connection.isNoBackslashEscapesSet()) {
boolean needsHexEscape = isEscapeNeededForString(x, stringLength);
if(!needsHexEscape) {
byte parameterAsBytes[] = null;
StringBuffer quotedString = new StringBuffer(x.length() + 2);
quotedString.append('\'');
quotedString.append(x);
quotedString.append('\'');
if(!isLoadDataQuery)
parameterAsBytes = StringUtils.getBytes(quotedString.toString(), charConverter, charEncoding, connection.getServerCharacterEncoding(), connection.parserKnowsUnicode());
else
parameterAsBytes = quotedString.toString().getBytes();
setInternal(parameterIndex, parameterAsBytes);
} else {
byte parameterAsBytes[] = null;
if(!isLoadDataQuery)
parameterAsBytes = StringUtils.getBytes(x, charConverter, charEncoding, connection.getServerCharacterEncoding(), connection.parserKnowsUnicode());
else
parameterAsBytes = x.getBytes();
setBytes(parameterIndex, parameterAsBytes);
}
return;
}
String parameterAsString = x;
boolean needsQuoted = true;
if(isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {
needsQuoted = false;
StringBuffer buf = new StringBuffer((int)((double) x.length() * 1.1000000000000001 D));
buf.append('\'');
for(int i = 0; i < stringLength; i++) {
char c = x.charAt(i);
switch(c) {
case 0: // '\0'
buf.append('\\');
buf.append('0');
break;
case 10: // '\n'
buf.append('\\');
buf.append('n');
break;
case 13: // '\r'
buf.append('\\');
buf.append('r');
break;
case 92: // '\\'
buf.append('\\');
buf.append('\\');
break;
case 39: // '\''
buf.append('\\');
buf.append('\'');
break;
case 34: // '"'
if(usingAnsiMode)
buf.append('\\');
buf.append('"');
break;
case 26: // '\032'
buf.append('\\');
buf.append('Z');
break;
default:
buf.append(c);
break;
}
}
buf.append('\'');
parameterAsString = buf.toString();
}
byte parameterAsBytes[] = null;
if(!isLoadDataQuery) {
if(needsQuoted)
parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString, '\'', '\'', charConverter, charEncoding, connection.getServerCharacterEncoding(), connection.parserKnowsUnicode());
else
parameterAsBytes = StringUtils.getBytes(parameterAsString, charConverter, charEncoding, connection.getServerCharacterEncoding(), connection.parserKnowsUnicode());
} else {
parameterAsBytes = parameterAsString.getBytes();
}
setInternal(parameterIndex, parameterAsBytes);
parameterTypes[(parameterIndex - 1) + getParameterIndexOffset()] = 12;
}
}
关于java的jdbc问号占位符就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。