2013-07-25 96 views
1

在我之前的文章call function dynamically, passing arguments from variable Sven指出我的代碼易受本地文件包含的影響。我做了一些修改以防止LFI。這是足夠的還是應該擔心?Ajax處理 - 安全問題

if ($_SERVER['HTTP_X_REQUESTED_WITH'] !== "XMLHttpRequest") 
    { 
     echo "Error"; 
     exit(); 

    } 
    $req = explode("_",$_POST['req']); 
    /* 
     User input should always be escaped 
     using preg_quote before being used in a regexp pattern. 
     Thanks bwoebi 
    */ 
    $className = preg_quote($req[0]) . "Controller" ; 
    $methodName = $req[1]; 
    $args= isset($_POST["data"]) ? $_POST['data'] : array(); 


    $file = "application/controllers/" . $className . ".php" ; 

    if (!file_exists($file) || preg_match("/^[a-z]$/", strtolower($className))) 
     exit(); 

    require_once $file; 

    $controller = new $className; 
    $result = call_user_func_array(array($controller, $methodName),$args); 

    echo json_encode($result); 

另一個問題可能是用戶可以從該文件夾調用任何控制器文件的公用方法。 但據我所知,更多的框架正在使用它們的路由domain.xy/controller/method/par模式,它具有相同的風險。 (儘管在我的控制器中,我儘可能多地使用服務器端驗證)

我正在考慮將一些身份驗證放入ajax處理程序/路由器文件中。

// PSEUDO CODE 

$user = new User(); 
// maybe bad practice to store the id session after authentication. Any comment on this? 
$userGroup =$user->getUserGroupById($_SESSION["user"]); 

$security = new Security(); 
$whiteList = $security->getWhiteList($userGroup); 
//$whiteList is an array with the list of controllers the user may access 
if (!in_array(className, $whiteList)) 
exit(); 

歡迎任何評論,最佳實踐例子!

回答

1

它應該現在是安全的,因爲您不允許惡意點和NUL字節包含在正則表達式中。

但仍然不是很好的做法。你真的應該匹配你的白名單。正如你所說的那樣,它是安全的,只允許用戶選擇允許用戶選擇的控制器。

tl; dr:使用您在僞代碼中寫的內容。

0

說實話,你的代碼看起來像一團糟。

  • 不是在正規表達式使用$className,那麼爲什麼你想與preg_quote()逃生呢?

  • 你爲什麼第一檢查類文件是否存在,只有然後是否在類名甚至允許?這似乎倒退了。 (在這種情況下,不應該做任何實際損害,但它是很好的做法使用輸入任何之前做輸入驗證第一

  • 是不是你的類名無效支票倒退呢?您的

    preg_match("/^[a-z]$/", strtolower($className)) 
    

    只有在$className僅由字母組成時纔會返回true。 (此外,使用strtolower()是不區分大小寫的匹配相當低效的方式。)難道不應該是

    !preg_match('/^[a-z]$/i', $className) 
    

    甚至

    preg_match('/[^a-z]/i', $className) 
    

    呢?

如果固定所有這些東西,你的代碼力量是OK(假設,而這樣做,你沒有引入任何新的錯誤)。

你可以通過創建一個名爲application/BogusController.php的文件來測試它,看看你是否可以通過將../Bogus作爲類名來包含它。試着去思考其他可能的變化,並測試它們。

在任何情況下,就像bwoebi筆記一樣,您的僞代碼使用了更安全的方法,應該很難出錯。我也建議你一起去。