2013-07-25 62 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笔记一样,您的伪代码使用了更安全的方法,应该很难出错。我也建议你一起去。