防止直接访问由ajax函数调用的文件

我从这样的ajax调用php代码:

ajaxRequest.open("GET", "func.php" + queryString, true); 

由于这是一个获取请求,任何人都可以通过简单地检查标题来看到它。 被传递的数据不敏感,但可能会被滥用,因为获取参数名称也是微不足道的。

如何防止直接访问http://mysite/func.php,但允许我的ajax页面访问它?

此外,我已经试过这里发布的解决scheme,但它不适合我 – 总是得到“直接访问不预先”的消息。

大多数Ajax请求/框架应该设置这个特定的头,你可以使用它来过滤Ajax和非Ajax请求。 我使用它来帮助确定大量项目中的响应types(json / html):

 if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) ) { // allow access.... } else { // ignore.... } 

编辑:你可以在你自己的Ajax请求中添加你自己的javascript代码中的以下内容:

 var xhrobj = new XMLHttpRequest(); xhrobj.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 

我使用的是:PHP会话+每次发送请求时发送的哈希。 这个散列是使用服务器端的一些algorithm生成的

嗯…你可以在会话开始时生成一次性密码,你可以在_SESSION中存储这个密码,然后给你的ajax调用添加一个参数,这个参数会重新发送(像validation码一样)。 这只对那个会话有效。

这样可以防止自动攻击,但是有权访问您的网站的人员仍然可以手动执行此操作,但这可能是devise更复杂的事情的基础。

我会质疑你为什么如此确信,没有人应该能够直接访问该文件。 你的第一个行动应该是假设人们可以直接访问页面,并围绕这种可能性采取行动。 如果你仍然相信你想closures对这个文件的访问,那么你应该知道你不能相信$_SERVERvariables,因为$_SERVER的起源可能很难确定,并且头文件的值可能被欺骗。 在一些testing中,我发现这些头文件( $_SERVER['HTTP_X_REQUESTED_WITH']$_SERVER['HTTP_X_REQUESTED_WITH'] )也是不可靠的。

谁在这个线程谁build议看标题是错误的某种方式或其他。 请求中的任何内容(HTTP_REFERER,HTTP_X_REQUESTED_WITH)都可能被不完全无能的攻击者欺骗,包括共享的秘密[1]。

您无法阻止人们向您的网站发送HTTP请求。 你想要做的是确保用户在通过会话cookie向网站的某个敏感部分发出请求之前必须进行身份validation。 如果用户做出未经validation的请求,就在那里停下来,给他们一个HTTP 403。

你的例子做了一个GET请求,所以我想你是关心请求的资源需求[2]。 您可以对.htaccess规则中的HTTP_REFERER或HTTP_X_REQUESTED_WITH标头执行一些简单的完整性检查,以阻止新进程被明显假的请求(或者不会听robots.txt的哑search爬行者)产生,但是如果攻击者伪造那些,你会想要确保你的PHP进程尽可能早地退出未经validation的请求。

[1]这是客户端/服务器应用程序的基本问题之一。 这就是为什么它不起作用:假设你有一个方法让你的客户端应用程序向服务器进行身份validation – 无论是秘密密码还是其他方法。 应用程序需要的信息必须可以被应用程序访问(密码隐藏在某处或其他地方)。 但是因为它运行在用户的计算机上,这意味着他们也可以访问这些信息:他们所需要的只是查看应用程序和服务器之间的源代码,二进制代码或networkingstream量,最终他们会发现您的应用authentication的机制,并复制它。 也许他们甚至会复制它。 也许他们会写一个聪明的黑客让你的应用程序做繁重的工作(你总是可以发送假的用户input到应用程序)。 但是不pipe怎么样,他们已经获得了所有必需的信息,而且也没有办法阻止他们阻止你的应用程序的使用。

[2]在一个devise良好的应用程序中的GET请求没有任何副作用,所以没有人使他们能够在服务器上进行更改。 您的POST请求应始终使用会话加上CSRF令牌进行validation,以便只有经过身份validation的用户才能调用它们。 如果有人攻击,这意味着他们有一个帐户,你想closures该帐户。

我解决了这个问题,准备一个检查function,做三件事情

  1. 检查引用$ _SERVER ['HTTP_REFERER'];
  2. 检查http x请求$ _SERVER ['HTTP_X_REQUESTED_WITH'];
  3. 通过桥文件检查来源

如果三者都通过,你成功地看到由ajax调用的php文件,如果只有一个失败,你不明白

点1和2已经解释,桥文件解决scheme如此工作:

桥文件

immagine下面的场景:

A.php页面调用通过ajax B.php,你想防止直接访问B.php

  • 1)当A.php页面被加载时,它会产生一个复杂的随机代码
  • 2)代码复制在一个文件C.txt不能直接从networking访问(httpd的安全)
  • 3)同时,这个代码在A.php页面的呈现html中被清晰地雕刻(例如作为body的一个属性es:

    数据桥=“ehfwiehfe5435ubf37bf3834i”

  • 4)这个雕刻的代码从javascript中回收,并通过ajax post请求发送到B.php

  • 5)B.php页面获取代码并检查它是否存在于C.txt文件中
  • 6)如果代码匹配,代码从C.txtpopup,页面B.php可以访问
  • 7)如果代码没有被发送(如果你试图直接访问B页)或者根本不匹配(如果你提供了一个旧代码或者自定义代码的技巧),B.php页面就会死掉。

