在PHP中检测Ajax并确保请求来自我自己的网站

时间:2009-12-23 16:50:25

标签: php ajax security

我使用我的PHP后端通过检查$_SERVER['HTTP_X_REQUESTED_WITH']中的值来检测AJAX请求。

这为我提供了可靠的检测,确保使用AJAX技术进行请求。

如何确保请求来自我自己的域,而不是外部域/机器人?

www.example.com/ajax?true可以允许任何人拨打AJAX电话并剪切信息。

我可以为每个正常进入我网站的人创建会话,然后允许AJAX调用..但这也可以伪造。

这些日子甚至重要吗?

8 个答案:

答案 0 :(得分:32)

让你控制器

  • 生成访问令牌
  • 存储在会话中供以后比较

在您的视图中

  • 将访问令牌声明为JS变量
  • 发送每个请求的令牌

返回控制器

  • 验证HTTP_X_REQUESTED_WITH
  • 验证令牌

检查这些安全性guidelines from OpenAjax 另外,阅读关于codinghorror.com Annie链接的文章。

答案 1 :(得分:23)

您可以检查HTTP_REFERRER,但并非所有浏览器都设置它。最好的方法是在JavaScript端为你的ajax调用编写一个包装器,它将document.cookie的一部分发送回服务器 - 只有你的域可以访问cookie。您可以将请求标头中的cookie与php中的AJAX调用中的cookie进行比较。

回应,“这些日子是否重要” - 是的,确实如此! Read this

答案 2 :(得分:6)

关于你的上一个问题:“在这些日子里,它是否重要?” 这是一个案例问题。如果ajax请求正在做一些不需要安全性的事情(例如加载最新股票报价),那么恕我直言并不重要。如果请求正在加载应该保护的信息(例如,返回识别信息或在服务器上执行某些操作),那么您应该将其视为此类。

我个人不使用服务器变量来知道什么是ajax请求。相反,我只是向ajax调用添加一个查询参数(例如http://domain.com/?ajax=true)。如果我需要保护ajax调用,那么我将使用相同的方法来保护常规页面请求(使用客户端和服务器)。正如Lucas Oman指出的那样,客户端的任何东西都可以伪造。即使您认为它来自您的站点或数据库,底线也不信任任何请求。始终遵循“过滤器输入 - 逃逸输出”的口头禅。

答案 3 :(得分:3)

David Walsh有一个很好的solution

/* decide what the content should be up here .... */
$content = get_content(); //generic function;

/* AJAX check  */
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    /* special ajax here */
    die($content);
}

/* not ajax, do more.... */

答案 4 :(得分:2)

实际上,最安全的方法是,按照您的建议,使用服务器端会话,因为这些会话无法像Cookie一样制作。

当然,有人仍然可以劫持会话ID,但是如果你还将用户的IP地址存储在他们的会话中并在每次请求中检查它,你就可以淘汰很多劫持。只有同一局域网或代理服务器上的某个人才能劫持它。

提到的任何其他方法 - cookies,javascript,http referer - 取决于客户端数据,这是不安全的,应始终怀疑是假的,伪造的,被劫持的和恶意构造的。

答案 5 :(得分:1)

Use POST session secured requests:

Inside the Webpage (e.g. index.php) we need to store the sessionid

container.RegisterSingleton<MapperConfiguration>(config);
container.Register<IMapper>(() => config.CreateMapper(container.GetInstance));

The ajax requests (ajaxrequest.js)

<?php
// Create Session
$session = session_id();
if(empty($session)) session_start();
?>
<head>
...
<script type="text/javascript">
  sid = '<?php echo session_id(); ?>';
</script>
<script type="text/javascript" src="ajaxrequest.js"></script>
...
</head>

Responsible php side:

/* simple getAjax function 
 * @param $url       request url
 * @param $param     parameter (dont use ?)
 * @param callback  function on success
 */
var spinnerid = '#spinner'; // Spinner as long ajax requests running
$(document).ajaxStart(function() { $(spinnerid).show(); });
$(document).ajaxStop(function() { $(spinnerid).hide(); });
function getAjax( url, param, callback ) {
    var data = null;
    url += "?sid=" + sid + "&" + param;
    $.ajax({
        url: url,
        method: "POST", // uncomment to use GET, POST is secured by session
        cache: false,
        async: true,
        success : function(data){
      callback(data);
    },
}

getAjax( 'http://domain.com/', 'data=foo', function( data ) {
 // do stuf with data 
 var jsonobj = eval("(" + data + ")");
 var data = jsonobj[0][ 'data' ];
});

答案 6 :(得分:0)

检查$_SERVER['HTTP_REFERER']。这在许多情况下都有效,但不应混淆为完全安全的解决方案。

答案 7 :(得分:0)

使用 google recaptcha...它为您的 Ajax 生成一个令牌,然后在服务器端您可以验证该令牌...