1. 程式人生 > >為啥jdbc問號佔位符可以防注入

為啥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.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;             }         }