首页 >Java >java教程 >为什么java jdbc问号占位符可以防注入?

为什么java jdbc问号占位符可以防注入?

青灯夜游
青灯夜游转载
2018-10-22 16:18:343387浏览

本篇文章给大家带来的内容是介绍为什么java jdbc问号占位符可以防注入?有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。

最近几天探讨一下关于sql注入的问题,以前林老师也讲过,现在总结一下:

其实,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: // &#39;\0&#39;
						buf.append(&#39;\\&#39;);
						buf.append(&#39;0&#39;);
						break;
					case 10: // &#39;\n&#39;
						buf.append(&#39;\\&#39;);
						buf.append(&#39;n&#39;);
						break;
					case 13: // &#39;\r&#39;
						buf.append(&#39;\\&#39;);
						buf.append(&#39;r&#39;);
						break;
					case 92: // &#39;\\&#39;
						buf.append(&#39;\\&#39;);
						buf.append(&#39;\\&#39;);
						break;
					case 39: // &#39;\&#39;&#39;
						buf.append(&#39;\\&#39;);
						buf.append(&#39;\&#39;&#39;);
						break;
					case 34: // &#39;"&#39;
						if(usingAnsiMode)
							buf.append(&#39;\\&#39;);
						buf.append(&#39;"&#39;);
						break;
					case 26: // &#39;\032&#39;
						buf.append(&#39;\\&#39;);
						buf.append(&#39;Z&#39;);
						break;
					default:
						buf.append(c);
						break;
				}
			}
			buf.append(&#39;\&#39;&#39;);
			parameterAsString = buf.toString();
		}
		byte parameterAsBytes[] = null;
		if(!isLoadDataQuery) {
			if(needsQuoted)
				parameterAsBytes = StringUtils.getBytesWrapped(parameterAsString, &#39;\&#39;&#39;, &#39;\&#39;&#39;, 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视频教程java开发图文教程bootstrap视频教程

以上是为什么java jdbc问号占位符可以防注入?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:csdn.net。如有侵权,请联系admin@php.cn删除

相关文章

查看更多