简体   繁体   English

使用PHP的动态内容

[英]Dynamic content using PHP

I am currently working on a website and I want to use PHP for dynamic site loading. 我目前正在网站上工作,我想使用PHP进行动态网站加载。

Right now I came up with this... 现在我想到了这个...

if (preg_match('/^[a-z0-9]+$/', isset($_GET['site']))) {
    $general      = realpath('includes/general/' . $_GET['site'] . '.php');
    $laboratories = realpath('includes/laboratories/' . $_GET['site'] . '.php');
    $validation   = realpath('includes/validation/' . $_GET['site'] . '.php');
    $training     = realpath('includes/training/' . $_GET['site'] . '.php');
    $reagents     = realpath('includes/reagents/' . $_GET['site'] . '.php');

    if ($general) {
        include $general;
    } else if ($laboratories) {
        include $laboratories;
    } else if ($validation) {
        include $validation;
    } else if ($training) {
        include $training;
    } else if ($reagents) {
        include $reagents;
    } else {
        $default = realpath('includes/general/home.php');
        include $default;
    }
} else {
    $default = realpath('includes/general/home.php');
    include $default;
}

What do you think about this? 你怎么看待这件事? Is it safe? 安全吗?

As for each value that $_GET['site'] can carry there is only one file to include, you can store that mapping in a whitelist: 至于$_GET['site']可以携带的每个值,只需包含一个文件,您可以将该映射存储在白名单中:

$include_path    = '/path/to/includes';
$include_default = '/general/home.php';
$includes        = [
    'home' => 'general/home.php',
    // ...    
    'lab-zero' => 'laboratories/lab-zero.php',
    // ...
];

$include = $include_default;

if (isset($includes[$_GET['site']])) {
    $include = $includes[$_GET['site']];
}

$path = $include_path . $include;
$real = realpath($path);

if ($real === $path && is_readable($real)) {
    include $real;
}

Only those $_GET['site'] parameters are then allowed, that do make sense (those which have been made plans for, those that have been configured in $includes array). 然后仅允许那些确实有意义的$_GET['site']参数(已计划的参数,已在$includes数组中配置的参数)。

Additionally if the whitelist contains an error, that file is not included ( realpath and is_readable checks). 此外,如果白名单包含错误,则不包含该文件( realpathis_readable检查)。

As you can also see, the value of $_GET['site'] has been fully shielded from the include path parameter. 如您所见, $_GET['site'] _ $_GET['site']已与include path参数完全屏蔽。 This is only possible with a whitelist which makes this approach pretty stable. 只有通过白名单才有可能,这使得此方法相当稳定。

Most importantly, this effectively protectes against traversal attacks which your code has been prone for by having a flaw in the checks and by white-listing against the file-system which is dangerous. 最重要的是,这可以有效地防止遍历攻击,而这种遍历攻击是代码中存在缺陷的危险,并且是针对危险的文件系统的白名单。

I had to make some changes to get your code to work. 我必须进行一些更改才能使您的代码正常工作。

            <?php               
                $include_path    = 'includes/';
                $include_default = 'general/home.php';
                $includes        = [
                    'home' => 'general/home.php',                     
                    'laboratories' => 'laboratories/laboratories.php',
                    'validation' => 'validation/validation.php',
                    'training' => 'training/training.php',
                    'reagents' => 'reagents/reagents.php',
                ];

                $include = $include_default;

                if (isset($_GET['site'])) {             
                    $include = $includes[$_GET['site']];            
                }

                $path = $include_path . $include;
                $real = realpath($path);

                if (is_readable($real)) {               
                    include $real;
                }
            ?>

Is this still safe as 这样仍然安全吗

      if ($real === $path && is_readable($real)) { 

wouldn't work since it's comparing two different things. 因为它在比较两个不同的东西,所以不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM