Cross-Site Request Forgery (CSRF) is a type of attack that occurs when a malicious Web site, email, blog, instant message, or program causes a user’s Web browser to perform an unwanted action on a trusted site for which the user is currently authenticated.
We have a serious issue here I will like to emphasize the fact that was mentioned in the definition which the user is currently authenticated, Which mean the user is a trusted user. It like having an attack from someone that use your trusted friend as a disguise. The most painful part might not be the attack itself but the fact that it came through someone you've trusted on you site.
We have a serious issue here I will like to emphasize the fact that was mentioned in the definition which the user is currently authenticated, Which mean the user is a trusted user. It like having an attack from someone that use your trusted friend as a disguise. The most painful part might not be the attack itself but the fact that it came through someone you've trusted on you site.
Download Script Live Demo
But the truth is that it not the fault of the user but the fault of the Developer because if there has been a proper protection in place then this would not happen.
The impact of a successful cross-site request forgery attack is limited to the capabilities exposed by the vulnerable application. For example, this attack could result in a transfer of funds, changing a password, or purchasing an item in the user's context. In effect, CSRF attacks are used by an attacker to make a target system perform a function (funds Transfer, form submission etc.) via the target's browser without knowledge of the target user, at least until the unauthorized function has been committed. --https://www.owasp.org/
Developers fix this problem by adding an based key each requests but this can been time consuming and can turn to nightmare for larger applications. I was at phpclasses.org and I came across a great class that do this automatically for you. it has a greater advantage than the manual method because it creates a unique token for each request which make it safer.The class was submitted by a developer named Jstar.
Let take a look at the token class, This is the class responsible for the encryption.
<?php
class TokenManager
{
private $tokenFunction;
private $maxTime;
private $minSecondBeforeNextClick;
public function __construct(callable $tokenFunction = null, $maxTime = 120, $minSecondBeforeNextClick = 1) { $this->
tokenFunction = ($tokenFunction != null) ? $tokenFunction : function () { return "_" . mt_rand(1, 20) . mt_rand(1, 20) . mt_rand(1, 20);
} ;
$this->
maxTime = $maxTime;
$this->
minSecondBeforeNextClick = $minSecondBeforeNextClick;
}
public function applyNewToken() { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
}
$token = call_user_func($this->
tokenFunction);
while (isset($_SESSION[$token])) { $token = call_user_func($this->
tokenFunction);
} $_SESSION[$token] = time() + $this->
maxTime;
$_SESSION['nextClick'] = time() + $this->
minSecondBeforeNextClick;
return $token;
}
public function useToken($token) { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
} if (isset($_SESSION[$token]) && $_SESSION[$token] >
= time()) { unset($_SESSION[$token]);
return true;
} elseif (isset($_SESSION[$token])) { unset($_SESSION[$token]);
} return false;
}
public function isFirstVisit() { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
}
return empty($_SESSION);
}
public function isAcceptedClick() { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
}
return !isset($_SESSION['nextClick']) || $_SESSION['nextClick'] <= time();
} } ?>
Now let see our Index.php to see how we will use the function.
private $tokenFunction;
private $maxTime;
private $minSecondBeforeNextClick;
public function __construct(callable $tokenFunction = null, $maxTime = 120, $minSecondBeforeNextClick = 1) { $this->
tokenFunction = ($tokenFunction != null) ? $tokenFunction : function () { return "_" . mt_rand(1, 20) . mt_rand(1, 20) . mt_rand(1, 20);
} ;
$this->
maxTime = $maxTime;
$this->
minSecondBeforeNextClick = $minSecondBeforeNextClick;
}
public function applyNewToken() { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
}
$token = call_user_func($this->
tokenFunction);
while (isset($_SESSION[$token])) { $token = call_user_func($this->
tokenFunction);
} $_SESSION[$token] = time() + $this->
maxTime;
$_SESSION['nextClick'] = time() + $this->
minSecondBeforeNextClick;
return $token;
}
public function useToken($token) { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
} if (isset($_SESSION[$token]) && $_SESSION[$token] >
= time()) { unset($_SESSION[$token]);
return true;
} elseif (isset($_SESSION[$token])) { unset($_SESSION[$token]);
} return false;
}
public function isFirstVisit() { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
}
return empty($_SESSION);
}
public function isAcceptedClick() { if (session_status() !== PHP_SESSION_ACTIVE) { session_start();
}
return !isset($_SESSION['nextClick']) || $_SESSION['nextClick'] <= time();
} } ?>
<?php
require ("./CSRFProtector.php");
$error = function () { die("Nice try dude");
} ;
$token = function () { return "_" . mt_rand(1, 200) . md5(mt_rand(2, 100));
} ;
$time = 120;
//in seconds $min = 1;
//in seconds $jsPath = "js";
$csrf = new CSRFProtector($jsPath, $error, $token, $time, $min);
$csrf->run();
/**you don't need this line in your real application
* it just to show the token when you perform an action
*/
if(isset($_POST['submit'])){ var_dump($_POST);
}else{ var_dump($_GET);
} ?> <html><body>
CSRF Protection Demo,
<h3>Link Example</h3> <a href="index.php">click me</a>
<h3>POST Form Example</h3> <form method="post" >
<label>Name</label><input type="text" name="name" />
<label>Email</label><input type="text" name="email" />
<input type="submit" name="submit" value="Submit" /> </form> <h3>GET Form Example</h3> <form method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<label>Name</label><input type="text" name="name" />
<label>Email</label><input type="text" name="email" />
<input type="submit" name="submit" value="Submit" /> </form> </body></html>
require ("./CSRFProtector.php");
$error = function () { die("Nice try dude");
} ;
$token = function () { return "_" . mt_rand(1, 200) . md5(mt_rand(2, 100));
} ;
$time = 120;
//in seconds $min = 1;
//in seconds $jsPath = "js";
$csrf = new CSRFProtector($jsPath, $error, $token, $time, $min);
$csrf->run();
/**you don't need this line in your real application
* it just to show the token when you perform an action
*/
if(isset($_POST['submit'])){ var_dump($_POST);
}else{ var_dump($_GET);
} ?> <html><body>
CSRF Protection Demo,
<h3>Link Example</h3> <a href="index.php">click me</a>
<h3>POST Form Example</h3> <form method="post" >
<label>Name</label><input type="text" name="name" />
<label>Email</label><input type="text" name="email" />
<input type="submit" name="submit" value="Submit" /> </form> <h3>GET Form Example</h3> <form method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<label>Name</label><input type="text" name="name" />
<label>Email</label><input type="text" name="email" />
<input type="submit" name="submit" value="Submit" /> </form> </body></html>
Thanks!
Your feedback helps us improve tutorials.
No comments:
Post a Comment