接上文
http://blog.itpub.net/29254281/viewspace-1318239/
領(lǐng)導(dǎo)讓開發(fā)同學(xué)鼓搗一個(gè)可配置化的后臺(tái).
又回到了原來的問題
如果要靈活,很多參數(shù)要從前端頁面?zhèn)鬟^來,有SQL注入的風(fēng)險(xiǎn).
如果參數(shù)化SQL,又很難做到靈活..
先看一個(gè)注入的例子:
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.ResultSet;
-
import java.sql.SQLException;
-
import java.sql.Statement;
-
-
public class Test {
-
public static void main(String[] args) throws SQLException {
-
String para="/index.html' union all select * from probe -- ";
-
Connection conn = DriverManager.getConnection("jdbc:MySQL://127.0.0.1:3306/mvbox", "xx", "xx");
-
-
Statement ps=conn.createStatement();
-
-
ResultSet rs = ps.executeQuery("select * from probe where path='"+para+"'");
-
while (rs.next()) {
-
System.out.println(rs.getString("host")+":"+rs.getString("path"));
-
}
-
rs.close();
-
ps.close();
-
conn.close();
-
}
-
}
如果要避免這種風(fēng)險(xiǎn),可以選擇參數(shù)化
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.PreparedStatement;
-
import java.sql.ResultSet;
-
import java.sql.SQLException;
-
-
public class Test {
-
public static void main(String[] args) throws SQLException {
-
String para="/index.html' union all select * from probe -- ";
-
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mvbox", "xx", "xx");
-
PreparedStatement ps=conn.prepareStatement("select * from probe where path=?");
-
ps.setString(1, para);
-
ResultSet rs=ps.executeQuery();
-
while (rs.next()) {
-
System.out.println(rs.getString("host")+":"+rs.getString("path"));
-
}
-
rs.close();
-
ps.close();
-
conn.close();
-
}
-
}
為何參數(shù)化可以防止注入?
作為MySQL JDBC驅(qū)動(dòng)來說(5.1.31),其實(shí)就是對(duì)敏感字符做了轉(zhuǎn)義.
觀察 com.mysql.jdbc.PreparedStatement 的 setString方法
可以看到有如下的替換過程
-
String parameterAsString = x;
-
boolean needsQuoted = true;
-
-
if (this.isLoadDataQuery || isEscapeNeededForString(x, stringLength)) {
-
needsQuoted = false; // saves an allocation later
-
-
StringBuffer buf = new StringBuffer((int) (x.length() * 1.1));
-
-
buf.append('\'');
-
-
//
-
// 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;
-
-
case '\u00a5':
-
case '\u20a9':
-
// escape characters interpreted as backslash by mysql
-
if(charsetEncoder != null) {
-
CharBuffer cbuf = CharBuffer.allocate(1);
-
ByteBuffer bbuf = ByteBuffer.allocate(1);
-
cbuf.put(c);
-
cbuf.position(0);
-
charsetEncoder.encode(cbuf, bbuf, true);
-
if(bbuf.get(0) == '\\') {
-
buf.append('\\');
-
}
-
}
-
// fall through
-
-
default:
-
buf.append(c);
-
}
-
}
-
-
buf.append('\'');
-
-
parameterAsString = buf.toString();
-
}
是不是可以使用 iBatis 的 $ 方式 增加靈活性,而在參數(shù)進(jìn)入iBatis之前,手工進(jìn)行一下敏感字符替換,而防止SQL注入攻擊呢?
文章標(biāo)題:再看ibatisOrderBy注入問題
分享網(wǎng)址:http://muchs.cn/article42/gphchc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、域名注冊(cè)、網(wǎng)站設(shè)計(jì)、品牌網(wǎng)站制作、外貿(mào)建站、手機(jī)網(wǎng)站建設(shè)
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)