保护控制器PHP(MVC)

时间:2014-06-04 15:15:47

标签: php security

我知道动态加载请求的类是非常不安全的,但它确实在我的代码中节省了很多复杂性......

这是否安全,或者用户是否有机会利用此功能? 这是我的代码:

$currentPage = Classes\stdlib::GetVariable("view"); //Gets a variable from $_GET and escapes it...
$isAdmin = isset($_GET["admin"]);
$view = "";
$content = null;
$allowedViews = array("Admin","Brukere","Fag","Fravær","Kontakt","Login","Profil","Registrer");
if (in_array($currentPage,$allowedViews,true)) {
    $view = "Views\\$currentPage";
    $content = new $view(); // <--- This is usualy unsecure since its derived from user request
}

//Using $content later in the code....

如果允许的话,这基本上只是加载类(in_array)。

你们觉得怎么样?主要安全漏洞还是OK?

1 个答案:

答案 0 :(得分:0)

正如Marc B.所说,包含include($_GET['foo']) 等代码的文件不安全,因为它是一个文件包含漏洞。例如,攻击者可以上传包含PHP代码的完全有效的图像文件,并通过更改$_GET['foo']的值来将其包含在此代码中。因此,只有在验证输入后才能使用include()。有几种方法可以做到这一点,例如

$map = array('bar' => 'bar.php');
if (!isset($map[$_GET['foo']]))
    throw new \Exception();
include($map[$_GET['foo']]);

或仅使用if-else

if ($_GET['foo'] == 'bar')
    include('bar.php');
else
    throw new \Exception();

使用自动加载解决了同样的问题。它定义了如何构建类 - 文件映射的规则,因此风险较低。例如,这个易受攻击的代码

$foo = $_GET['foo'];
$bar = new $foo();
$bar->doSomething();

他只能检查系统中可用的类,并且可能使用doSomething()方法对您使用可用的类。这仍然是一个安全风险,但不像文件包含那么大。

因此,通过使用类,您应该执行相同的映射或if-else,就像我在开头写下的那样:

if ($_GET['foo'] == 'bar' && $_SESSION['isAdmin'])
    $view = new Views\AdminView();
else
    $view = new Views\RegularView();
$view ->doSomething();

我不认为拥有允许的视图类列表是最佳实践。我认为您应该在查询数据之前进行授权。通过渲染视图,您通常已经从数据库或文件中获取了一些数据,但我们不希望未经授权的用户发送该查询,因为它完全是多余的,只是在服务器上占用资源。

在你的代码中$isAdmin = isset($_GET["admin"]);非常奇怪。每个人都可以设置该参数,因此使用它来决定某人是否是管理员将是一个非常巨大的设计缺陷。来自$_GET$_POST的每个变量都可以伪造(OAuth请求签名和CSRF令牌除外:D)。尝试详细了解会话,身份验证和授权,如果您对安全性有任何疑问,请在此处提出:https://security.stackexchange.com/