Last active
August 29, 2015 14:05
-
-
Save felipecwb/e6abab0b062e631de617 to your computer and use it in GitHub Desktop.
Example about how to protect of CSRF attack.
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
<?php | |
namespace Storage\Provider; | |
interface ProviderInterface | |
{ | |
/** | |
* @param string $identifier | |
* @param mixed $data | |
* @return bool | |
*/ | |
public function persist($identifier, $data); | |
/** | |
* @param string $identifier | |
* @return mixed | |
*/ | |
public function get($identifier); | |
/** | |
* @param string $identifier | |
* @return bool | |
*/ | |
public function delete($identifier); | |
} |
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
<?php | |
$csrf = new Security\TokenManager(new Storage\Provider\AnyType\StorageProvider()); | |
$csrf->generateNewToken(); | |
// Giving token to the client | |
print "Client Token: " . $csrf->getToken() . PHP_EOL; | |
// ...In the next time... | |
// Getting the client's token | |
print "Enter token please: " | |
$tokenClient = trim(fgets(STDIN)); | |
if (! $csrf->verify($tokenClient)) { | |
print "Ops! There's an error with your token!" . PHP_EOL | |
. "Please check it and try again or ask for a new token." . PHP_EOL; | |
exit(1); | |
} | |
// ...do something... |
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
<?php | |
namespace Security; | |
use Storage\Provider\ProviderInterface; | |
class TokenManager | |
{ | |
private $storage; | |
private $expires = 1800; // 30 minutes | |
public function __construct(ProviderInterface $provider) | |
{ | |
$this->storage = $provider; | |
} | |
public function setExpires($seconds) | |
{ | |
$this->expires = (int) $seconds; | |
} | |
protected function tokenizer() | |
{ | |
$alphabet = "abcdefghijklmnopqrstuwxyz0123456789ABCDEFGHIJKLMNOPQRSTUWXYZ!@#$%¨&*{]}^`[)(-+:?/|"; | |
$pass = array(); | |
$alphaLength = strlen($alphabet) - 1; | |
for ($i = 0; $i < 30; $i++) { | |
$n = rand(0, $alphaLength); | |
$pass[] = $alphabet[$n]; | |
} | |
return sha1(implode($pass)); | |
} | |
protected function storageToken($token) | |
{ | |
$this->storage->persist('_token', $token); | |
$this->storage->persist('_token-expires', (time() + $this->expires)); | |
} | |
public function generateNewToken() | |
{ | |
$newToken = $this->tokenizer(); | |
$this->storageToken($token); | |
} | |
/** | |
* @param string $token | |
* @return bool | |
*/ | |
public function verify($token) | |
{ | |
$storagedToken = $this->getToken(); | |
if (! $this->isExpired() | |
&& strlen($token) === strlen($storagedToken) | |
&& $token === $storagedToken | |
) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* @return string | |
*/ | |
public function getToken() | |
{ | |
return $this->storage->get('_token'); | |
} | |
protected function isExpired() | |
{ | |
return $this->storage->get('_token-expires') <= time(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment