89 lines
2.3 KiB
PHP
89 lines
2.3 KiB
PHP
<?php
|
|
/** \file include/security.php
|
|
* \brief DI webinterface framework utilities
|
|
* \author Jack Weeland, Core|Vision
|
|
* \version $Revision: 26247 $
|
|
* \date $Date: 2016-02-29 10:40:22 +0100 (Mon, 29 Feb 2016) $
|
|
*
|
|
* Security functions
|
|
*/
|
|
|
|
/**
|
|
* CSRF (cross-site request forgery) protection
|
|
*/
|
|
|
|
/**
|
|
* Create a CSRF token and store it in the session
|
|
*
|
|
* Inputs:
|
|
* - purpose as defined in 'csrf_check_token()'
|
|
*
|
|
* Returns a CSRF token
|
|
*/
|
|
function csrf_create_token($purpose)
|
|
{
|
|
global $_PAGE_INFO;
|
|
|
|
if( !$_SESSION[$_PAGE_INFO['id']]['csrf_token_' . $purpose] ) {
|
|
$sem = db_sema_acquire("secure-" . $_PAGE_INFO['id']);
|
|
// create token, based on client address and time
|
|
$now = gettimeofday();
|
|
$csrf_token = sha1($_SERVER['REMOTE_ADDR'] . $_SERVER['REMOTE_PORT'] . $now['sec'] . $now['usec']);
|
|
// store the CSRF token in the session
|
|
$_SESSION[$_PAGE_INFO['id']]['csrf_token_' . $purpose] = $csrf_token;
|
|
db_sema_release($sem);
|
|
}
|
|
// else: already set
|
|
|
|
return $_SESSION[$_PAGE_INFO['id']]['csrf_token_' . $purpose];
|
|
}
|
|
|
|
/**
|
|
* Check the CSRF token
|
|
*
|
|
* NB: there are multiple tokens because the different purposes can run
|
|
* in parallel
|
|
*
|
|
* Returns TRUE on success or FALSE on failure
|
|
*/
|
|
function csrf_check_token()
|
|
{
|
|
global $_PAGE_INFO;
|
|
|
|
if( !$_POST['__csrf_token__'] ) {
|
|
error_log("CSRF token not set");
|
|
unset($_POST);
|
|
return FALSE;
|
|
}
|
|
|
|
$check_ok = FALSE;
|
|
$sem = db_sema_acquire("secure-" . $_PAGE_INFO['id']);
|
|
foreach( array('form','status_handler','status_check','js','ibox') as $purpose ) {
|
|
if( $_POST['__csrf_token__'] == $_SESSION[$_PAGE_INFO['id']]['csrf_token_' . $purpose] ) {
|
|
// okay; clear the token so a forger cannot repeat it
|
|
// the token for the status handler is sticky
|
|
if( $purpose != 'status_handler' ) {
|
|
unset($_SESSION[$_PAGE_INFO['id']]['csrf_token_' . $purpose]);
|
|
}
|
|
$check_ok = TRUE;
|
|
}
|
|
}
|
|
db_sema_release($sem);
|
|
|
|
return $check_ok;
|
|
}
|
|
|
|
/**
|
|
* Clear a CSRF token
|
|
*
|
|
* Inputs:
|
|
* - purpose as defined in 'csrf_check_token()'
|
|
*/
|
|
function csrf_clear_token($purpose)
|
|
{
|
|
$sem = db_sema_acquire("secure-" . $_PAGE_INFO['id']);
|
|
unset($_SESSION[$_PAGE_INFO['id']]['csrf_token_' . $purpose]);
|
|
db_sema_release($sem);
|
|
}
|
|
|
|
?>
|