从URL get参数安全地实例化PHP类?

时间:2018-04-26 11:51:31

标签: php security parameters templating

我已经编写了一个代码片段,应该根据get参数实例化一个php类。

(根据@ sietse85和@CBroe的建议编辑的代码:)

  $this->pageVal = preg_replace('/[^A-Za-z]/', '', filter_input(INPUT_GET, 'page')) ? preg_replace('/[^A-Za-z]/', '', filter_input(INPUT_GET, 'page')) : "index";

  $file = $this->moduleDir . $this->pageVal . ".php";
  if (file_exists($file)) {
    require_once $file;
    $class = new $this->pageVal($this);
  } else {
    header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found", true, 404);
    $this->loadPage("404");
  }

在这个类似的问题中被警告要做这样的事情: Call PHP function from url?

在其他问题中,人们有时会在使用不安全的代码时收到警告 - 现在我尝试通过使用filter_input根据这些警告删除某些安全问题(在我的代码中)并且只需要存在的文件。也许这还不够或不是正确的程序?

我是否应该将现有网页和可能的参数列入白名单,或者做其他事情以避免安全问题或者这不是必需的?

像这样:

$existingPages = ["index", "profile", "login", "register"];

if(in_array(filter_input(INPUT_GET, 'page'), $existingPages)) {

  //GO ON WITH PROCESSING
  $this->pageVal = filter_input(...)

}

如果我的问题背景不明确从您的角度,请描述问题以帮助我指定它。

谢谢!

1 个答案:

答案 0 :(得分:0)

  

我尝试使用filter_input

根据这些警告删除安全问题(在我的代码中)

抱歉 - 您没有删除安全问题,此代码仍然容易受到目录遍历的影响。 filter_input()函数是恕我直言非常不适当的函数。您永远不应该更改输入的表示,但您应该验证它。但是,需要告诉filter_input()如何验证它。并且它没有部分文件名的选项。

  

我应该将现有网页列入白名单

如果您修复了目录遍历问题,那么您已将可运行的脚本列入白名单 - 只能在指定目录中运行脚本。

考虑:

$this->pageVal = basename($_GET['file']);
$file = $this->moduleDir . $this->pageVal . ".php";
if (!is_readable($file)) {
    trigger_warning("User attempted to access non-existent code: " 
      . base64encode($_GET['page']), E_USER_WARNING);
    $this->pageVal = 'index';
    $file = $this->moduleDir . $this->pageVal . ".php";
}
require_once $file;

使用正则表达式删除/保留任意字符不是一个优雅的解决方案。