通过这种方式,只能通过从父页面A生成的ajax调用来访问B页面。pageB.php的关键字只能从pageA.php

根据你的描述,我假设你试图防止滥用权力,但不需要一个坚如磐石的解决scheme。

从那以后,我会build议使用cookies:

只需在使用AJAX的页面上设置setcookie() ,然后在func.php中检查$_COOKIE是否有正确的值。 这将给你一些合理的保证,任何人调用func.php最近访问您的网站。

如果你想更有趣,你可以设置和validation唯一的会话id(你可能已经这样做),以确保cookie不被伪造或滥用。

这样做没有意义。 它不添加任何实际的安全性。

表示请求正在通过Ajax(如HTTP_X_REQUESTED_WITH )进行的所有标题都可以伪造在客户端。

如果您的Ajax提供敏感数据或允许访问敏感操作,则需要添加适当的安全性,如login系统。

将下面的代码放在由ajax调用的php文件的最顶端。 它会执行一个Ajax请求,但如果直接从浏览器调用,将会“死”。

 define('AJAX_REQUEST', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); if(!AJAX_REQUEST) {die();} 

就个人而言,我select在“死()”之后不输出任何内容,作为额外的安全措施。 这意味着我更喜欢仅仅向“入侵者”显示一个空白页面,而不是给出诸如“如果”或“为什么”这个页面受保护的提示。

我试过这个

1)在主php文件(从其发送ajax请求)创build会话与一些随机值,如$_SESSION['random_value'] = 'code_that_creates_something_random'; 必须确定,该会话是在$.post之上创build的。

2)然后

 $.post( "process_request.php", { input_data:$(':input').serializeArray(), random_value_to_check:'<?php echo htmlspecialchars( $_SESSION['random value'], ENT_QUOTES, "UTF-8"); ?>' }, function(result_of_processing) { //do something with result (if necessary) }); 

3)和process_request.php

 if( isset($_POST['random_value_to_check']) and trim($_POST['random_value_to_check']) == trim($_SESSION['random value']) ){ //do what necessary } 

在我定义会话之前,然后隐藏input字段与会话值,然后隐藏input字段的值与ajax发送。 但后来决定隐藏的input字段没有必要,因为没有它可以发送

我尝试了很多build议,没有人解决这个问题。 最后,我保护了php目标文件的参数,这是限制直接访问php文件的唯一方法。 **在主Html页面中,通过htaccess导致php文件并设置限制导致失败Ajax连接。