PHP - Moved: Csrf With Ajax And Get
This topic has been moved to Ajax Help.
http://www.phpfreaks.com/forums/index.php?topic=323434.0 Similar Tutorialshey guys,
i was introuduced the the world of csrf a little while ago by a member of PHP Freaks, beofore hand i had'nt a clue...so i decided to read a little more into and created a class to deal with generating tokens and ensuring the site is free from CSRF.
now my understanding is that a CSRF can be made from clicking on sponsers, images and basically anything that can cause a request to another site/domain.
now with the script allows the user to have multipule tokens and a new token is generated everytime when filling a form or whatever, allowing user to have more than one tab open. I'm just a little concerned that a CSRF attack can still be made this way as a new token is made on each form page.
when creating a form i do this:
<input name="csrf_token" type="hidden" value="12345" />then on post im able to do something like this: $token = $csrf->get_token(); // token for input if ($csrf->is_safe($post->csrf_token) && form->is_valid()) { echo "safe" } else { echo "unsafe"; }here is my class <?php namespace Security; use Session\Session as Session; use Security\SSL; class CSRF { protected $_expiration = "3600"; public function get_token($expiration = null) { $ssl = new SSL; $token = $ssl->random_string(20); $session = new Session; $session->start(); if ($expiration === null) { $expiration = $this->_expiration; } else if (!is_numeric($expiration)) { // error } if (!$session->offset_exists('csrf_token')) { $session->csrf_token = array(); } $expiration = time() + $expiration; $session->append('csrf_token', array('token' => $token, 'expiration' => $expiration )); return $csrf_token; } protected function token_exists($token) { $session = new Session; $session->start(); $csrf_token = $session->csrf_token; $result = false; foreach ($csrf_token as $key => $array) { if (time() > $array['expiration']) { $session->offset_unset('csrf_token', $key); } else if ($array['expiration'] > time()&& $array['token'] === $token) { $session->offset_unset('csrf_token', $key); $result = true; } } return $result; } public function is_safe($token) { if ($this->token_exists($token)) { return true; } return false; } }any advise would be greatful, thank you Edited by Destramic, 11 January 2015 - 04:27 PM. How much work do you to stop CSRF? Like, I've made sure when changing passwords/e-mails (or anything related to account security) they have to confirm their own password so CSRF can't really do much. I've got a header referral check on everything but this is really easy to spoof so without putting hidden tokens in each form is there any easier way? I can't really be bothered and the worst thing they can do is get a user to post a spam post on my forum or something trivial. How far do you take it? This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=312841.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=325858.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=351379.0 This topic has been moved to Miscellaneous. http://www.phpfreaks.com/forums/index.php?topic=333348.0 I have a question about Cross-Site Request Forgeries (CSRF). Somewhere in the processing of my form, I check: if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token']) { // all other code omitted } else { // no place for bad guys here } So basically, if the token is good then the form continues to check for errors, valid data, etc... I was wondering; is there a point in checking the token again each time I check something else? For example: // above code omitted if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token']) { // all other code omitted // check to see if there were any errors if (count($errors) >= 1) { $valid = false; } else { // all other code omitted if ($sent == $allowed) { if ($addNew == true) {// Should I be checking the token each time, or am I being redundant?? // all other code omitted } } } } else { // no place for bad guys here } As the title says, I would like to know how exactly CSRF can be 100% (or close to it) prevented.
One of the most recommended solutions is to create a token and insert it into a hidden field, but I've tested it on another domain and you can just do a cURL request and retrieve the token then make another request with it included. Proof:
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "URL"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = curl_exec($ch); curl_close($ch); $exploded = explode('type="hidden" name="token" value="', $response); $token = substr($exploded[1], 0, 64); echo $token; // ebd9ab96d40bdb21bbaa2e1a18d657be2e413105ae86ecc14def6137f38a1571 ?>I would hate to include captcha on all my forms, so how exactly does one prevent CSRF? This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=320161.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=348693.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=350592.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=347835.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=308756.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=309753.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=314220.0 This topic has been moved to Miscellaneous. http://www.phpfreaks.com/forums/index.php?topic=314117.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=319274.0 This topic has been moved to Ajax Help. http://www.phpfreaks.com/forums/index.php?topic=332473.0 Hi - My app is built with Codeigniter and so if I turn on CSRF on CI inside the config I get the token being created on my page - good.
But I have 1 page ( "shopping cart") which uses Scriptaculous Ajax.Updater function : http://api.prototype...x/Ajax/Updater/
When I turn on CSRF my shopping cart page refuses to function in terms of updating the cart or deleting any items from the cart. These are both js functions.
I am really stuck - any help would be a God send. Thank You !!
Here is the code:
UpDate JS Function:
function jsUpdateCart(){ var parameter_string = ''; allNodes = document.getElementsByClassName("process"); for(i = 0; i < allNodes.length; i++) { var tempid = allNodes[i].id; var temp = new Array; temp = tempid.split("_"); var real_id = temp[2]; var real_value = allNodes[i].value; parameter_string += real_id +':'+real_value+','; } var params = 'ids='+parameter_string; var ajax = new Ajax.Updater( 'ajax_msg','http://localhost/mysite/index.php/welcome/ajax_cart', {method:'post',parameters:params,onComplete:showMessage} ); } Hi all, I'm writing my own MVC framework purely to improve my oo php skills and I've created a CSRF token validation class to help prevent CSRF attacks. I just need some feedback on it really, is it insecure, is there a better way to validate tokens, etc. Code: [Select] <?php // Security measure. if (!defined('BASE_PATH')) { exit(); } class CSRF { private static $tokens = array(); private static $session_name = 'csrf_data'; /** * Loads CSRF token data from session into $tokens array. * * This is called before the controller is loaded. * * @return void */ public static function init() { $session_name = self::$session_name; // Move CSRF token data from session to class field. if (isset($_SESSION[$session_name])) { self::$tokens = unserialize($_SESSION[$session_name]); unset($_SESSION[$session_name]); } } /** * Saves the CSRF data to a session. * * @static * @return void */ private static function save() { $session_name = self::$session_name; unset($_SESSION[$session_name]); $_SESSION[$session_name] = serialize(self::$tokens); } /** * Creates a new token. * * @static * @param string $name * @return string */ private static function generateToken($name) { $token = md5(uniqid(rand(), true)); self::$tokens[$name] = $token; self::save(); return $token; } /** * Validate a token by its name. * * @static * @param string $name * @param string $token The CSRF token included with the form data. * @return bool */ public static function validateToken($name, $token) { if (!isset(self::$tokens[$name])) { return false; } return ($token == self::$tokens[$name]); } } // End of CSRF class. |