保护控制器PHP (MVC)


Securing controller PHP (MVC)

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

是否认为这是安全的,或者用户是否有办法利用这一点?这是我的代码:

$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?

正如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/