title: PHP / ajaxcall - approach to prevent abuse or direct access
body: <p>The problem by calling ajax (in my case through jquery) is that the target can be seen in the source of the side. I searched for a solution to prevent abuse and want to ask you what you think of my humble approach.</p>
  
  <p>to know about ajax calls (correct me if i am wrong):</p>
  
  <ul>
  <li><p>you have to allow direct access to the user because it needs the access like in any regular html rendering.</p></li>
  <li><p>sessions can be used.</p></li>
  <li><p>IP tracking could be used since the user is accessing the file and not my script (this would hold for other securing approaches)</p></li>
  </ul>
  
  <p>out of this i created a script which access the ajaxscript first, gets the time, hashes or encrypts the same time with a good known salt and password and delivers these two values to the user. in the success function i take this 2 values and access the main-script with the next ajaxcall. There i check these values:</p>
  
  <ol>
  <li><p>Are the time and the encrypted time equal</p></li>
  <li><p>Did not more than x seconds run after the two ajax calls</p></li>
  </ol>
  
  <p>I also included a easy to fake $_SERVER['HTTP_X_REQUESTED_WITH' just for additional security, this can easy be spoofed and faken. Instead of delivering the 2 values through GET you could use Session to transport those :). </p>
  
  <p>the index.html</p>
  
  <pre><code>&lt;script&gt;
  $(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] +"&amp;timedone="+ arr[0];
      $("#ajaxcontent").load(geturl);
  
          });
      });
  }); 
  &lt;/script&gt;
  &lt;button id="ajaxloadlink"&gt;Lade ajax.php mit load()&lt;/button&gt;
  </code></pre>
  
  <p>the processfile ajax.php:</p>
  
  <pre><code>&lt;?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'] ) &amp;&amp; ( $_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 &lt;= $curtime &amp;&amp; $timedone &gt;= $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";
      }
  ?&gt;
  </code></pre>
  
  <p>It would be a honor for me to hear what you think of my approach and to correct the code if you think it has to. For me it works, i allowed 2 seconds between the ajax calls (which is easy to render since it are just 2 words). </p>
  
  <p>Generally all accessible content can be accessed by using curl with correct headers by going through index.html like any regular user would. because in most environments (like php) curl can't access ajaxcalls easily since it can't "click" buttons which is needed in this script. Although in other environments like watir, selenium you can easily fake that too.</p>
  
  <p>So is that for you an additional layer of security?
  Thanks for your opinions helping me out. Thanks also for correcting my wrongdoings.</p>
  
  <p>Have a great Day here at SOF 2012!!</p>