PHP安全程式設計之阻止檔名被操縱

2021-07-16 10:06:40 字數 1814 閱讀 8954

在很多情形下會使用動態包含,此時目錄名或檔名中的部分會儲存在乙個變數中。例如,你可以快取你的部分動態頁來降低你的資料庫伺服器的負擔。

<?php

include "/cache/.html";

?>

為了讓這個漏洞更明顯,示例中使用了$_get。如果你使用了受汙染資料時,這個漏洞同樣存在。使用$_get['username']是乙個極端的例子,通過它可以把問題看得更清楚。

雖然上面的流程有其優點,但它同時為攻擊者提供了乙個可以自由選擇快取頁的良機。例如,乙個使用者可以方便地通過編輯url中的username的值來察看其他使用者的快取檔案。事實上,攻擊者可以通過簡單的更改username的值為相應的檔名(不加副檔名)來察看/cache目錄下的所有擴充套件名為.html的檔案。

儘管該程式限制了攻擊者所操作的目錄和檔名,但變更檔名並不是唯一的手段。攻擊者可以創造性地達到在檔案系統中進行跨越的目的,而去察看其他目錄中的.html檔案以發現敏感資訊。這是因為可以在字串使用父目錄的方式進行目錄跨越:

上面url的執行結果如下:

<?php

include "/cache/../admin/users.html";

?>

此時,..意味著/cache的父目錄,也就是根目錄。這樣上面的例子就等價於:

<?php

include "/admin/users.html";

?>

由於所有的檔案都會在檔案系統的根目錄下,該流程就允許了乙個攻擊者能訪問你伺服器上所有的.html檔案。

在某些平台上,攻擊者還可以使用乙個null來終止字串,例如:

這樣就成功地繞開了.html副檔名的限制。當然,一味地去通過猜測攻擊者的所有惡意攻擊手段是不可能的,無論你在檔案上加上多少控制,也不能排除風險。重要的是在動態包含時永遠不要使用被汙染資料。攻擊手段不是一成不變的,但漏洞不會變化。只要通過過濾資料即可修復這個漏洞。

<?php

$clean = array();

/* $_get['filename'] is filtered and stored in $clean['filename']. */

include "/path/to/";

?>

如果你確認引數中只有檔名部分而沒有路徑資訊時,另乙個有效的技巧是通過使用basename()來進行資料的過濾:

<?php

$clean = array();

if (basename($_get['filename'] == $_get['filename'])

include "/path/to/";

?>

如果你允許有路徑資訊但想要在檢測前把它化簡,你可以使用realpath()函式:

<?php

$filename = realpath("/path/to/");

?>

通過上面程式處理得到的結果($filename)可以被用來確認是否位於/path/to目錄下:

<?php

$pathinfo = pathinfo($filename);

if ($pathinfo['dirname'] == '/path/to')

?>

如果檢測不通過,你就應該把這個請求記錄到攻擊日誌以備後查。這個在你把這個流程作為深度防範措施時特別重要,因為你要確定其它的安全手段失效的原因。

來自:

PHP安全程式設計 阻止檔名被操縱

在很多情形下會使用動態包含,此時目錄名或檔名中的部分會儲存在乙個變數中。例如,你可以快取你的部分動態頁來降低你的資料庫伺服器的負擔。php view plain copy include cache html 為了讓這個漏洞更明顯,示例中使用了 get。如果你使用了受汙染資料時,這個漏洞同樣存在。使...

PHP安全程式設計之開啟遠端檔案的風險

php有乙個配置選項叫allow url fopen,該選項預設是有效的。它允許你指向許多態別的資源,並像本地檔案一樣處理。例如,通過讀取url你可以取得某乙個頁面的內容 html contents file get contents 當被汙染資料用於include和require的檔案指向時,會產...

PHP安全程式設計之主機檔案目錄瀏覽

除了能在共享伺服器上讀取任意檔案之外,攻擊者還能建立乙個可以瀏覽檔案系統的指令碼。由於你的大多數敏感檔案不會儲存在 主目錄下,此類指令碼一般用於找到你的原始檔的所在位置。請看下例 if isset get dir elseif isset get file else function cat fil...