summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2015-08-24 09:14:27 +0200
committerMorris Jobke <hey@morrisjobke.de>2015-08-24 09:14:27 +0200
commit40b1054530229139a5cacf28ed4b883d52835ad6 (patch)
treeae6693babddc83bf4c77ef7890726a6b517ed392 /lib
parent510010e774c4019b7fc616c90085649abb7afac3 (diff)
parentdf2ce8a075d70a2180f2b1c7685b19db6d3ce91b (diff)
downloadnextcloud-server-40b1054530229139a5cacf28ed4b883d52835ad6.tar.gz
nextcloud-server-40b1054530229139a5cacf28ed4b883d52835ad6.zip
Merge pull request #18254 from owncloud/mitigate-breach
Add mitigation against BREACH
Diffstat (limited to 'lib')
-rw-r--r--lib/base.php13
-rw-r--r--lib/private/appframework/http/request.php22
-rw-r--r--lib/private/server.php1
-rw-r--r--lib/private/util.php8
4 files changed, 29 insertions, 15 deletions
diff --git a/lib/base.php b/lib/base.php
index 42e1d7f8586..1f921b13e67 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -134,18 +134,7 @@ class OC {
OC_Config::$object = new \OC\Config(self::$configDir);
OC::$SUBURI = str_replace("\\", "/", substr(realpath($_SERVER["SCRIPT_FILENAME"]), strlen(OC::$SERVERROOT)));
- /**
- * FIXME: The following line is required because of a cyclic dependency
- * on IRequest.
- */
- $params = [
- 'server' => [
- 'SCRIPT_NAME' => $_SERVER['SCRIPT_NAME'],
- 'SCRIPT_FILENAME' => $_SERVER['SCRIPT_FILENAME'],
- ],
- ];
- $fakeRequest = new \OC\AppFramework\Http\Request($params, null, new \OC\AllConfig(new \OC\SystemConfig()));
- $scriptName = $fakeRequest->getScriptName();
+ $scriptName = $_SERVER['SCRIPT_NAME'];
if (substr($scriptName, -1) == '/') {
$scriptName .= 'index.php';
//make sure suburi follows the same rules as scriptName
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
index aaad286e843..a2109439177 100644
--- a/lib/private/appframework/http/request.php
+++ b/lib/private/appframework/http/request.php
@@ -32,6 +32,7 @@ namespace OC\AppFramework\Http;
use OC\Security\TrustedDomainHelper;
use OCP\IConfig;
use OCP\IRequest;
+use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
/**
@@ -67,6 +68,8 @@ class Request implements \ArrayAccess, \Countable, IRequest {
protected $config;
/** @var string */
protected $requestId = '';
+ /** @var ICrypto */
+ protected $crypto;
/**
* @param array $vars An associative array with the following optional values:
@@ -80,17 +83,20 @@ class Request implements \ArrayAccess, \Countable, IRequest {
* - string 'method' the request method (GET, POST etc)
* - string|false 'requesttoken' the requesttoken or false when not available
* @param ISecureRandom $secureRandom
+ * @param ICrypto $crypto
* @param IConfig $config
* @param string $stream
* @see http://www.php.net/manual/en/reserved.variables.php
*/
public function __construct(array $vars=array(),
ISecureRandom $secureRandom = null,
+ ICrypto $crypto,
IConfig $config,
$stream='php://input') {
$this->inputStream = $stream;
$this->items['params'] = array();
$this->secureRandom = $secureRandom;
+ $this->crypto = $crypto;
$this->config = $config;
if(!array_key_exists('method', $vars)) {
@@ -415,8 +421,22 @@ class Request implements \ArrayAccess, \Countable, IRequest {
return false;
}
+ // Decrypt token to prevent BREACH like attacks
+ $token = explode(':', $token);
+ if (count($token) !== 2) {
+ return false;
+ }
+
+ $encryptedToken = $token[0];
+ $secret = $token[1];
+ try {
+ $decryptedToken = $this->crypto->decrypt($encryptedToken, $secret);
+ } catch (\Exception $e) {
+ return false;
+ }
+
// Check if the token is valid
- if(\OCP\Security\StringUtils::equals($token, $this->items['requesttoken'])) {
+ if(\OCP\Security\StringUtils::equals($decryptedToken, $this->items['requesttoken'])) {
return true;
} else {
return false;
diff --git a/lib/private/server.php b/lib/private/server.php
index 89001567219..ff78536cec0 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -410,6 +410,7 @@ class Server extends SimpleContainer implements IServerContainer {
'requesttoken' => $requestToken,
],
$this->getSecureRandom(),
+ $this->getCrypto(),
$this->getConfig(),
$stream
);
diff --git a/lib/private/util.php b/lib/private/util.php
index 501dbf5c4c5..edd375b5c36 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -1057,7 +1057,8 @@ class OC_Util {
/**
* Register an get/post call. Important to prevent CSRF attacks.
*
- * @return string Generated token.
+ * @return string The encrypted CSRF token, the shared secret is appended after the `:`.
+ *
* @description
* Creates a 'request token' (random) and stores it inside the session.
* Ever subsequent (ajax) request must use such a valid token to succeed,
@@ -1074,7 +1075,10 @@ class OC_Util {
// Valid token already exists, send it
$requestToken = \OC::$server->getSession()->get('requesttoken');
}
- return ($requestToken);
+
+ // Encrypt the token to mitigate breach-like attacks
+ $sharedSecret = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(10);
+ return \OC::$server->getCrypto()->encrypt($requestToken, $sharedSecret) . ':' . $sharedSecret;
}
/**