2010-04-11 56 views
3

我想知道我的代碼是否安全,並且如果有其他更安全的替代方案來包含外部文件..PHP include()替代?

所以這是我的代碼示例,它是否安全?我怎樣才能讓它更安全?謝謝!

<?php switch($_GET['p']){ 
    case 'test1': 
     include 'test1.php'; 
     break; 
    case 'test2': 
     include 'test2.php'; 
     break; 
    case 'test': 
       echo 'something'; 
     include 'pages/test.php'; 
       echo 'something'; 
     break; 
    default: 
     include 'main.php'; 
     break; 
} ?> 

回答

6

你的代碼很好。當文件名被硬編碼時,沒有條件地包括像你這樣的文件的問題。當所包含的文件基於來自用戶的未經過清理的值時,會發生該問題。例如

include $_GET['p']; 

可以包括任何用戶想要(取決於PHP設置它可能還包括其他領域的文件)

其他選項都在變化你在做什麼

requirerequire_once如果文件不存在就會失敗。 inlucde_oncerequire_once確保該文件只包含一次,所以該文件已包含在程序中的其他位置,因此不會包含該文件。

include_once 'myfile.php'; 
include_once 'myfile.php'; //does nothing as the file is already included 

如果您有使用類,也有autoloader的選項。從應用程序的外觀來看,您將不得不重新構建它,以便能夠使用它。

0

鑑於你只包括你已經硬編碼的,我不明白爲什麼這不安全。這些不是外部文件,但我明白你的意思。外部意味着在不同的服務器上。

至於你的問題,include的唯一替代方案是require但這並不一定安全,它只是工作不同。

0

是的,非常安全。

您正在包含知道內容的文件,而不是基於來自外部來源的變量來執行此操作。如果無法加載,include將不會導致腳本失敗,如果這是您想要的結果,請選擇require('filename');

-1

你可以做更多的可讀性,如下所示:

$safeIncludes = array('test1', 'test2', 'test3'); 
$p = $_GET['p']; 
if(in_array($p, $safeIncludes)) { 
    $scriptName = $p . '.php'; 
    include($scriptName); 
} 

除此之外,它安全的,因爲其他人指出。

+0

但是如果它只有幾頁,是否真的值得分配一個數組並搜索它,如果一個簡單的開關()可以做到?我不明白爲什麼它現在不可讀? (除非病例明顯增加,即20+) – 2010-04-11 15:51:37

+0

@Tim Post也許是這樣 - 我認爲這值得暗示,因爲任何進一步的修改只需要在陣列上進行。此外,如果他決定將允許的腳本列表存儲在數據庫中,他會*需要*類似上面的內容。 – karim79 2010-04-11 15:56:03

+0

這實際上並不匹配提供的代碼 - 沒有默認值,測試也沒有處理。它比較短,但對新手程序員來說不是(可以說)更具可讀性。 – AndyS 2016-02-13 22:55:36

0

它是安全的,並且switch語句使得邏輯更清晰。只是爲了使它更安全,也許你可以使用$ __ POST來隱藏開關變量數據源,使它更安全。 :D

1

您甚至可以在進入交換機之前考慮檢查$_GET['p']的內容。如果它包含特殊字符,垃圾或其他東西,你的程序可能需要記錄事件(而不是浪費時間來渲染頁面)。

至少,一個很好,有禮貌的「對不起,我們無法處理您的請求」頁面將是有序的。

這仍然允許切換到主頁面,前提是p包含了值得開關評估的東西。

如果主頁面執行任何數量的查詢以進行渲染,則尤其如此。遲早,有人會注意到你的URI結構並決定使用它可能很有趣,不要在白癡上燒掉CPU週期:)