Here i'm taking advantage of the REST'ful interface of Windows Live. This does make coding pretty cool as you can tap into their JSON strutured ODATA. GET POST PUT and DELETE contents right from the browser with little javascript. Check it out at http://rex.dev.live.com)
Example
Its all about using your own tools for the job ...
$.getJSON('./proxy.php?path=Contacts/AllContacts', function(json){console.log(json)});I'm using JQuery to access proxy.php which relays requests to http://apis.live.net/. My proxy.php script is also deciphering the path (Windows Live RESTful service to reduce the ammount of browser->proxy server requests.
Code
My proxy script is included below. I've written it in a way which passes on errors and does not require any additional libraries ... not even the ominpresent cURL library. It supports all kind of request verbs (i.e. GET,POST,PUT,DELETE). Which may be overwritten via querystring e.g. &method=verb - to be compatible with browsers with limited XHR features.
<?php
/**
* PHP Proxy, resolves XSS security controls.
* Communicate with remote resources.
* @param path (required)
* @param method (optional)
* E.g. "proxy.php?method=GET&path=Contacts/AllContacts"
*
* @author Andrew Dodson
*/
if( isset( $_GET['path'] ) ){
$path = $_GET['path'];
$opts = array(
'http'=> array(
// 'proxy' => 'tcp://127.0.0.1:8888',
'ignore_errors' => true,
'method'=> 'GET',
'header'=>"Content-Type: application/json\r\nAuthorization: WRAP access_token=" . $_COOKIE['accessToken'] . "\r\nAccept: application/json\r\n"
)
);
$a = ( preg_match("#^https?:\/\/#",$path)
? array($path)
: array('http://apis.live.net/v4.0/') + explode('/', '/'.trim($path, '/') ) );
foreach( $a as $path ){
// If this is the last request
if($path===end($a)){
$opts['http']['content'] = file_get_contents("php://input"); // payload
$opts['http']['method'] = (!empty($_GET['method'])?$_GET['method']:$_SERVER['REQUEST_METHOD']); // e.g. GET,POST,PUT
}
// do we need to define the path?
if(!empty($resp)){
$json = (array)json_decode($resp);
$path = $json[$path.'Link'];
if(!preg_match('#^https?:\/\/#', $path))
$path = $json['BaseUri'] . $path;
}
// Make the request
if (!$fp = fopen($path, 'r',false, stream_context_create($opts))) {
break;
}
$resp = stream_get_contents($fp);
}
$meta = stream_get_meta_data($fp);
foreach( $meta['wrapper_data'] as $o) header($o);
print $resp;
}
?>
CSRF - Cross site request forgery
Proxies, by definition, can make a multitude of HTTP requests. This makes them good entry points for malicious scripts running on other websites. Especially if you can defined the verb like the example above can.
The best ways to prevent unscrupulous websites from attacking your users account is to...
Referer header;
Ommitted from the script above - because when accessing the proxy directly, as one would do in development, there are no request headers.
if( parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST ) !== $_SERVER['HTTP_HOST'] ) ){
// CSFR in progress, get me out of here!
}
