Difference between revisions of "HTTP Post request to a PHP server"

From Second Life Wiki
Jump to navigation Jump to search
Line 1: Line 1:
<div class="boilerplate metadata" id="prod" style="margin: 0 5%; padding: 0 7px 7px 7px; background: #EDF1F1; border: 1px solid #999999; text-align: left;">
The accuracy of this article has been called into question. This can be discussed in the [[{{TALKPAGENAME}}|talk page]].


'''Dispute:''' With the capture of a single message an attacker only needs at most {{HoverText|24 hours |less then 24 hours on a 600MHz Pentium 3}} to systematically determine the secret MD5 nonce used to authenticate all messages without requiring any interaction with the source or target of the message. Taking the time period require to break the security into consideration, this article is misnamed.
integer SECRET_NUMBER=123456789;
</div>
xrequest(string url, list l)
{
    integer i;
    integer len=llGetListLength(l) & 0xFFFE; // makes the list count even
    string body;
    for (i=0;i<len;i+=2)
    {
        string varname=llList2String(l,i);
        string varvalue=llList2String(l,i + 1);
        if (i>0) body+="&";
        body+=llEscapeURL(varname)+"="+llEscapeURL(varvalue);
    }
    string hash=llMD5String(body,SECRET_NUMBER);
    http_request_id = llHTTPRequest(url+"?hash="+hash,[HTTP_METHOD,"POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"],body);
}


== Introduction ==
On the server side here is the PHP function which will allow your server to check the securty hash:


LSL now offer the ability to request HTTP page from any website.


 
  <?php
You can use different methods to access your webserver.
  // this function tweak slightly urlencode to make it behave exactly like llEscapeURL in Second Life.
The most obvious is GET, the get method allows any number of parameters.
  function llEscapeURL($s)
 
  {
The syntax is :
  return str_replace(
 
  array("+","-",".","_"),
http://www.yourwebsite.com/pay.php?user=Corto+Maltese&amount=100
  array("%20","%2D","%2E","%5F"),
 
  urlencode($s));
In the example above the page pay.php is requested with 2 parameters param1 and param2.
  } 
The issue with GET is that if someone manage to sniff or guess your webpage, he could potentially take any webbrowser and type :
 
 
  // this my main SL page XML-RPC page
http://www.yourwebsite.com/pay.php?param1=Joe+Blog&amount=1000000
   function checkHash()
 
And your web server will have little idea that this request is bogus.
 
 
This is where my library comes into action.
 
The LSL library takes every character in your HTTP request and compute a security HashCode.
The library will then add this extra security hash parameter to your request like that:
 
http://www.yourwebsite.com/pay.php?user=Corto+Maltese&amount=100&hash=edabcc1792b33e7d6055cc4c8e69912c
 
When the server receive the request, it will be able to check that the hash provided is correct.
If the request was tempered, the hash will not be correct, the server will therefore ignore the request and not allow Job Blog to pretend he has paid L$ 1,000,000.
 
Also the library uses a POST method, the POST method is not very different from GET but allow slightly more input parameters than GET, The POST method is also a bit more secure as the parameters do not appears in the cache statistics or similar tools.
 
== Syntax ==
 
The main LSL function is called xrequest
 
  xrequest(string Url, List Parameters)
 
Url :
  is the address of your webpage. for example "http://www.yoursite.com/sl.php"
 
Parameters :
  is a list of string, the list must be set in pairs using this format:
  [variable_name_1, variable_value_1, variable_name_2, variable_value_2, ...]
 
 
In the example below the script request a page using the parameters a=1, b=2 and c=3.
<code>
   default
   {
   {
      touch_start(integer total_number)
  global $body;
      {
  $hash=$_GET["hash"];
          xrequest("http://www.yoursite.com/sl.php",["a","1","b","2","c","3"]);
  $body="";
      }
  $cpt=0;
     
  $SECRET_NUMBER=123456789;
      http_response(key request_id, integer status, list metadata, string body)
  foreach ($_POST as $name => $value) {
      {
  if ($cpt++>0) $body.="&";
          if (request_id == http_request_id)
  $body.=llEscapeURL($name)."=".llEscapeURL($value);
          {
  }
              llSetText(body, <0,0,1>, 1);
  $calcHash=md5($body.':'.$SECRET_NUMBER);
          }
  if ($hash!=$calcHash)  
      }
  {
     
  sleep(2); // slow down the requests
  echo "result=FAIL\nMSG=Invalid hash"; + $body="";  
  die;
  }
   }
   }
