PHP/ajaxcall-防止滥用或直接访问的方法

PHP/ajaxcall-防止滥用或直接访问的方法,php,jquery,ajax,security,Php,Jquery,Ajax,Security,在我的例子中,通过jquery调用ajax的问题是,可以在端的源代码中看到目标。我在寻找防止虐待的解决办法,想问你对我谦逊的态度有何看法 要了解ajax调用,请纠正我的错误: 您必须允许直接访问用户,因为它需要与任何常规html呈现一样的访问权限 可以使用会话 可以使用IP跟踪,因为用户正在访问文件,而不是我的脚本。这对于其他安全方法来说是有效的 基于此,我创建了一个脚本,它首先访问ajaxscript,获取时间,同时使用已知的salt和密码进行哈希或加密,并将这两个值传递给用户。在succes

在我的例子中,通过jquery调用ajax的问题是,可以在端的源代码中看到目标。我在寻找防止虐待的解决办法,想问你对我谦逊的态度有何看法

要了解ajax调用,请纠正我的错误:

您必须允许直接访问用户,因为它需要与任何常规html呈现一样的访问权限

可以使用会话

可以使用IP跟踪,因为用户正在访问文件,而不是我的脚本。这对于其他安全方法来说是有效的

基于此,我创建了一个脚本,它首先访问ajaxscript,获取时间,同时使用已知的salt和密码进行哈希或加密,并将这两个值传递给用户。在success函数中,我获取这2个值,并通过下一个ajaxcall访问主脚本。在这里,我检查这些值:

时间和加密时间相等吗

在两次ajax调用后运行的时间不超过x秒

我还包括了一个易于伪造的$服务器['HTTP_X_REQUESTED_WITH',只是为了增加安全性,这很容易被欺骗和伪造。您可以使用会话来传输这些值,而不是通过GET传递这两个值:

index.html

<script>
$(document).ready(function() {  
$("#ajaxloadlink").click(function(){
$("#ajaxcontent").load("ajax.php",function(responseText, textStatus, XMLHttpRequest){
    // alert(responseText);
    var pruf = responseText; // $("#ajaxcontent").html();
    var arr = pruf.split('|');
    var geturl = "ajax.php?verifyvar="+ arr[1] +"&timedone="+ arr[0];
    $("#ajaxcontent").load(geturl);

        });
    });
}); 
</script>
<button id="ajaxloadlink">Lade ajax.php mit load()</button>
进程文件ajax.php:

<?php
// the function to use for encryption
define('SALT', 'whateveryouwant'); 
function encrypt($text) 
    { 
        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SALT, $text, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND)))); 
    } 

function decrypt($text) 
    { 
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SALT, base64_decode($text), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))); 
    } 


if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
    //only internal scripts can be used, fakeable

        if(empty($_GET))
        {
            $time = time();
            $verifvar_created = encrypt($time); 
            echo $time."|".$verifvar_created;
        }
        else
        {
        //zweiter Durchlauf
        $verifvar = $_GET['verifyvar'];
        $timedone = $_GET['timedone'];

            //VERIFY
            $curtime = time(); //holds also timemax
            $timemin = $curtime - 2;

            if($timedone <= $curtime && $timedone >= $timemin)
            {
                echo "COOOL";
                //now its an actual request
                $verifvar_checked = decrypt($timedone); 
                if ($verifvar == $verifvar_checked)
                {
                    echo "VERIFIED";
                    // now process the actual script
                    // :)
                }
            }
        }
} else 
    {
        echo "no direct access allowed";
    }
?>
我很荣幸能听到您对我的方法的看法,如果您认为有必要的话,我也会修改代码。对我来说,它是有效的,我在ajax调用之间留出了2秒的时间,这很容易呈现,因为它只有2个字

一般来说,所有可访问的内容都可以通过使用带有正确标题的curl通过index.html访问,就像任何普通用户一样。因为在大多数环境(如php)中,curl无法轻松访问ajaxcalls,因为它无法单击此脚本中需要的按钮。尽管在其他环境(如watir)中,selenium很容易伪造那也是

