Skip to content

Commit b7133e4

Browse files
committed
fix(CORS): CORS should only be bypassed on PublicPage if not logged in to prevent CSRF attack vectors
Signed-off-by: Ferdinand Thiessen <[email protected]>
1 parent 57c974f commit b7133e4

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

lib/private/AppFramework/Middleware/Security/CORSMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function __construct(IRequest $request,
8383
public function beforeController($controller, $methodName) {
8484
// ensure that @CORS annotated API routes are not used in conjunction
8585
// with session authentication since this enables CSRF attack vectors
86-
if ($this->reflector->hasAnnotation('CORS') && !$this->reflector->hasAnnotation('PublicPage')) {
86+
if ($this->reflector->hasAnnotation('CORS') && (!$this->reflector->hasAnnotation('PublicPage') || $this->session->isLoggedIn())) {
8787
$user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null;
8888
$pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null;
8989

tests/lib/AppFramework/Middleware/Security/CORSMiddlewareTest.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,17 @@ public function testCorsIgnoredIfWithCredentialsHeaderPresent() {
126126
* @CORS
127127
* @PublicPage
128128
*/
129-
public function testNoCORSShouldAllowCookieAuth() {
129+
public function testNoCORSOnAnonymousPublicPage() {
130130
$request = new Request(
131131
[],
132132
$this->createMock(IRequestId::class),
133133
$this->createMock(IConfig::class)
134134
);
135135
$this->reflector->reflect($this, __FUNCTION__);
136136
$middleware = new CORSMiddleware($request, $this->reflector, $this->session, $this->throttler);
137+
$this->session->expects($this->once())
138+
->method('isLoggedIn')
139+
->willReturn(false);
137140
$this->session->expects($this->never())
138141
->method('logout');
139142
$this->session->expects($this->never())
@@ -145,6 +148,30 @@ public function testNoCORSShouldAllowCookieAuth() {
145148
$middleware->beforeController($this->controller, __FUNCTION__);
146149
}
147150

151+
/**
152+
* @CORS
153+
* @PublicPage
154+
*/
155+
public function testCORSShouldNeverAllowCookieAuth() {
156+
$request = new Request(
157+
[],
158+
$this->createMock(IRequestId::class),
159+
$this->createMock(IConfig::class)
160+
);
161+
$this->reflector->reflect($this, __FUNCTION__);
162+
$middleware = new CORSMiddleware($request, $this->reflector, $this->session, $this->throttler);
163+
$this->session->expects($this->once())
164+
->method('isLoggedIn')
165+
->willReturn(true);
166+
$this->session->expects($this->once())
167+
->method('logout');
168+
$this->session->expects($this->once())
169+
->method('logClientIn')
170+
->with($this->equalTo('user'), $this->equalTo('pass'))
171+
->willReturn(true);
172+
$middleware->beforeController($this->controller, __FUNCTION__);
173+
}
174+
148175
/**
149176
* @CORS
150177
*/

0 commit comments

Comments
 (0)