</code>
Here is the code of the xrequest function.
Note that you should change the SECRET_NUMBER to any number of your choice but preferably something rather large and random up to 2,000,000,000.
<code>
  integer SECRET_NUMBER=123456789;
    
    
  xrequest(string url, list l)
  {
      integer i;
      integer len=llGetListLength(l) & 0xFFFE; // makes the list count even
      string body;
    
    
    for (i=0;i<len;i+=2)
   checkHash();
    {
   // You can use the parameters here by simply using $_POST["parameter_name"]  
          string varname=llList2String(l,i);
  echo "OK";
          string varvalue=llList2String(l,i + 1);
  ?>
          if (i>0) body+="&";
          body+=llEscapeURL(varname)+"="+llEscapeURL(varvalue);
      }
      string hash=llMD5String(body,SECRET_NUMBER);
      http_request_id = llHTTPRequest(url+"?hash="+hash,[HTTP_METHOD,"POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"],body);
   }
</code>
 
On the server side here is the PHP function which will allow your server to check the securty hash:
 
<code>
  <?php
  // this function tweak slightly urlencode to make it behave exactly like llEscapeURL in Second Life.
  function llEscapeURL($s)
  {
  return str_replace(
  array("+","-",".","_"),
  array("%20","%2D","%2E","%5F"),
  urlencode($s));
  }    
 
  // this my main SL page XML-RPC page
  function checkHash()
  {
  global $body;
  $hash=$_GET["hash"];
  $body="";
  $cpt=0;
  $SECRET_NUMBER=123456789;
  foreach ($_POST as $name => $value) {
  if ($cpt++>0) $body.="&";
  $body.=llEscapeURL($name)."=".llEscapeURL($value);
  }
  $calcHash=md5($body.':'.$SECRET_NUMBER);
  if ($hash!=$calcHash)
  {
  sleep(2); // slow down the requests
  echo "result=FAIL\nMSG=Invalid hash"; + $body="";
  die;
  }
  }
 
 
  checkHash();
  // You can use the parameters here by simply using $_POST["parameter_name"]  
  echo "OK";
  ?>
</code>
 
This library could be improved, to treat output parameter too.
It doesn't do anything in this area yet.
 
[[Category:LSL Library|Secure HTTP Post]]

Revision as of 15:08, 9 September 2007

integer SECRET_NUMBER=123456789;

xrequest(string url, list l)
{
    integer i;
    integer len=llGetListLength(l) & 0xFFFE; // makes the list count even
    string body;

   for (i=0;i<len;i+=2)
   {
        string varname=llList2String(l,i);
        string varvalue=llList2String(l,i + 1);
        if (i>0) body+="&";
        body+=llEscapeURL(varname)+"="+llEscapeURL(varvalue);
    }
    string hash=llMD5String(body,SECRET_NUMBER);
    http_request_id = llHTTPRequest(url+"?hash="+hash,[HTTP_METHOD,"POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"],body);
}

On the server side here is the PHP function which will allow your server to check the securty hash:


 <?php
 // this function tweak slightly urlencode to make it behave exactly like llEscapeURL in Second Life.
 function llEscapeURL($s)
 {
 	return str_replace(
 		array("+","-",".","_"),
 		array("%20","%2D","%2E","%5F"),
 		urlencode($s));
 }   
 
 // this my main SL page XML-RPC page
 function checkHash()
 {
 	global $body;
 	$hash=$_GET["hash"];
 	$body="";
 	$cpt=0;
 	$SECRET_NUMBER=123456789;
 	foreach ($_POST as $name => $value) {
 		if ($cpt++>0) $body.="&";
 		$body.=llEscapeURL($name)."=".llEscapeURL($value);
 	}
 	$calcHash=md5($body.':'.$SECRET_NUMBER);
 	if ($hash!=$calcHash) 
 	{
 		sleep(2); // slow down the requests
 		echo "result=FAIL\nMSG=Invalid hash"; + $body=""; 
 		die;
 	}
 }
 
 
 checkHash();
 // You can use the parameters here by simply using $_POST["parameter_name"] 
 echo "OK";
 ?>