SQL Injection 基本防範 / MySQL 筆記

2013050710:41

SQL Injection 基本介紹
簡稱隱碼攻擊,中國大陸稱作SQL注入攻擊..


SQL資料隱碼攻擊 (wiki)

這幾篇是很白話的介紹︰
PHP+MySQL环境下SQL Injection攻防总结 (簡體)

SQL Injection with MySQL (簡體)

SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(上) (microsoft)
SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(下) (microsoft)



SQL Injection 範例

SQL Injection Attacks by Example
一堆常見的 sql injection 攻擊的範例與原理介紹

SQL Injection Walkthrough
一堆常見的 sql injection 攻擊的範例與原理介紹

SQL Injection Cheat Sheet
比前面兩個的更複雜的 sql injection 介紹



XSS (Cross Site Scripting) Cheat Sheet

HTML Purifier XSS Attacks Smoketest





另外

有些資料建議採用 mysql_real_escape_string  來過濾 POST /  GET 的資料
以避免 SQL Injection

但  mysql_real_escape_string 也不一定安全

仍有方法繞過 mysql_real_escape_string 的過濾功能


例如 client 下的 URI
 
/article.php?id=1 UNION ALL SELECT 1,group_concat(table_name,0x2e,column_name) from information_schema.columns where table_schema=database()


article.php  中的寫法類似:
<?php
$id = _GET['id'];
//這時用戶端輸入的 $id = '1 UNION ALL SELECT 1,group_concat(table_name,0x2e,column_name) from information_schema.columns where table_schema=database()

$sqlcmd = "SELECT id,account FROM AA WHERE id=" . mysql_real_escape_string($id);


組合出來的新的 $sqlcmd 變成

SELECT id,account FROM AA WHERE id=1 UNION ALL SELECT 1,group_concat(table_name,0x2e,column_name) from i
nformation_schema.columns where table_schema=database();

這命令撈出來的資料類似:

mysql> SELECT id,account FROM AA WHERE id=1 UNION ALL SELECT 1,group_concat(table_name,0x2e,column_name) from information_schema.columns where table_schema=database()\G
*************************** 1. row ***************************
     id: 1
account: item_recommend.Item_recommend_no,item_recommend.Item_no,item_recommend.status,AA.id,AA.account,advert.ad_id,advert.ad_title,advert.ad_ph
oto,tupu
1 row in set (0.01 sec)

mysql>


client 再多加工 可以變出更多花樣
PS: php中若是這樣就避開問題
$sqlcmd = "SELECT id,account FROM AA WHERE id='" . mysql_real_escape_string($id) . "'";  //前後多了 ' 符號

對於整數資料的 id ,直接 intval 才是王道
$id = intval( $_GET['id'] );

** 特別注意 intval 有分 32 / 64bits
參考 PHP 手冊:

http://php.net/manual/en/function.intval.php

The integer value of var on success, or 0 on failure. Empty arrays return 0, non-empty arrays return 1.

The maximum value depends on the system. 32 bit systems have a maximum signed integer range of -2147483648 to 2147483647.
So for example on such a system, intval('1000000000000') will return 2147483647.

The maximum signed integer value for 64 bit systems is 9223372036854775807.

Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of integer casting apply.

一些 32bits 的範例

<?php
echo intval(42);                      // 42
echo intval(4.2);                     // 4
echo intval('42');                    // 42
echo intval('+42');                   // 42
echo intval('-42');                   // -42
echo intval(042);                     // 34
echo intval('042');                   // 42
echo intval(1e10);                    // 1410065408
echo intval('1e10');                  // 1
echo intval(0x1A);                    // 26
echo intval(42000000);                // 42000000
echo intval(420000000000000000000);   // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(428);                   // 42
echo intval('42'8);                 // 34
echo intval(array());                 // 0
echo intval(array('foo''bar'));     // 1
?>

 
參考資料:

http://www.blackhatlibrary.net/SQL_injection

Why mysql_real_escape_string() isn’t enough to stop SQL injection attacks!


http://www.bollymovies.ucoz.com/index/sql_injection_tutorial_mysql/0-73

http://hi.baidu.com/all3g/item/3f3d73aa9547d39b1510738d

http://lists.mysql.com/announce/364


Yahoo! TW YSM MKT - Blind SQL Injection Vulnerability
http://www.resecure.me/public/Yahoo-TW-YSM-BSQLI.txt
台灣Yahoo 今年 4月份被發現的 Blind SQL Injection



addslashes() vs  mysql_real_escape_string() 的區別

addslashes() 在 magic_quotes_sybase=on 時 將「'」轉換成「''」
addslashes() 在 magic_quotes_sybase=off 時 將「'」轉換成「\'」

mysql_real_escape_string() 永遠將「'」轉換成「\'」

mysql_real_escape_string() 會影響到的字元︰
\x00
\n
\r
\
'
"
\x1a
 

以下 magic_quotes_sybase=off 時
  原始文字 addslashes() mysql_real_escape_string()
  ' \' \'
  \ \\ \\
  " \" \"



在 php.ini 中另一個設定是
magic_quotes_gpc = Off / On
是指 所有 GET、POST 和 COOKIE 的資料 都自動以 addslashes() 處理過


另,還個函數︰mysql_escape_string() 在 php 5.3以後取消
 



  •    (悄悄話) 1F
  • <悄悄話留言,不公開>