From 2fc2cd5863c2d9bbe22b289648a94a6c643e180d Mon Sep 17 00:00:00 2001 From: Franz Liedke Date: Thu, 1 Aug 2019 22:53:31 +0200 Subject: [PATCH] Bypass CSRF token check when using access tokens Fixes #1828. --- .../Middleware/AuthenticateWithHeader.php | 2 +- .../csrf_protection/RequireCsrfTokenTest.php | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/framework/core/src/Http/Middleware/AuthenticateWithHeader.php b/framework/core/src/Http/Middleware/AuthenticateWithHeader.php index fa4564a95..1286049af 100644 --- a/framework/core/src/Http/Middleware/AuthenticateWithHeader.php +++ b/framework/core/src/Http/Middleware/AuthenticateWithHeader.php @@ -41,7 +41,6 @@ class AuthenticateWithHeader implements Middleware $request = $request->withAttribute('apiKey', $key); $request = $request->withAttribute('bypassFloodgate', true); - $request = $request->withAttribute('bypassCsrfToken', true); } elseif ($token = AccessToken::find($id)) { $token->touch(); @@ -50,6 +49,7 @@ class AuthenticateWithHeader implements Middleware if (isset($actor)) { $request = $request->withAttribute('actor', $actor); + $request = $request->withAttribute('bypassCsrfToken', true); $request = $request->withoutAttribute('session'); } } diff --git a/framework/core/tests/integration/api/csrf_protection/RequireCsrfTokenTest.php b/framework/core/tests/integration/api/csrf_protection/RequireCsrfTokenTest.php index d52ec519c..148a2774b 100644 --- a/framework/core/tests/integration/api/csrf_protection/RequireCsrfTokenTest.php +++ b/framework/core/tests/integration/api/csrf_protection/RequireCsrfTokenTest.php @@ -190,4 +190,34 @@ class RequireCsrfTokenTest extends TestCase $this->database()->table('settings')->where('key', 'csrf_test')->first()->value ); } + + /** + * @test + */ + public function access_token_does_not_need_csrf_token() + { + $this->database()->table('access_tokens')->insert( + ['token' => 'myaccesstoken', 'user_id' => 1] + ); + + $response = $this->send( + $this->request( + 'POST', '/api/settings', + [ + 'json' => ['csrf_test' => 2], + ] + )->withHeader('Authorization', 'Token myaccesstoken') + ); + + // Successful response? + $this->assertEquals(204, $response->getStatusCode()); + + // Was the setting actually changed in the database? + $this->assertEquals( + 2, + $this->database()->table('settings')->where('key', 'csrf_test')->first()->value + ); + + $this->database()->table('access_tokens')->where('token', 'myaccesstoken')->delete(); + } }