next up previous contents
Next: SQL injection 實例 Up: SQL Injection 注入 Previous: 限制輸入字元   Contents

PHP 避免 SQL 注入

  1. PHP 之 magic_quotes_gpc 的美麗與哀愁:PHP 為了防止 user 端送到 server 端的資料,會被惡意內容攻擊,有 SQL injection 的疑慮,因此很體貼地設計一個 magic_quotes_gpc 開關,當此開關 on 時,$_GET$_POST$_COOKIE 等從 user 端來的資料,如果含有單引號、雙引號、反斜線等內容,會自動被加上倒反斜線跳脫該字元,也就是做 addslashes() 的處理,以免程式設計師直接把資料串在 SQL 指令上,導致系統沒兩天就被駭客爆台。不過 php 5.4 以上版本,不支援此開關。
  2. 範例:查詢使用者帳號。使用 PHP 的 get_magic_quotes_gpc 函數判斷 magic_quotes_gpc 是否開啟,如果沒有開啟,則將輸入字串中指定的字符加入倒斜線,也就是跳脫其作用。 本練習系統 PHP 版本為 5.4.xx,故以下範例 get_magic_quotes_gpc 函數判斷永遠為關閉,會執行addslashes 函數。
    [root@kvm8 ~]# cd /var/www/html
    [root@kvm8 html]# vim escape.php 
    [root@kvm8 html]# cat escape.php 
    <?php
    $dbhost = 'localhost:3036';
    $dbuser = 'root';
    $dbpass = '123qwe';
    $conn = mysql_connect($dbhost, $dbuser, $dbpass);
    if(! $conn ) {
            die('Could not connect: ' . mysql_error());
    }
    
    if(! get_magic_quotes_gpc() ) {
            $user = addslashes ($_GET['user']);
    } else {
            $user = $_GET['user'];
    }       
    
    $sql = "SELECT host,user FROM user WHERE user='{$user}'";
    mysql_select_db('mysql');
    $retval = mysql_query( $sql );
    while($row = mysql_fetch_array($retval, MYSQL_NUM))     {
     echo "HOST:  {$row[0]}  <br> ".
     "User:  {$row[1]} <br> ".
     "--------------------------------<br>";
    }      
    ?>
    
  3. 在 php 網址後加入 ?user='a' or 1,如果可以 SQL Injection,應該會回傳所有 user,但卻回應空白,也就是沒有 |user='a' or 1| 這個用戶。
    Image escape1
  4. 在 php 網址後加入 ?user=dywang,查詢結果列出 host 及 user。
    Image escape2



2017-10-27