PHP 之防sql注入示例
一、效果图
1、存在sql注入
2、消除sql注入
二、简单示例
1、创建表
2、提交界面设计
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录</title> </head> <body> <form action="?" method="POST"> <input type="text" name="username" placeholder="请输入用户名"><br> <input type="password" name="password" placeholder="请输入密码"><br> <input type="submit" value="提交"> </form> </body> </html>
3、编写可注入的php代码
if($_POST) { extract($_REQUEST); $conn = mysqli_init(); mysqli_real_connect($conn, '127.0.0.1', 'test', '123456'); //连接数据库 mysqli_select_db($conn, 'test'); //选择数据库 if(!$username || !$password) { die('error'); } $sql = insertSql('test', [ 'username' => $username, 'password' => $password ]); $res = mysqli_query($conn, $sql); mysqli_close($conn); if($res) { die('ok'); } die('err'); }
4、使用sqlmap测试
python sqlmap.py --url="http://localhost/test/test2.php" --dbs --data="username=yy&password=123" --method="post" --flush-session --dbms=mysql --level=5 --risk=3 --random-agent --tamper=space2comment
三、解决sql注入
<?php if($_POST) { //处理sql注入 $_REQUEST = strip_sql($_REQUEST); extract($_REQUEST); $conn = mysqli_init(); mysqli_real_connect($conn, '127.0.0.1', 'test', '123456'); //连接数据库 mysqli_select_db($conn, 'test'); //选择数据库 if(!$username || !$password) { die('error'); } $sql = insertSql('test', [ 'username' => $username, 'password' => $password ]); $res = mysqli_query($conn, $sql); mysqli_close($conn); if($res) { die('ok'); } die('err'); } /** * 拼接sql语句 * @param $table * @param $array * @return string */ function insertSql($table, $array) { $sqlk = ''; $sqlv = ''; foreach ($array as $k => $v) { $sqlk .= ',`' . $k.'`'; $sqlv .= ',"'.$v.'"'; } $sqlk = substr($sqlk, 1); $sqlv = substr($sqlv, 1); $sql = "insert into $table ($sqlk) values ($sqlv)"; return $sql; } function strip_sql($string, $type = 1) { if(is_array($string)) { return array_map('strip_sql', $string); } else { if($type) { $string = preg_replace("/\/\*([\s\S]*?)\*\//", "", $string); $string = preg_replace("/0x([a-fA-d0-9]{2,})/", '0x\\1', $string); $string = preg_replace("/0X([a-fA-d0-9]{2,})/", '0X\\1', $string); $string = preg_replace_callback("/(select|update|replace|delete|drop)([\s\S]*?)(from)/i", 'strip_wd', $string); $string = preg_replace_callback("/(load_file|substring|substr|reverse|trim|space|left|right|mid|lpad|concat|concat_ws|make_set|ascii|bin|oct|hex|ord|char|conv)([^a-z]?)\(/i", 'strip_wd', $string); $string = preg_replace_callback("/(union|where|having|outfile|dumpfile)/i", 'strip_wd', $string); return $string; } else { return str_replace(array('_','d','e','g','i','m','n','p','r','s','t','v','x','E','R','T','X'), array('_','d','e','g','i','m','n','p','r','s','t','v','x','E','R','T','X'), $string); } } } function strip_wd($m) { if(is_array($m) && isset($m[1])) { $wd = substr($m[1], 0, -1).'&#'.ord(substr($m[1], -1)).';'; if(isset($m[3])) return $wd.$m[2].$m[3]; if(isset($m[2])) return $wd.$m[2].'('; return $wd; } return ''; } ?>