那么这对你来说是一个额外的安全层吗? 谢谢你的意见帮助我,也谢谢你纠正我的错误


祝您在SOF 2012上度过愉快的一天!!

Ajax调用在技术上与普通的POST/GET请求没有区别,而且目标始终是用户/浏览器可以看到,您无法通过模糊方法通过安全性来确保应用程序的安全

如果您的目标是限制请求速率,那么您应该在web服务器或防火墙级别上这样做。如果您想使用php,您可以使用会话来识别用户并限制他们的请求速率

<?php
  session_start();

  if( !isset($_SESSION['time'])
   || $_SESSION['time'] < ( time() - 60 * 5 ) 
  ){
     $_SESSION['time' ] = time();
     $_SESSION['count'] = 0 ;
   }
     $_SESSION['count']++ ;

   if(  $_SESSION['count'] > 10 ){
     die("Stop ! You can't make more than 10 requests in 5 Minutes");
   }

因为会话使用cookies,所以保护应用程序不受http洪水的影响是没有用的。

为了使事情更加混乱,您可以让它有两个甚至更多不同的服务器脚本,每个脚本只返回响应的一部分,由一个共享密钥加密,该密钥只能从索引页获得。因此javascript代码必须这样做两个不同的ajax调用,然后将响应放在一起,在客户端对其进行解密,只有这样它才可用


但这并不能帮助您抵御Selenium,因为它可以做用户通常会做的任何事情。

这可能在codereview上更好,但在我看来,您的代码已经有一个小问题,您无法判断用户的连接速度有多快,您可能会在1秒内加载什么,另一个用户将在5秒内加载。因此,也许您应该提高限制。除此之外,你想防止什么样的滥用?我不明白你为什么试图在客户端隐藏URL。我也不明白你在《curl不能轻松访问ajaxcalls》上的意思是什么?你能解释一下所有这些代码的目的吗?@egor我不想在客户端隐藏URL,这是做不到的。curl可以抓住ajax目标-脚本并直接访问该脚本。php环境中的curl不能访问index.html并从那里转到ajax目标脚本。我的脚本需要通过index.html调用以首先获得所需的2个值。不能访问index.html并从那里转到ajax目标脚本不,它可以:@truth我测试了脚本wi我的客户、游戏玩家和3600个用户中没有一个产生错误,我记录他们。这是一个反复试验的问题。正如我在帖子中所描述的,它只需要呈现两个单词,而不是整个html站点,所以访问速度相当快。不过,为了安全起见,我建议根据你们的国家和互联网速度,我住在瑞士,那里的互联网非常发达快速增加值。在countrary,机器人有更多的自由度。我需要它来查询需要额外安全层的游戏的其他表单字段。@您好,谢谢您的回答。我知道它不能完全安全。浏览器中用JavaScript处理的任何数据/计算都是不安全的,因为所有代码都在本地计算机上运行。我建议使用session来传输值,而不是GET。我的脚本只会使不通过index.html直接访问ajax.php变得不可能。这是因为time获得了其加密的Contrepart
我可以看到您的应用程序提出的请求。由于我有你的应用程序的js代码,我可以编写一个小php/python脚本,通过访问index.html只需一次就可以发出数千个请求。使用apache/nginx或iptables限制请求速率非常容易,这应该是一种方法。不可能防止像用户一样的机器人滥用。我用python编写了一个脚本,可以在任何可访问的网站上完成。我不明白你怎么能只通过一个站点渲染就请求index.html 1000x。这是不可能的。。因为新属性只能在新请求时呈现;实际上,这可能取决于您的应用程序和用户模式。如果一个Avarge用户对一个脚本只做了50req/m,然后有人做了2000req,那么您可以确定有什么问题。你可以提出任何你想要的要求。如果我使用iptables限制服务器上的请求,并且每个主机只允许100个请求/分钟,那么您的第101个请求将被丢弃,因为我丢弃的是tcp数据包,所以根本不会有http请求。如果您使用chrome开发工具观看流量,您可以看到请求和响应的标题。模仿它并不难。另外,请检查: