【问题标题】:Problem with some simple code一些简单代码的问题
【发布时间】:2009-07-10 20:44:08
【问题描述】:
<?php

// get all files from pages/ with .php extension
$pages = glob('pages/*.php');

foreach ($pages as $page) {

// remove path
$page_clean = str_replace('pages/', '', $page);

// put it in an array
$allowed_pages = array($page_clean);

// determine that the lank will be index.php?page=%
$page = $_GET['page'] . '.php';

// load page
if(in_array($page, $allowed_pages)) {
  include('pages/' . $page);
} else {
echo "Page not found.";
}

}

?>

它确实包括我要求的页面,但它也回显“未找到页面”。我在这里做错了什么?

一个爱

【问题讨论】:

  • 请注意,您应该使用basename($file) 而不是str_replacephp.net/basename
  • 我可以说你的方法非常危险。假设您在 pages/script.php 中有一些危险代码,一个坏人只需在 Web 浏览器中键入 index.php?page=script 并且 script.php 将被自动加载。使用 if / else if 的开关,它的代码更多但更安全。

标签: php


【解决方案1】:

if 块不应该在循环中。此外,您构建的数组不正确。试试:

<?php

// get all files from pages/ with .php extension
$pages = glob('pages/*.php');

$allowed_pages = array();
foreach ($pages as $page) {
    // remove path
    $page_clean = str_replace('pages/', '', $page);

    // put it in an array
    $allowed_pages[] = $page_clean;
}

// determine that the lank will be index.php?page=%
$page = $_GET['page'] . '.php';

// load page
if(in_array($page, $allowed_pages)) {
    include('pages/' . $page);
} else {
    echo "Page not found.";
}

【讨论】:

    【解决方案2】:

    您不应该在每次请求时浏览整个目录来查看给定文件是否存在。只需检查该特定文件是否存在:

    if (strpos($page, '..') !== false || strpos($page, '/') !== false) {
        // invalid value, but you better use a whitelist than a blacklist like I did
    } else {
        if (is_file('pages/'.$page.'.php')) {
            // file exists
        } else {
            // file doesn’t exist
        }
    }
    

    【讨论】:

    • +1,是的,看起来这确实是他想要做的事情。奇怪的是他选择了glob 函数(事实上,直到今天我才听说过这个函数......)。 PHP 和它疯狂的数百万核心函数,哈哈。我同意,绝对使用白名单来确保安全。 @Buggin Out:这意味着,制作一个包含所有允许的 PHP 脚本的数组,然后测试是否允许请求的文件。还有其他更安全的方法......但是,是的......足够的咆哮。 :-)
    【解决方案3】:

    我会这样做:

    if(!isset($_SESSION['allowed_pages'])) {
      $_SESSION['allowed_pages'] = array_map('basename', glob('pages/*.php'));
    }
    $page = $_GET['page'] . '.php';
    
    if(in_array($page, $_SESSION['allowed_pages'])) {
        include("pages/$page");
    }else {
        echo 'Page not found.';
    }
    

    每个会话只加载一次页面列表,并摆脱了从 glob 中清理页面名称的显式循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      相关资源
      最近更新 更多