Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中检测Ajax并确保请求来自我自己的网站_Php_Ajax_Security - Fatal编程技术网

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

在PHP中检测Ajax并确保请求来自我自己的网站,php,ajax,security,Php,Ajax,Security,我使用我的PHP后端通过检查$\u服务器['HTTP\u X\u REQUESTED\u WITH']中的值来检测AJAX请求 这给了我一个可靠的检测,确保请求是利用AJAX技术发出的 我如何确保请求来自我自己的域,而不是外部域/机器人 www.example.com/ajax?true允许任何人进行ajax调用并剪切信息 我可以为每个正常进入我网站的人创建会话,然后允许AJAX调用。。但这也可能是假的 这些天有什么关系吗?检查$\u服务器['HTTP\u REFERER']。这在许多情况下都可

我使用我的PHP后端通过检查
$\u服务器['HTTP\u X\u REQUESTED\u WITH']
中的值来检测AJAX请求

这给了我一个可靠的检测,确保请求是利用AJAX技术发出的

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

www.example.com/ajax?true允许任何人进行ajax调用并剪切信息

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


这些天有什么关系吗?

检查
$\u服务器['HTTP\u REFERER']
。这在许多情况下都可以使用,但对于一个完全安全的解决方案,不应混淆。

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

在回答“这些天这有关系吗?”——是的,有关系

大卫·沃尔什有一个好主意

让你的控制器

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

  • 将访问令牌声明为JS变量
  • 在每个请求中发送令牌
回到你的控制器里

  • 使用验证HTTP\u X\u请求的\u
  • 验证令牌
检查这些安全性。

另外,请阅读codinghorror.com.Annie linked上的文章。

实际上,最安全的方法是,正如您所建议的,使用服务器端会话,因为这些会话不能像cookies那样精心编制

诚然,有些人仍然可以劫持会话ID,但如果您也在会话中存储用户的IP地址,并在每个请求中检查它,则可以清除许多劫持。只有同一局域网或代理上的人才能劫持它


提到的任何其他方法——cookies、javascript、http referer——都依赖于客户端数据,这些数据不安全,应该始终被怀疑是伪造、伪造、劫持和恶意构造的。

关于最后一个问题:“在这些日子里,这有关系吗?” 这是一个个案问题。如果ajax请求正在做一些不需要安全性的事情(例如加载最新的股票报价),那么这真的不重要。如果请求正在加载应保护的信息(例如,返回标识信息或在服务器上执行操作),则应将其视为安全信息


我个人不使用服务器变量来知道什么时候是ajax请求。相反,我只是在ajax调用中添加一个查询参数(例如)。如果我需要保护ajax调用,那么我将使用与保护常规页面请求相同的方法(同时使用客户端和服务器)。正如卢卡斯·阿曼所指出的,客户方的任何东西都可能是伪造的。底线是不要相信任何请求,即使您认为它来自您的站点或数据库。始终遵循“过滤输入-转义输出”的咒语

使用会话后安全请求:

在网页(例如index.php)内,我们需要存储sessionid

<?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>
责任方:

if( isset( $_GET['sid'] ) ) $client_sid = $_GET['sid'];

if( session_id() == null ) session_start();

if( session_id() != $client_sid ) {
    // noID or wrongID, redirect to mainindex
    ignore_user_abort(true);
    header( "HTTP/1.1 403 Forbidden" );
    header("Connection: close", true);
    exit;
} else {

    // get data
    if( isset( $_GET['data'] ) ) {
        $data = $_GET['data'];
    } else if( isset( $_POST['data'] ) ) {
        $data = $_POST['data'];
    } else {
        $data = null;
    }

    // do stuff with data

    // return data as json
    $resp[0]['data'] = $data; 
    print_r( json_encode( $resp ) );
}

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

这将为您提供所需的内容,但并不可靠,因为浏览器可以在其中放入它喜欢的任何内容。它很容易伪造,因此价值不能被真正信任。从根本上说,您不能保证请求来自任何地方,即使您向页面发出令牌并让ajax请求将令牌传递回您。“真的,你必须问问自己,这有关系吗?”乔纳森·桑普森-我可以在BurpSuite之类的东西中捕捉到请求并更改HTTP\U引用程序……所以我认为这不是解决办法。我也可以在脚本w/curl.+1中完成,因为基于浏览器的AJAX请求会随每个请求发送cookie—您只需在每个页面上添加令牌检查。这不会阻止机器人直接命中API。它可以像您的JavaScript应用程序一样获得访问令牌。这与保护请求无关。任何人都可以向请求添加HTTP头。我不确定此方法除了通过隐蔽性实现安全性之外还能实现什么。编写一个web请求很简单,而Ajax请求就是这样。检查Javascript包装器并添加它将要添加的任何内容稍微不那么琐碎。所有这些都是为了模拟会话令牌。我想如果机器人不使用Javascript,它可能会阻止机器人。但它本身并不能保证请求的安全。这种方法需要访问会话cookie。如果robot可以访问会话cookie,则是,该站点不安全。但你也有比XSRF更大的问题!我读了这篇博客文章,内容非常丰富,因为这个主题对我来说是新的。根据我的检查,CakePHP会自动执行此操作,并且在浏览器重新启动时重置cookie。这应该可以处理注册用户。在公共场所对抗机器人时会发生什么?example.com/blog/title1?ajax=true | example.com/blog/title2?ajax=true关于“现在重要吗”,我想我根本无法阻止机器人在我所有的公共区域轻松爬行。关于公共区域,你可以使用诸如CAPTCHA之类的垃圾邮件预防技术:是的,是的,是的。吉姆说话很有道理。听他的,这是最好的答案。您永远无法确定对站点的请求的来源。即使请求经过身份验证,用户也可能正在使用bot和有效凭据,甚至只是从浏览器中取出cookie。同意,用户可以更改生成会话的方式,使其更安全。出于安全原因,我不会使用会话ID。建议为每个请求生成一个随机令牌,即sa
/* 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' ];
});
if( isset( $_GET['sid'] ) ) $client_sid = $_GET['sid'];

if( session_id() == null ) session_start();

if( session_id() != $client_sid ) {
    // noID or wrongID, redirect to mainindex
    ignore_user_abort(true);
    header( "HTTP/1.1 403 Forbidden" );
    header("Connection: close", true);
    exit;
} else {

    // get data
    if( isset( $_GET['data'] ) ) {
        $data = $_GET['data'];
    } else if( isset( $_POST['data'] ) ) {
        $data = $_POST['data'];
    } else {
        $data = null;
    }

    // do stuff with data

    // return data as json
    $resp[0]['data'] = $data; 
    print_r( json_encode( $resp ) );
}