PHP 開發中有效防禦 SQL 注入攻擊有哪些好方法?

時間 2021-05-31 02:00:59

1樓:eechen

可以用預處理引數化查詢手動轉義引數來防禦SQL注入,不僅僅PHP開發中如此,其他語言中大多也是如此.甭管什麼Query Builder還是ORM,最終還是要轉換成SQL交給資料庫執行,所以它們底層同樣需要通過預處理引數化查詢或手動轉義引數來避免被SQL注入,沒有任何黑科技.

比如medoo.php這個PHP實現的Query Builder,就是通過PDO::quote($param)手動轉義引數,然後通過exec/query來執行SQL,其並沒有使用預處理引數化查詢(prepare($sql)/execute(array($param)).

把所有引數當成字串來處理是必要的.也就是說intval($_GET['id'])雖然能把$_GET['id']轉成整數,但存在乙個問題,如果$_GET['id']是乙個大於PHP_INT_MAX的數,intval將不能正常處理.而資料庫中的unsigned bigint(20)的大小相當於2倍64位PHP_INT_MAX的大小,所以有必要把$_GET['id']當做字串來處理.

另外,大於PHP_INT_MAX的數的運算應該使用PHP內建的bcmath或者gmp擴充套件.

下面分別演示pdo_mysql和mysqli的SQL IN()語句的預處理引數化查詢:

<?

php//id IN ($ids) 佔位符生成

function

(array

$params

)function

(array

$ids

)` WHERE `id` IN ()";

$stmt

=$db

->prepare

($sql

);$stmt

->execute

($ids

);//所有id都當做字串處理,值傳遞.

return

$stmt

->fetchAll

(PDO

::FETCH_ASSOC);}

function

(array

$ids

)` WHERE `id` IN ()";

$stmt

=$db

->prepare

($sql

);//MySQLi自動化"引用繫結"引數(因為mysqli的execute不像pdo的execute支援引數陣列傳遞,所以顯得麻煩些)

$params

=array_merge

(array

(str_repeat

('s'

,count

($ids

))),

$ids

);//array('sss', 1, 3, 5)

foreach

($params

as$k

=>$v)

//因為bind_param要求傳遞引用.

call_user_func_array

(array

($stmt

,'bind_param'

),$params

);//相當於$stmt->bind_param('sss', $ids[0], $ids[1], $ids[2]);

$stmt

->execute

();return

$stmt

->get_result

()->

fetch_all

(MYSQLI_ASSOC);}

用tail -f /path/to/mysqld/general_log檢視MySQL的SQL日誌可見:

Prepare

SELECT

*FROM``

WHERE`id

`IN(?

,?,?

)Execute

SELECT

*FROM``

WHERE`id

`IN('1'

,'3'

,'5'

)Close

stmt

2樓:

1、不要隨意開啟生產環境中Webserver的錯誤顯示。

2、永遠不要信任來自使用者端的變數輸入,有固定格式的變數一定要嚴格檢查對應的格式,沒有固定格式的變數需要對引號等特殊字元進行必要的過濾轉義。

3、使用預編譯繫結變數的SQL語句。

4、做好資料庫帳號許可權管理。

5、嚴格加密處理使用者的機密資訊。

來自 「Web安全之SQL注入技巧與防範」。

3樓:林燦斌

使用PDO或者MySQLi,有很多封裝好的方便的Class。

例如使用PHP-PDO-MySQL-Class · GitHub(這個Class使用上比較類似Python的MySQLdb)的話,這樣就是安全的:

<?

php$DB

->query

("SELECT * FROM fruit WHERE name IN (?)"

,array

($_GET

['pm1'

],$_GET

['pm2'

]));

$DB->

query

("SELECT * FROM users WHERE name=? and password=?"

,array

($_GET

['name'

],$_GET

['pw'

]));

?>

直接拼接字串則是危險的:

<?

php$DB

->query

("SELECT * FROM fruit WHERE name IN ('"

.$_GET

['pm1'].

"','"

.$_GET

['pm2'].

"')"

);$DB

->query

("SELECT * FROM users WHERE name='"

.$_GET

['name'].

"' and password='"

.$_GET

['pw'].

"'");

?>

PDO引數繫結的原理是將命令與引數分兩次傳送到MySQL,MySQL就能識別引數與命令,從而避免SQL注入(在引數上構造命令)。

mysql在新版本PHP中已經預廢棄,使用的話會丟擲錯誤,現在建議使用MySQLi或者MySQL_PDO。

4樓:

通常有一下幾種方法:

(1)輸入驗證和過濾

(2)預處理Sql語句

(3)採用儲存過程

(4)輸入白名單

其他的安全建議:

資料庫最小特權連線, 安全編碼才是王道!

5樓:雷伯

防SQL注入最好的方法就是千萬不要自己拼裝SQL命令和引數, 而是用PDO的prepare和bind.

原理就在於要把你的SQL查詢命令和傳遞的引數分開:

> prepare的時候, DB server會把你的SQL語句解析成SQL命令.

> bind的時候, 只是動態傳參給DB Server解析好的SQL命令.

其他所有的過濾特殊字串這種白名單的方式都是浮雲.

6樓:harry

參考 PHP 的官方擴充套件 Filter http://

au2.php.net/manual/zh/b

ook.filter.php

php開發中有什麼經典的輪子值得自己去實現一遍?

MVC必須自己實現一遍。然後是實現下 Route 至於實現Db那是基本功 Model的話可以研究實現下 SPL 裡面的ArrayAccess 介面 完成上面這些,基本的框架就成型了。接下來可以試試實現系統的許可權管理 rbac 或者 acl都可以實現了這些,乙個基本的後台就搭建完了 冷夜草 首先必須...

php開發介面系統,使用框架和原生php開發的效能和安全問題怎麼考慮?

框架和安全沒有必然聯絡。當然框架提供的庫可能會提供一些常見問題的解決方法。如果真的是5W併發,系統瓶頸也跟框架關係不大了,還要考慮頻寬,前端 儲存系統的處理能力。只要系統能有基本的可伸縮性,多幾部署個節點可以抵消框架帶來的負面影響 值不值可以根據自己的情況計算 但這樣壓力會集中到下層的儲存服務上 D...

平面轉前端開發,再做php開發,再做python。各位高手看看這條路怎麼樣?

李曄 題主列出來的技能中,很多都是那種入門簡單,但深鑽一下又都很有東西的型別。但你要想明白最終要做的是什麼。如果目標是前端的話,學好HTML,JS就可以了,處理好各瀏覽器相容,JS是一門通用性很強的語言,目標是前端的話,主要用到的地方就是處理dom。再說php,Python,node.js,看題主這...