【问题标题】:Anything wrong with this PHP这个 PHP 有什么问题
【发布时间】:2010-11-01 05:08:57
【问题描述】:

您能看出这段代码有什么问题吗,或者可以对其进行优化吗?

来自 index.php 的代码,用于包含文件

if(empty($_GET['t'])) { 
    $folder = "apps/"; 
}else {
    $folder = str_replace("/", "", $_GET['t']) . "/"; 
}    

if(empty($_GET['app'])) { 
    include('apps/home.php'); 
} else { 
    if(file_exists($folder.$app.".php")) { 
        include($folder.$app.".php"); 
    } else  { 
        include("/home/radonsys/public_html/global/error/404.php");
    }
}

我的问题?一个页面,它发布到自己没有找到它的页面并返回到那个 404 页面。

如果需要,我可以包含该页面的表单代码吗?

来自 bugs.php 的代码

<form method="post" action="">
    <div>Title</div>
    <div><input name="title" type="text" class="bginput" value="" size="59" tabindex="1" /></div>
    <br />
    <div>
        <label class="smallfont">
            Application
            <select name="app" style="display:block; width:200px" tabindex="2">
                <option value="Admin CP">AdminCP</option>
                <option value="Add User">Add User</option>
                <option value="Bugzilla">Bugzilla</option>
                <option value="Portal">Portal</option>
                <option value="To Do">To Do</option>
                <option value="Internal Messages">Internal Messages</option>
                <option value="User CP">UserCP</option>
                <option value="Change Password">Change Password</option>
                <option value="Change Email">Change Email</option>
                <option value="General">General</option>
            </select>
        </label>
    </div>
    <br />
    <div>Bug Description</div>
    <textarea name="content" style="width:7%"></textarea>
    <br />
    <div>
        <label class="smallfont">
            Priority
            <select name="priority" style="display:block; width:200px" tabindex="2">
                <option value="0" selected="selected">Unknown</option>
                <option value="1">1 - Highest</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5 - Medium</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
                <option value="10">10 - Lowest</option>
            </select>
        </label>
    </div>
    <br />
    <input type="submit" value="Save" />
</form>

澄清

上面的脚本在index.php中,它在页面上调用,例如,?app=bugs在apps文件夹中包含bugs.php。

bugs.php 脚本中的内容使用 POST 向自身发送数据,但是,由于我们遇到错误页面 404.php,因此发布数据永远不会到达页面本身

【问题讨论】:

    标签: php html forms include directory


    【解决方案1】:

    您是说表单向自身发布,这是否意味着您正在使用 POST?
    如果是这样,您需要将 $_GET[] 更改为 $_POST[]

    你发布的代码越多越好。

    【讨论】:

      【解决方案2】:

      一些cmets:

      • 如果您愿意,可以使用 $_REQUEST 从 POST 或 GET 获取变量。
      • 您似乎没有设置 $app 任何地方。
      • 您可能需要考虑对包含的文件更加严格(例如,文件名必须匹配的白名单或模式)。

      【讨论】:

      • 已定义 $app,可能会更改为 $_REQUEST 并在初始 alpha 或应用程序后使用白名单更加严格。
      【解决方案3】:

      嗯,为什么某个应用程序/页面有问题的答案是因为选择 id 是 app,顺便说一下,它是页面的 app 变量,所以它没有获取正确的页面。

      提示 请记住仔细命名您的属性!

      【讨论】:

        【解决方案4】:

        您遇到的问题是因为您在表单标签中使用了method="post",并试图从$_GET 获取数据。

        method = "post" 时,表单值可通过$_POST['fieldname']$_REQUEST['fieldname'](包含POST 和GET 值)访问。您还可以将表单的 method 更改为 GET

        但是,我能看到的最大问题是..

        include($folder.$app.".php"); 
        

        这太可怕了,尤其是如果您使用的是 register_globals(在您发布的代码中,这是 $app 唯一可能来自的地方)

        $_GET['app'] 设置为..

        ../../something/else.php
        

        ..你会包括..

        $_GET['t'] . "../../something/else.php"
        

        如果您必须根据用户输入动态包含文件,则去掉所有非字母数字字符,并拥有有效文件的白名单 - 如下所示:

        $valid_files = array("General", "Todo");
        $safe_filename = preg_replace("/[^a-zA-Z0-9]/", "", $_REQEST["app"]);
        if(in_array($safe_filename, $valid_files)){
            include("apps/" . $safe_filename . ".php");
        }
        

        还有其他的路由方式,例如使用header("location: ...")

        header ('HTTP/1.1 301 Moved Permanently');
        header ('Location: ' . $new_location);
        

        当然,您必须安全地清理 $new_location,但它比使用 include() 问题更少(因为它不会在您的服务器上动态执行任意脚本)

        基本上,脚本会执行以下操作:

        $safe_filename = preg_replace("/[^a-zA-Z0-9]/", "", $_REQUEST["app"]);
        $new_location = "/apps/" . $safe_filename . ".php"; // construct new URL
        
        // If it's valid, redirect, if not, return error 404
        if(in_array($safe_filename, $valid_destinations)){
            header ('HTTP/1.1 301 Moved Permanently');
            header ('Location: ' . $new_location);
        } else {
            header("HTTP/1.0 404 Not Found");
        }
        

        【讨论】:

        • 您的正则表达式正在从字符串中删除所有内容。
        • 拥有一个白名单会产生大量的字节,因为有很多很多的文件。
        猜你喜欢
        • 2011-08-26
        • 2011-10-19
        • 2011-02-13
        • 2011-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多