博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么占位符可以防止sql注入?
阅读量:4353 次
发布时间:2019-06-07

本文共 3070 字,大约阅读时间需要 10 分钟。

先看下面用占位符来查询的一句话

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';这个时候是查不出来的。

转载于:https://www.cnblogs.com/greatfish/p/6067849.html

你可能感兴趣的文章
Fedora14 mount出现错误时解决办法【亲测有效】
查看>>
使用Visual Studio 2013进行UI自动化测试
查看>>
13-集体照
查看>>
读了曾国藩家书,,心态逐渐平和起来。搞技术的如果缺乏信念的指引,生活会很乏味无聊!...
查看>>
160809308周子济第六次作业
查看>>
大型Web应用运行时 PHP负载均衡指南
查看>>
为phpStorm 配置PHP_CodeSniffer自动检查代码
查看>>
测试工具网址大全(转)
查看>>
ServiceStack DotNet Core前期准备
查看>>
webpack中‘vant’全局引入和按需引入【vue-cli】
查看>>
Date、String和Timestamp类型转换
查看>>
计算机的组成
查看>>
[简单到爆]eclipse-jee-neon的下载和安装
查看>>
vector
查看>>
Redis学习之set类型总结
查看>>
栈和队列
查看>>
CSS2-3常见的demo列子总结一
查看>>
第522篇--DataTable to Excel C#
查看>>
C++\virtual 虚函数、纯虚函数
查看>>
asp.net mvc 4多级area实现技巧
查看>>