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

addslashes 函式

  1. 如前例 injection.php,select 查詢時 $user 變數沒有加單引號。
    [root@kvm8 ~]# cat /var/www/html/injection.php 
    <?php
    $dbhost = 'localhost:3306';
    $dbuser = 'root';
    $dbpass = '123qwe';
    $user = $_GET['user'];
    $conn = mysqli_connect($dbhost, $dbuser, $dbpass) 
    	or die(mysqli_connect_error().PHP_EOL);
    mysqli_select_db( $conn, 'mysql' )
    	or die('Error: '.mysqli_error($conn).PHP_EOL);
    $sql = "SELECT host,user FROM user WHERE user=$user";
    $retval = mysqli_query( $conn,$sql )
    	or die('Error: '.mysqli_error($conn).PHP_EOL);
    while($row = mysqli_fetch_array($retval, MYSQLI_NUM)) {
        echo "HOST: {$row[0]}<br>User: {$row[1]}<br>".
        "--------------------------------<br>";
    }
    mysqli_free_result($retval);
    echo "Fetched data successfully\n";
    mysqli_close($conn); 
    ?>
    
  2. 查詢 user='root' 時,root 必須加單引號。
    [root@kvm8 html]# curl -s http://kvm8.deyu.wang/escape.php?"user='root'" \
     | sed 's/<br> */\n/g'
    HOST: 127.0.0.1
    User: root
    --------------------------------
    HOST: ::1
    User: root
    --------------------------------
    HOST: kvm8.deyu.wang
    User: root
    --------------------------------
    HOST: localhost
    User: root
    --------------------------------
    Fetched data successfully
    
  3. 為避免使用者輸入一些如單引號等,可能進行 sql injection 的相關字元,可以使用 addslashes() 函式,將取得的字串中相關的字元加入倒斜線,也就是跳脫其作用。以下例子 escape.php 是將上例 injection.php 的 $_GET['user'] 變數,先經過 addslashes() 函式處理後,再存入 $user 變數。
    [root@kvm8 ~l]# grep addslashes /var/www/html/escape.php
    $user = addslashes($_GET['user']);
    
  4. 再查詢 user='root' 時,出現錯誤,原因為單引號被加倒斜線跳脫了。
    [root@kvm8 html]# curl -s http://kvm8.deyu.wang/escape.php?"user='root'"
    Error: You have an error in your SQL syntax; check the manual that corresponds
     to your MariaDB server version for the right syntax to use near
     '\'root\'' at line 1
    
  5. 將 escape.php 的 select 查詢,改成 user='$user',也就是單引號由程式自動加上,不要由使用用輸入。
    [root@kvm8 html]# grep '$user' escape.php$user = addslashes($_GET['user']);
    $sql = "SELECT host,user FROM user WHERE user='$user'";
    
  6. 再使用 user=root,不加單引號查詢,正常輸出查詢結果。
    [root@kvm8 html]# curl -s http://kvm8.deyu.wang/escape.php?"user=root" \
     | sed 's/<br> */\n/g'
    HOST: 127.0.0.1
    User: root
    --------------------------------
    HOST: ::1
    User: root
    --------------------------------
    HOST: kvm8.deyu.wang
    User: root
    --------------------------------
    HOST: localhost
    User: root
    --------------------------------
    Fetched data successfully
    
  7. escape.php 的變數 $user$_GET['user'] 經 addslashes() 函式處理過,所以即使查詢變數改成 user=a' or 'a'='a,滿足其前後單引號的語法,也無法 sql injection 了。
    [root@kvm8 html]# curl -s http://kvm8.deyu.wang/escape.php?"user=a'%20or%20'a'='a"
    Fetched data successfully
    



De-Yu Wang 2020-04-07