【问题标题】:What's the best practice to hide a form-processing file, from direct access?从直接访问中隐藏表单处理文件的最佳做法是什么?
【发布时间】:2014-04-01 12:07:38
【问题描述】:

我有一个包含此代码的表单:

<form action="/directory/" method="POST" target="_blank">
<input name="hello" type="hidden" value="something"/>
<input name="there" type="hidden" value="something"/>

/directory/ 文件夹中,我放置了一个index.php 文件,用于处理表单,代码如下:

<?php 

if(isset($_POST['hello']));

switch ($_POST['hello']) {

    case "1":
        $var1 = "word1";
        break;

    case "2":
        $var1 = "word2";
        break;

    default:
        $var1 = "other";
}
?>

<?php 

if(isset($_POST['there']));

switch ($_POST['there']) {

    case "1":
        $var2 = "word3";
        break;

    case "2":
        $var2 = "word4";
        break;

    default:
        $var2 = "other";
}
?>   
<!doctype html>
<html>
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div>
Content, <?php echo $var1; ?>, Content, <?php echo $var2; ?>, Content.
</div>
</body>
</html>

但我不希望好奇的用户能够直接转到 mydomain.com/directory/ 并查看 index.php 的输出,除非他通过表单到达那里。

那么我如何隐藏/使index.php 不可访问,或者更改.php 中的某些内容,同时或多或少地保留action="/directory/" 标记?

最好的做法是什么?

【问题讨论】:

  • 如果你完全不希望/directory/被直接访问,你可以在目录中创建.htaccess文件并保存在其中deny from all。为我工作。
  • 刚试了一下,使用表单时也拒绝访问。
  • 试试deny from all allow from 127.0.0.1
  • 不,那也没用..

标签: php forms post http-post form-submit


【解决方案1】:

但我不希望好奇的用户能够直接访问 mydomain.com/directory/ 并查看 index.php 的输出,除非他通过表单到达那里。

我认为您不了解 HTTP 请求的工作原理。当用户提交表单时,他们不一定通过表单到达那里。他们只是向特定资源(在本例中为/directory/index.php)提交 POST 请求。为了让该资源接受来自用户的 POST 请求,他们需要能够访问它。

表单所做的只是向用户提供有关该资源在 POST 请求中期望什么的信息,例如它正在寻找的值。但是这样的请求也可以手动发出,服务器不知道有什么区别。如果您愿意,您可以将对该资源的访问限制为 POST 请求。实现这一点的一种方法可能是让页面检查$_POST[] 的存在,并确保它具有预期的值(您已经这样做了)。

如果您想确保用户必须首先请求表单并且只有然后执行 POST 请求,那么您可能需要以某种方式跟踪该状态。一种方法是提供一个唯一令牌作为表单的一部分。隐藏表单域中的 GUID 对此非常有效。当您显示表单时,您将在数据库中跟踪生成的令牌(甚至可能为其分配时间戳以便它可以过期)。然后在您的 POST 处理程序页面中,您将提交的令牌与数据库中的已知令牌进行比较,如果不匹配则显示错误。这将允许您拒绝不包含已知令牌的 POST 请求,要求用户在执行 POST 之前首先请求表单。


针对下面的 cmets,如果页面的某些前提条件失败,您可以返回错误而不是显示内容。这可能很简单:

<?php
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
?>
    <p>This is an error message.</p>
<?php
    } else {

?>
    <p>This is the normal page content.</p>
<?php
    }
?>

有很多不同的组织方式。也许结束响应而不是将其余部分放在else 块中?我的 PHP 有点生疏了,但你应该能够弄清楚一些事情。您甚至可以只返回一个 HTTP 错误代码并让用户自己弄清楚:

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        header('HTTP/1.1 500 Internal Server Error');
    } else {
?>
    <p>This is the normal page content.</p>
<?php
    }
?>

有很多HTTP error codes 可供选择。最终,逻辑和布局是你想要的。您可以控制向用户显示的内容以及显示该内容的逻辑条件。

【讨论】:

  • 恐怕这个令牌/GUID 真的超出了我的知识范围,而且对于我想要实现的目标来说听起来也很复杂。在第二段中,您的意思是我应该通过检查 $var 值是否设置为 other 来向用户显示不同的内容?我该怎么做?
  • @rockyraw:其实并没有那么复杂,而且它确实是一种标准的方法来跟踪用户提出了哪些请求的状态(例如,防止用户多次大量发布表单) .它所涉及的只是生成一个标识符并将其存储在数据库中。至于显示不同的内容,你绝对可以做到。当 POST 处理程序首次加载时,您可以检查请求是否包含您期望的内容,如果没有,则显示错误而不是页面内容。您可以完全控制在任何给定页面上显示的内容。
  • 我目前没有在网站上使用任何数据库。你能给我一个例子 php sn-p 如何显示这样的错误吗?那会是某种 if/else 命令,如果使 url 重定向到错误页面?不知道应该如何最好地完成。谢谢!
  • 太好了,我想这正是我需要的。这有什么缺点或可能的黑客攻击吗?例如,与您描述的第一种方法相比?
  • @rockyraw:好吧,精明的用户仍然可以对表单进行逆向工程并重复它。因此,他们也许可以一次获取表单,将键/值对加载到程序中,然后一遍又一遍地将其发布到页面上。这对你来说可能是也可能不是问题。如果不是,没问题。
【解决方案2】:

您应该查看 htaccess 限制,访问此链接:

http://www.javascriptkit.com/howto/htaccess.shtml

【讨论】:

  • 我看了看,并不确定那里列出的哪些规则适合我的特定目的......
猜你喜欢
  • 1970-01-01
  • 2021-07-04
  • 2010-11-05
  • 1970-01-01
  • 2010-10-09
  • 2011-06-06
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
相关资源
最近更新 更多