SQL Injection注入漏洞的防范:
1、對輸入進行嚴格的轉義和過濾
2、使用參數(shù)化(Parameterized Query 或 Parameterized Statement)
--推薦的做法
3、使用存儲過程
1、PHP防范案例
轉義舉例:
1 2 3 4 5 6 7 8 9 10 11 | function escape($link,$data){
if (is_string($data)){
return mysqli_real_escape_string($link,$data);
}
if (is_array($data)){
foreach ($data as $key = >$val){
$data[$key] = escape($link,$val);
}
}
return $data;
}
|
過濾舉例:(黑名單)
1 | str_replace( "%" ,"",$_POST[ 'username' ]),把post里面的數(shù)據(jù)里面含有 % 的替換成空
|
推薦的做法:使用參數(shù)化(先解析語法,而不是直接將參數(shù)拼接到SQL中)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $username = $_GET[ 'username' ];
$password = $_GET[ 'password' ];
try {
$pdo = new PDO( 'mysql:host=localhost;dbname=ant' , 'root' , 'root' );
$sql = "select * from admin where username=? and passowrd=?" ;
$stmt = $pdo - >prepare($sql); / / 先不傳參數(shù),先解析語法
/ / var_dump($stmt);
$stmt - >execute(array($username,$password));
/ / 這個時候在把參數(shù)傳進去,以索引數(shù)組的方式傳進去,就成功防止了注入
}catch (PDOException $e){
echo $e - >getMessage();
}
?>
|
2、python防范案例
不安全的寫法: 直接將變量拼到SQL,產(chǎn)生注入
1 2 3 4 5 | import psycopg2
def bla_range_result( self ,startid,endid):
range_result = “select * from result where id > = % s and id < = % s” % (startid,endid)
self .cur.execute(range_result)
self .db.commit()
|
不安全的寫法: 使用psycopg2的占位符寫法
1 2 3 4 5 | import psycopg2
def bla_range_result( self ,startid,endid):
range_result = "select * from result where id>=%s and id<=%s"
self .cur.execute(range_result,(startid,endid))
self .db.commit()
|
3、使用存儲過程
使用存儲過程的效果和參數(shù)化查詢語句類似,其區(qū)別就是存儲過程需要先將SQL語句定義在數(shù)據(jù)庫中。但需要注意的是,存儲過程中也可能會存在注入問題。因此應該避免在存儲過程內使用動態(tài)的SQL語句。