提问人:syaz 提问时间:10/9/2008 最后编辑:syaz 更新时间:2/3/2014 访问量:17370
阻止直接访问 PHP 页面
Prevent direct access to a PHP page
问:
如何防止我的用户直接访问仅用于 ajax 调用的页面?
在 ajax 调用期间传递密钥似乎是一种解决方案,而没有密钥的访问将不会被处理。但是制造钥匙也很容易,不是吗?视图源的诅咒...
p/s:使用 Apache 作为 Web 服务器。
编辑:为了回答原因,我的索引.php中有jQuery ui选项卡,在这些选项卡中是带有脚本的表单,如果直接访问它们,则无法正常工作。为什么用户想要这样做,我不知道,我只是认为通过阻止在没有验证脚本的情况下直接访问表单,我会更加用户友好。
答:
无法保证他们通过 AJAX 访问它。直接访问和 AJAX 访问都来自客户端,因此很容易被伪造。
你为什么要这样做?
如果是因为PHP代码不是很安全,那就让PHP代码更安全。(例如,如果 AJAX 将用户 ID 传递给 PHP 文件,请在 PHP 文件中编写代码以确保该用户 ID 是正确的。
评论
听起来你可能做错了事情。AJAX 调用就像标准页面请求一样,只是按照约定,响应不会显示给用户。
但是,它仍然是一个客户端请求,因此您必须很高兴客户端能够看到响应。以这种方式使用“密钥”混淆访问只会使事情复杂化。
实际上,我想说的是,视图源的“诅咒”是通过隐蔽性来对抗安全性的一个小武器。
那么,你为什么要这样做呢?
评论
如果浏览器将通过正常请求或ajax调用您的页面,那么有人可以手动调用它。就服务器-客户端通信而言,普通请求和 ajax 请求之间确实没有明确定义的区别。
常见的情况是将一个标头传递给服务器,上面写着“此请求是由ajax完成的”。如果您使用的是 Prototype,它会自动将 http 标头“X-Requested-With”设置为“XMLHttpRequest”,以及一些其他标头,包括原型版本。(详见 http://www.prototypejs.org/api/ajax/options“requestHeaders”)
添加:如果您使用的是其他 AJAX 库,您可以添加自己的标头。这对于了解服务器端的请求类型以及避免在浏览器中请求 ajax 页面的简单情况非常有用。它不会保护您的请求免受所有人的侵害,因为您不能。
不确定这一点,但可能会检查引荐来源网址标题?我认为如果有人手动输入您的 URL,它就不会有引荐来源标头,而 AJAX 调用有(至少在我刚刚在系统上进行的快速测试中)。
不过,这是一种糟糕的检查方式。由于很多原因,Referrer 可能是空白的。你是想阻止人们把你的网络服务当作公共服务来使用吗?
阅读编辑注释后,如果表单将通过ajax调用加载,则可以检查window.location以查看url是否是ajax表单的url。如果是,请通过 document.location 转到正确的页面
评论
正如其他人所说,Ajax 请求可以通过创建正确的标头来模拟。 如果要进行基本检查以查看请求是否为 Ajax 请求,可以使用:
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
//Request identified as ajax request
}
但是,您绝不应将安全性建立在此检查的基础上。如果您需要,它将消除对页面的直接访问。
评论
这对于保护某些东西绝对没有用。但我认为,如果你想让一个 php 页面生成整个页面,如果该页面不是由 ajax 请求的,而只生成使用 ajax 时返回的您需要的部分,这可能会有用。这将允许你使你的网站对ajax不友好,所以如果说他们点击了一个链接,它应该加载一个评论框,但他们没有ajax,它仍然会将它们发送到页面,然后生成为一个显示评论的整个页面。
COOKIES不安全...试试 _SESSION 美元。这几乎是您实际上可以依赖的少数几件事之一,这些跨页面不能被欺骗。因为,当然,它基本上永远不会离开你的控制。
通过 index.php 传递直接请求,通过 ajax.php 传递 ajax 请求,然后不让用户直接浏览到任何其他源文件 - 确保 index.php 和 ajax.php 具有适当的逻辑来包含它们需要的代码。
谢谢,虽然我用
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
if(IS_AJAX) {
//Request identified as ajax request
}
干杯!
在调用脚本的 javascript 文件中:
var url = "http://website.com/ajax.php?say=hello+world";
xmlHttp.open("GET", url, true);
xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
然后在 PHP 文件 ajax.php 中:
if($_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest") {
header("Location: http://website.com");
die();
}
极客仍然可以通过伪造标头来调用ajax.php脚本,但我的脚本的其余部分需要会话,因此当未检测到有效会话时,执行结束。我需要它才能工作,以便将具有过期 hybridauth 会话的人重定向到主站点以便再次登录,因为他们最终被重定向到 ajax 脚本。
评论