2009-07-06 73 views
13

我使用MySQL API的功能必須轉義哪些字符以防止(My)SQL注入?

mysql_real_escape_string() 

根據相關文檔,逃離了以下特點:

\0 
\n 
\r 
\ 
' 
" 
\Z 

現在,我看着OWASP.org的ESAPI安全庫和Python的端口它有以下代碼(http://code.google.com/p/owasp-esapi-python/source/browse/esapi/codecs/mysql.py):

 """ 
     Encodes a character for MySQL. 
     """ 
     lookup = { 
     0x00 : "\\0", 
     0x08 : "\\b", 
     0x09 : "\\t", 
     0x0a : "\\n", 
     0x0d : "\\r", 
     0x1a : "\\Z", 
     0x22 : '\\"', 
     0x25 : "\\%", 
     0x27 : "\\'", 
     0x5c : "\\\\", 
     0x5f : "\\_", 
     } 

現在,我想知道是否所有這些字符真正需要的是ES披着披肩。我明白爲什麼%和_在那裏,它們是LIKE運算符中的元字符,但我不能簡單地理解爲什麼它們會添加退格和製表符(\ b \ t)?如果您執行查詢,是否存在安全問題:

SELECT a FROM b WHERE c = '...user input ...'; 

其中用戶輸入包含製表符或退格字符?

我的問題是:爲什麼他們在ESAPI安全庫中包含\ b \ t?有沒有任何情況下你可能需要逃避這些角色?

+0

我不是一個Python人或MySQL的人,但我的第一次,雖然是尋找單元測試對於這一點,遺憾的是他們並沒有透露任何useful- http://code.google.com/p/owasp-esapi-python/source/browse/esapi/test/codecs/test_mysql.py – RichardOD 2009-07-06 13:35:03

回答

14

MySQL manual page for strings說:

  • \0一個ASCII NUL(0×00)字符。
  • \'單引號(「'」)字符。
  • \"雙引號(「"」)字符。
  • \b退格字符。
  • \n的換行(換行)字符。
  • \r回車符。
  • \t製表符。
  • \Z ASCII 26(Control-Z)。請參閱表格後面的註釋。
  • \\反斜槓(「\」)字符。
  • \% A「%」字。請參閱表格後面的註釋。
  • \_ A「_」字。請參閱表格後面的註釋。
+0

鏈接它死了。考慮更新。 – 2014-04-30 16:01:06

38

關於退格字符猜測:想象一下,我向您發送電子郵件「你好,這裏是你想更新您的數據庫查詢」,並與

INSERT INTO students VALUES ("Bobby Tables",12,"abc",3.6); 

您cat文件的附加文本文件,看到它的好的,只需將文件傳送給MySQL即可。你不知道什麼,但是,是我把

DROP TABLE students;\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b 

INSERT語句,你沒有看到,因爲在控制檯輸出的退格改寫它。 BAMM!

只是一個猜測,雖然。

編輯(無法抗拒):

alt text

+12

+1爲參考,以我最喜歡的漫畫XKCD – 2009-07-06 13:43:02

+1

:這不是什麼t原來的http://xkcd.com/327/ – 2009-07-06 14:35:35

+3

這樣感謝Stefano,它符合CC許可證的歸屬條款。 – balpha 2009-07-06 14:40:07

0

其中用戶輸入包含製表符或退格字符?

這是相當了不起的一個事實是直到今天大多數用戶都認爲,這是用戶輸入已經被轉義,而這種逃避「防止注射」。

-2

不能只是一個刪除用戶輸入的單引號(S)?

如:$input =~ s/\'|\"//g;

0

Java解決方案:

public static String filter(String s) { 
    StringBuffer buffer = new StringBuffer(); 
    int i; 

    for(byte b : s.getBytes()) { 
     i = (int) b; 

     switch(i) { 
      case 9 : buffer.append(" "); break; 
      case 10 : buffer.append("\\n" ); break; 
      case 13 : buffer.append("\\r" ); break; 
      case 34 : buffer.append("\\\""); break; 
      case 39 : buffer.append("\\'" ); break; 
      case 92 : buffer.append("\\" ); 

      if(i > 31 && i < 127) buffer.append(new String(new byte[] { b })); 
     } 
    } 

    return buffer.toString(); 
}