8313a3fcb3
While BREACH requires the following three factors to be effectively exploitable we should add another mitigation: 1. Application must support HTTP compression 2. Response most reflect user-controlled input 3. Response should contain sensitive data Especially part 2 is with ownCloud not really given since user-input is usually only echoed if a CSRF token has been passed. To reduce the risk even further it is however sensible to encrypt the CSRF token with a shared secret. Since this will change on every request an attack such as BREACH is not feasible anymore against the CSRF token at least.
96 lines
2.4 KiB
PHP
96 lines
2.4 KiB
PHP
<?php
|
|
/**
|
|
* ownCloud - App Framework
|
|
*
|
|
* This file is licensed under the Affero General Public License version 3 or
|
|
* later. See the COPYING file.
|
|
*
|
|
* @author Thomas Müller <deepdiver@owncloud.com>
|
|
* @copyright Thomas Müller 2014
|
|
*/
|
|
|
|
|
|
namespace OC\AppFramework\Middleware\Security;
|
|
|
|
use OC\AppFramework\Http\Request;
|
|
use OC\AppFramework\Middleware\SessionMiddleware;
|
|
use OC\AppFramework\Utility\ControllerMethodReflector;
|
|
use OCP\AppFramework\Http\Response;
|
|
|
|
|
|
class SessionMiddlewareTest extends \Test\TestCase {
|
|
|
|
/**
|
|
* @var ControllerMethodReflector
|
|
*/
|
|
private $reflector;
|
|
|
|
/**
|
|
* @var Request
|
|
*/
|
|
private $request;
|
|
|
|
protected function setUp() {
|
|
parent::setUp();
|
|
|
|
$this->request = new Request(
|
|
[],
|
|
$this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock(),
|
|
$this->getMock('\OCP\Security\ICrypto'),
|
|
$this->getMock('\OCP\IConfig')
|
|
);
|
|
$this->reflector = new ControllerMethodReflector();
|
|
}
|
|
|
|
/**
|
|
* @UseSession
|
|
*/
|
|
public function testSessionNotClosedOnBeforeController() {
|
|
$session = $this->getSessionMock(0);
|
|
|
|
$this->reflector->reflect($this, __FUNCTION__);
|
|
$middleware = new SessionMiddleware($this->request, $this->reflector, $session);
|
|
$middleware->beforeController($this, __FUNCTION__);
|
|
}
|
|
|
|
/**
|
|
* @UseSession
|
|
*/
|
|
public function testSessionClosedOnAfterController() {
|
|
$session = $this->getSessionMock(1);
|
|
|
|
$this->reflector->reflect($this, __FUNCTION__);
|
|
$middleware = new SessionMiddleware($this->request, $this->reflector, $session);
|
|
$middleware->afterController($this, __FUNCTION__, new Response());
|
|
}
|
|
|
|
public function testSessionClosedOnBeforeController() {
|
|
$session = $this->getSessionMock(1);
|
|
|
|
$this->reflector->reflect($this, __FUNCTION__);
|
|
$middleware = new SessionMiddleware($this->request, $this->reflector, $session);
|
|
$middleware->beforeController($this, __FUNCTION__);
|
|
}
|
|
|
|
public function testSessionNotClosedOnAfterController() {
|
|
$session = $this->getSessionMock(0);
|
|
|
|
$this->reflector->reflect($this, __FUNCTION__);
|
|
$middleware = new SessionMiddleware($this->request, $this->reflector, $session);
|
|
$middleware->afterController($this, __FUNCTION__, new Response());
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
private function getSessionMock($expectedCloseCount) {
|
|
$session = $this->getMockBuilder('\OC\Session\Memory')
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$session->expects($this->exactly($expectedCloseCount))
|
|
->method('close');
|
|
return $session;
|
|
}
|
|
|
|
}
|