Fix CSRF token generation / validation

Operate on raw bytes instead of base64-encoded strings.
Issue was introduced in a977465

Signed-off-by: Leon Klingele <git@leonklingele.de>
This commit is contained in:
Leon Klingele 2016-10-31 18:22:42 +01:00
parent 42b0a0d2af
commit e5d78a3523
No known key found for this signature in database
GPG Key ID: 83AEC0FEBAA5D483
3 changed files with 15 additions and 7 deletions

View File

@ -51,8 +51,8 @@ class CsrfToken {
*/ */
public function getEncryptedValue() { public function getEncryptedValue() {
if($this->encryptedValue === '') { if($this->encryptedValue === '') {
$sharedSecret = base64_encode(random_bytes(strlen($this->value))); $sharedSecret = random_bytes(strlen($this->value));
$this->encryptedValue = base64_encode($this->value ^ $sharedSecret) . ':' . $sharedSecret; $this->encryptedValue = base64_encode($this->value ^ $sharedSecret) . ':' . base64_encode($sharedSecret);
} }
return $this->encryptedValue; return $this->encryptedValue;
@ -71,6 +71,6 @@ class CsrfToken {
} }
$obfuscatedToken = $token[0]; $obfuscatedToken = $token[0];
$secret = $token[1]; $secret = $token[1];
return base64_decode($obfuscatedToken) ^ $secret; return base64_decode($obfuscatedToken) ^ base64_decode($secret);
} }
} }

View File

@ -137,15 +137,19 @@ class CsrfTokenManagerTest extends \Test\TestCase {
} }
public function testIsTokenValidWithValidToken() { public function testIsTokenValidWithValidToken() {
$a = 'abc';
$b = 'def';
$xorB64 = 'BQcF';
$tokenVal = sprintf('%s:%s', $xorB64, base64_encode($a));
$this->storageInterface $this->storageInterface
->expects($this->once()) ->expects($this->once())
->method('hasToken') ->method('hasToken')
->willReturn(true); ->willReturn(true);
$token = new \OC\Security\CSRF\CsrfToken('XlQhHjgWCgBXAEI0Khl+IQEiCXN2LUcDHAQTQAc1HQs=:qgkUlg8l3m8WnkOG4XM9Az33pAt1vSVMx4hcJFsxdqc='); $token = new \OC\Security\CSRF\CsrfToken($tokenVal);
$this->storageInterface $this->storageInterface
->expects($this->once()) ->expects($this->once())
->method('getToken') ->method('getToken')
->willReturn('/3JKTq2ldmzcDr1f5zDJ7Wt0lEgqqfKF'); ->willReturn($b);
$this->assertSame(true, $this->csrfTokenManager->isTokenValid($token)); $this->assertSame(true, $this->csrfTokenManager->isTokenValid($token));
} }

View File

@ -36,7 +36,11 @@ class CsrfTokenTest extends \Test\TestCase {
} }
public function testGetDecryptedValue() { public function testGetDecryptedValue() {
$csrfToken = new \OC\Security\CSRF\CsrfToken('XlQhHjgWCgBXAEI0Khl+IQEiCXN2LUcDHAQTQAc1HQs=:qgkUlg8l3m8WnkOG4XM9Az33pAt1vSVMx4hcJFsxdqc='); $a = 'abc';
$this->assertSame('/3JKTq2ldmzcDr1f5zDJ7Wt0lEgqqfKF', $csrfToken->getDecryptedValue()); $b = 'def';
$xorB64 = 'BQcF';
$tokenVal = sprintf('%s:%s', $xorB64, base64_encode($a));
$csrfToken = new \OC\Security\CSRF\CsrfToken($tokenVal);
$this->assertSame($b, $csrfToken->getDecryptedValue());
} }
} }