CsrfToken.php 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  6. * SPDX-License-Identifier: AGPL-3.0-only
  7. */
  8. namespace OC\Security\CSRF;
  9. /**
  10. * Class CsrfToken represents the stored or provided CSRF token. To mitigate
  11. * BREACH alike vulnerabilities the token is returned in an encrypted value as
  12. * well in an unencrypted value. For display measures to the user always the
  13. * unencrypted one should be chosen.
  14. *
  15. * @package OC\Security\CSRF
  16. */
  17. class CsrfToken {
  18. private string $encryptedValue = '';
  19. /**
  20. * @param string $value Value of the token. Can be encrypted or not encrypted.
  21. */
  22. public function __construct(
  23. private string $value,
  24. ) {
  25. }
  26. /**
  27. * Encrypted value of the token. This is used to mitigate BREACH alike
  28. * vulnerabilities. For display measures do use this functionality.
  29. */
  30. public function getEncryptedValue(): string {
  31. if ($this->encryptedValue === '') {
  32. $sharedSecret = random_bytes(\strlen($this->value));
  33. $this->encryptedValue = base64_encode($this->value ^ $sharedSecret) . ':' . base64_encode($sharedSecret);
  34. }
  35. return $this->encryptedValue;
  36. }
  37. /**
  38. * The unencrypted value of the token. Used for decrypting an already
  39. * encrypted token.
  40. */
  41. public function getDecryptedValue(): string {
  42. $token = explode(':', $this->value);
  43. if (\count($token) !== 2) {
  44. return '';
  45. }
  46. $obfuscatedToken = $token[0];
  47. $secret = $token[1];
  48. return base64_decode($obfuscatedToken) ^ base64_decode($secret);
  49. }
  50. }