Last active
February 12, 2019 03:52
-
-
Save steveclifton/d6568236f4d90ad2f7d7b4b1d9d14684 to your computer and use it in GitHub Desktop.
Simple cross-site request forgery token php class
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
<? | |
class csrf { | |
/** | |
* Generates a new token | |
* @return [string] page name | |
*/ | |
private static function getnewtoken($ps_page) { | |
$lo_token = new stdClass; | |
$lo_token->expiry = time() + 1800; // 30 minutes | |
$lo_token->value = base64_encode(random_bytes(31)); // create random token | |
return $_SESSION['csrftokens'][$ps_page] = $lo_token; | |
} | |
/** | |
* Returns a token for a page | |
* @param [string] page name | |
* @return [string] token | |
*/ | |
private static function gettoken($ps_page) { | |
$lo_token = !empty($_SESSION['csrftokens'][$ps_page]) ? $_SESSION['csrftokens'][$ps_page] : null; | |
// make sure the time is set, and is within the window | |
if (empty($lo_token->expiry) || time() > $lo_token->expiry) { | |
return self::getnewtoken($ps_page); | |
} | |
return $lo_token; | |
} | |
/** | |
* Returns a page's token | |
* @param [string] page name | |
* @return [string] markup to be used in the form | |
*/ | |
public static function getinputtoken($ps_page) { | |
if (empty($ps_page)) { | |
trigger_error('Page alias is missing', E_USER_ERROR); | |
return; | |
} | |
$lo_token = self::gettoken($ps_page); | |
return '<input type="hidden" name="token" value="'. $lo_token->value .'">'; | |
} | |
/** | |
* Verify's a request token against a session token | |
* @param [string] page name | |
* @param [string] token from the request | |
* @return [bool] whether the request submission is valid or not | |
*/ | |
public static function verifytoken($ps_page, $pm_requesttoken) { | |
if (empty($ps_page)) { | |
trigger_error('Page alias is missing', E_USER_WARNING); | |
return false; | |
} | |
$lo_token = self::gettoken($ps_page); | |
// if the time is greater than the 30 minute form submission window | |
if (time() > (int) $lo_token->expiry) { | |
return false; | |
} | |
// check the hash matches | |
if (hash_equals($lo_token->value, $pm_requesttoken)) { | |
unset($_SESSION['csrftokens'][$ps_page]); | |
return true; | |
} | |
return false; | |
} | |
} // csrf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment