我知道动态加载请求的类是非常不安全的,但它确实在我的代码中节省了很多复杂性......
这是否安全,或者用户是否有机会利用此功能? 这是我的代码:
$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?
答案 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/