Created
October 10, 2012 02:42
-
-
Save cgutierrez/3862844 to your computer and use it in GitHub Desktop.
Lithium Global CSRF Protection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use lithium\action\Dispatcher; | |
use lithium\storage\Session; | |
use lithium\security\validation\RequestToken; | |
use lithium\action\Response; | |
Dispatcher::applyFilter('run', function($self, $params, $chain) { | |
$request = $params['request']; | |
$excludes = array('get', 'head', 'options'); | |
if (!in_array(strtolower($request->method), $excludes)) { | |
$token = $request->env('HTTP_X_CSRF_TOKEN'); | |
if (!empty($request->data['security']) && | |
!empty($request->data['security']['token'])) { | |
$token = $request->data['security']['token']; | |
} | |
if (!RequestToken::check($token)) { | |
// do any sort of logging here | |
return new Response(array( | |
'request' => $request, | |
'location' => Session::read('csrf_redirect') | |
)); | |
} | |
} | |
// generate a new token for all requests besides ajax requests | |
if (!$request->is('ajax')) { | |
RequestToken::get(array('regenerate' => true)); | |
Session::write('csrf_redirect', "/" . ltrim($request->url)); | |
} | |
return $chain->next($self, $params, $chain); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://docs.djangoproject.com/en/dev/ref/contrib/csrf/ | |
(function(window) { | |
function sameOrigin(url) { | |
// url could be relative or scheme relative or absolute | |
var host = document.location.host; // host + port | |
var protocol = document.location.protocol; | |
var sr_origin = '//' + host; | |
var origin = protocol + sr_origin; | |
// Allow absolute or scheme relative URLs to same origin | |
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || | |
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') || | |
// or any other URL that isn't scheme relative or absolute i.e relative. | |
!(/^(\/\/|http:|https:).*/.test(url)); | |
} | |
function safeMethod(method) { | |
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); | |
} | |
$(document).ajaxSend(function(event, xhr, settings) { | |
if (!safeMethod(settings.type) && sameOrigin(settings.url)) { | |
xhr.setRequestHeader("X-CSRF-Token", $('meta[name="security.token"]').attr('content')); | |
} | |
}); | |
})(window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace app\extensions\helper; | |
class Security extends \lithium\template\helper\Security { | |
public function requestToken(array $options = array()) { | |
$defaults = array('name' => 'security.token', 'id' => false, 'meta' => false); | |
$options += $defaults; | |
$requestToken = $this->_classes['requestToken']; | |
$value = $requestToken::key(); | |
$name = $options['name']; | |
$meta = $options['meta']; | |
unset($options['name'], $options['meta']); | |
if ($meta === true) { | |
$attrs = sprintf('name="%s" content="%s"', $name, $value); | |
return $this->_context->html->head('meta', array('options' => $attrs)); | |
} | |
return $this->_context->form->hidden($name, compact('value') + $options); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<?=$this->Security->requestToken(array('meta' => true));?> | |
</head> | |
<body> | |
<form method="post" action="/some/action"> | |
<?=$this->Security->requestToken(); ?> | |
</form> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment