为啥jdbc问号占位符可以防注入

来源:互联网 发布:地产网络推广 编辑:程序博客网 时间:2024/04/27 16:45

最近几天探讨一下关于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.1000000000000001D));                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;        }    }


1 0