Backport CSRF prevention.
This commit is contained in:
parent
3e339f3d66
commit
625cd822c3
|
@ -24,6 +24,16 @@
|
|||
echo '/>';
|
||||
?>
|
||||
<?php endforeach; ?>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var requesttoken = '<?php echo $_['requesttoken']; ?>';
|
||||
$(document).bind('ajaxSend', function(elm, xhr, s){
|
||||
if(requesttoken) {
|
||||
xhr.setRequestHeader('requesttoken', requesttoken);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body id="<?php echo $_['bodyid'];?>">
|
||||
|
|
12
lib/json.php
12
lib/json.php
|
@ -41,6 +41,18 @@ class OC_JSON{
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check an ajax get/post call if the request token is valid.
|
||||
* @return json Error msg if not valid.
|
||||
*/
|
||||
public static function callCheck(){
|
||||
if( !OC_Util::isCallRegistered()){
|
||||
$l = OC_L10N::get('core');
|
||||
self::error(array( 'data' => array( 'message' => $l->t('Token expired. Please reload page.') )));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user is a admin, send json error msg if not
|
||||
*/
|
||||
|
|
|
@ -53,6 +53,13 @@ class JSON {
|
|||
return(\OC_JSON::checkLoggedIn());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check an ajax get/post call if the request token is valid.
|
||||
* @return json Error msg if not valid.
|
||||
*/
|
||||
public static function callCheck(){
|
||||
return(\OC_JSON::callCheck());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send json success msg
|
||||
|
|
|
@ -249,6 +249,22 @@ class Util {
|
|||
return(\OC_Hook::emit( $signalclass, $signalname, $params ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an get/post call. This is important to prevent CSRF attacks
|
||||
* TODO: write example
|
||||
*/
|
||||
public static function callRegister(){
|
||||
return(\OC_Util::callRegister());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check an ajax get/post call if the request token is valid. exit if not.
|
||||
* Todo: Write howto
|
||||
*/
|
||||
public static function callCheck(){
|
||||
return(\OC_Util::callCheck());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -155,11 +155,13 @@ class OC_Template{
|
|||
$this->renderas = $renderas;
|
||||
$this->application = $app;
|
||||
$this->vars = array();
|
||||
if($renderas == 'user') {
|
||||
$this->vars['requesttoken'] = OC_Util::callRegister();
|
||||
}
|
||||
$this->l10n = OC_L10N::get($app);
|
||||
header('X-Frame-Options: Sameorigin');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
header('X-Frame-Options: Sameorigin');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
$this->findTemplate($name);
|
||||
}
|
||||
|
||||
|
@ -355,6 +357,7 @@ class OC_Template{
|
|||
if( $this->renderas == "user" ){
|
||||
$page = new OC_Template( "core", "layout.user" );
|
||||
$page->assign('searchurl',OC_Helper::linkTo( 'search', 'index.php' ));
|
||||
$page->assign('requesttoken', $this->vars['requesttoken']);
|
||||
if(array_search(OC_APP::getCurrentApp(),array('settings','admin','help'))!==false){
|
||||
$page->assign('bodyid','body-settings');
|
||||
}else{
|
||||
|
|
73
lib/util.php
73
lib/util.php
|
@ -331,4 +331,77 @@ class OC_Util {
|
|||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register an get/post call. This is important to prevent CSRF attacks
|
||||
* Todo: Write howto
|
||||
* @return $token Generated token.
|
||||
*/
|
||||
public static function callRegister(){
|
||||
//mamimum time before token exires
|
||||
$maxtime=(60*60); // 1 hour
|
||||
|
||||
// generate a random token.
|
||||
$token=mt_rand(1000,9000).mt_rand(1000,9000).mt_rand(1000,9000);
|
||||
|
||||
// store the token together with a timestamp in the session.
|
||||
$_SESSION['requesttoken-'.$token]=time();
|
||||
|
||||
// cleanup old tokens garbage collector
|
||||
// only run every 20th time so we don´t waste cpu cycles
|
||||
if(rand(0,20)==0) {
|
||||
foreach($_SESSION as $key=>$value) {
|
||||
// search all tokens in the session
|
||||
if(substr($key,0,12)=='requesttoken') {
|
||||
if($value+$maxtime<time()){
|
||||
// remove outdated tokens
|
||||
unset($_SESSION[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// return the token
|
||||
return($token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check an ajax get/post call if the request token is valid.
|
||||
* @return boolean False if request token is not set or is invalid.
|
||||
*/
|
||||
public static function isCallRegistered(){
|
||||
//mamimum time before token exires
|
||||
$maxtime=(60*60); // 1 hour
|
||||
if(isset($_GET['requesttoken'])) {
|
||||
$token=$_GET['requesttoken'];
|
||||
}elseif(isset($_POST['requesttoken'])){
|
||||
$token=$_POST['requesttoken'];
|
||||
}elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])){
|
||||
$token=$_SERVER['HTTP_REQUESTTOKEN'];
|
||||
}else{
|
||||
//no token found.
|
||||
return false;
|
||||
}
|
||||
if(isset($_SESSION['requesttoken-'.$token])) {
|
||||
$timestamp=$_SESSION['requesttoken-'.$token];
|
||||
if($timestamp+$maxtime<time()){
|
||||
return false;
|
||||
}else{
|
||||
//token valid
|
||||
return true;
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check an ajax get/post call if the request token is valid. exit if not.
|
||||
* Todo: Write howto
|
||||
*/
|
||||
public static function callCheck(){
|
||||
if(!OC_Util::isCallRegistered()) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue