CryptoWrapper.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OC\Session;
  8. use OCP\IConfig;
  9. use OCP\IRequest;
  10. use OCP\ISession;
  11. use OCP\Security\ICrypto;
  12. use OCP\Security\ISecureRandom;
  13. /**
  14. * Class CryptoWrapper provides some rough basic level of additional security by
  15. * storing the session data in an encrypted form.
  16. *
  17. * The content of the session is encrypted using another cookie sent by the browser.
  18. * One should note that an adversary with access to the source code or the system
  19. * memory is still able to read the original session ID from the users' request.
  20. * This thus can not be considered a strong security measure one should consider
  21. * it as an additional small security obfuscation layer to comply with compliance
  22. * guidelines.
  23. *
  24. * TODO: Remove this in a future release with an approach such as
  25. * https://github.com/owncloud/core/pull/17866
  26. *
  27. * @package OC\Session
  28. */
  29. class CryptoWrapper {
  30. public const COOKIE_NAME = 'oc_sessionPassphrase';
  31. /** @var IConfig */
  32. protected $config;
  33. /** @var ISession */
  34. protected $session;
  35. /** @var ICrypto */
  36. protected $crypto;
  37. /** @var ISecureRandom */
  38. protected $random;
  39. /** @var string */
  40. protected $passphrase;
  41. /**
  42. * @param IConfig $config
  43. * @param ICrypto $crypto
  44. * @param ISecureRandom $random
  45. * @param IRequest $request
  46. */
  47. public function __construct(IConfig $config,
  48. ICrypto $crypto,
  49. ISecureRandom $random,
  50. IRequest $request) {
  51. $this->crypto = $crypto;
  52. $this->config = $config;
  53. $this->random = $random;
  54. if (!is_null($request->getCookie(self::COOKIE_NAME))) {
  55. $this->passphrase = $request->getCookie(self::COOKIE_NAME);
  56. } else {
  57. $this->passphrase = $this->random->generate(128);
  58. $secureCookie = $request->getServerProtocol() === 'https';
  59. // FIXME: Required for CI
  60. if (!defined('PHPUNIT_RUN')) {
  61. $webRoot = \OC::$WEBROOT;
  62. if ($webRoot === '') {
  63. $webRoot = '/';
  64. }
  65. setcookie(
  66. self::COOKIE_NAME,
  67. $this->passphrase,
  68. [
  69. 'expires' => 0,
  70. 'path' => $webRoot,
  71. 'domain' => '',
  72. 'secure' => $secureCookie,
  73. 'httponly' => true,
  74. 'samesite' => 'Lax',
  75. ]
  76. );
  77. }
  78. }
  79. }
  80. /**
  81. * @param ISession $session
  82. * @return ISession
  83. */
  84. public function wrapSession(ISession $session) {
  85. if (!($session instanceof CryptoSessionData)) {
  86. return new CryptoSessionData($session, $this->crypto, $this->passphrase);
  87. }
  88. return $session;
  89. }
  90. }