<?php
|
|
/**
|
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
|
*
|
|
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
|
|
* @author Joas Schilling <coding@schilljs.com>
|
|
* @author Lukas Reschke <lukas@statuscode.ch>
|
|
* @author Phil Davis <phil.davis@inf.org>
|
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
|
*
|
|
* @license AGPL-3.0
|
|
*
|
|
* This code is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
*/
|
|
|
|
namespace OC\Session;
|
|
|
|
use OCP\IConfig;
|
|
use OCP\IRequest;
|
|
use OCP\ISession;
|
|
use OCP\Security\ICrypto;
|
|
use OCP\Security\ISecureRandom;
|
|
|
|
/**
|
|
* Class CryptoWrapper provides some rough basic level of additional security by
|
|
* storing the session data in an encrypted form.
|
|
*
|
|
* The content of the session is encrypted using another cookie sent by the browser.
|
|
* One should note that an adversary with access to the source code or the system
|
|
* memory is still able to read the original session ID from the users' request.
|
|
* This thus can not be considered a strong security measure one should consider
|
|
* it as an additional small security obfuscation layer to comply with compliance
|
|
* guidelines.
|
|
*
|
|
* TODO: Remove this in a future release with an approach such as
|
|
* https://github.com/owncloud/core/pull/17866
|
|
*
|
|
* @package OC\Session
|
|
*/
|
|
class CryptoWrapper {
|
|
public const COOKIE_NAME = 'oc_sessionPassphrase';
|
|
|
|
/** @var IConfig */
|
|
protected $config;
|
|
/** @var ISession */
|
|
protected $session;
|
|
/** @var ICrypto */
|
|
protected $crypto;
|
|
/** @var ISecureRandom */
|
|
protected $random;
|
|
/** @var string */
|
|
protected $passphrase;
|
|
|
|
/**
|
|
* @param IConfig $config
|
|
* @param ICrypto $crypto
|
|
* @param ISecureRandom $random
|
|
* @param IRequest $request
|
|
*/
|
|
public function __construct(IConfig $config,
|
|
ICrypto $crypto,
|
|
ISecureRandom $random,
|
|
IRequest $request) {
|
|
$this->crypto = $crypto;
|
|
$this->config = $config;
|
|
$this->random = $random;
|
|
|
|
if (!is_null($request->getCookie(self::COOKIE_NAME))) {
|
|
$this->passphrase = $request->getCookie(self::COOKIE_NAME);
|
|
} else {
|
|
$this->passphrase = $this->random->generate(128);
|
|
$secureCookie = $request->getServerProtocol() === 'https';
|
|
// FIXME: Required for CI
|
|
if (!defined('PHPUNIT_RUN')) {
|
|
$webRoot = \OC::$WEBROOT;
|
|
if ($webRoot === '') {
|
|
$webRoot = '/';
|
|
}
|
|
|
|
if (PHP_VERSION_ID < 70300) {
|
|
setcookie(self::COOKIE_NAME, $this->passphrase, 0, $webRoot, '', $secureCookie, true);
|
|
} else {
|
|
setcookie(
|
|
self::COOKIE_NAME,
|
|
$this->passphrase,
|
|
[
|
|
'expires' => 0,
|
|
'path' => $webRoot,
|
|
'domain' => '',
|
|
'secure' => $secureCookie,
|
|
'httponly' => true,
|
|
'samesite' => 'Lax',
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param ISession $session
|
|
* @return ISession
|
|
*/
|
|
public function wrapSession(ISession $session) {
|
|
if (!($session instanceof CryptoSessionData)) {
|
|
return new CryptoSessionData($session, $this->crypto, $this->passphrase);
|
|
}
|
|
|
|
return $session;
|
|
}
|
|
}
|