From 41ac69adb1a4c50dc3a9341a4391969befba3e9e Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 8 Oct 2021 15:22:09 +0100 Subject: [PATCH] Forced response cache revalidation on logged-in responses - Prevents authenticated responses being visible when back button pressed in browser. - Previously, 'no-cache, private' was added by default by Symfony which would have prevents proxy cache issues but this adds no-store and a max-age option to also invalidate all caching. Thanks to @haxatron via huntr.dev Ref: https://huntr.dev/bounties/6cda9df9-4987-4e1c-b48f-855b6901ef53/ --- app/Http/Kernel.php | 3 ++ .../PreventAuthenticatedResponseCaching.php | 30 +++++++++++++++++++ tests/SecurityHeaderTest.php | 9 ++++++ 3 files changed, 42 insertions(+) create mode 100644 app/Http/Middleware/PreventAuthenticatedResponseCaching.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a98528d0f..8c71e2194 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,6 +2,7 @@ namespace BookStack\Http; +use BookStack\Http\Middleware\PreventAuthenticatedResponseCaching; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel @@ -30,6 +31,7 @@ class Kernel extends HttpKernel \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \BookStack\Http\Middleware\VerifyCsrfToken::class, + \BookStack\Http\Middleware\PreventAuthenticatedResponseCaching::class, \BookStack\Http\Middleware\CheckEmailConfirmed::class, \BookStack\Http\Middleware\RunThemeActions::class, \BookStack\Http\Middleware\Localization::class, @@ -39,6 +41,7 @@ class Kernel extends HttpKernel \BookStack\Http\Middleware\EncryptCookies::class, \BookStack\Http\Middleware\StartSessionIfCookieExists::class, \BookStack\Http\Middleware\ApiAuthenticate::class, + \BookStack\Http\Middleware\PreventAuthenticatedResponseCaching::class, \BookStack\Http\Middleware\CheckEmailConfirmed::class, ], ]; diff --git a/app/Http/Middleware/PreventAuthenticatedResponseCaching.php b/app/Http/Middleware/PreventAuthenticatedResponseCaching.php new file mode 100644 index 000000000..3ad5b3914 --- /dev/null +++ b/app/Http/Middleware/PreventAuthenticatedResponseCaching.php @@ -0,0 +1,30 @@ +headers->set('Cache-Control', 'max-age=0, no-store, private'); + $response->headers->set('Pragma', 'no-cache'); + $response->headers->set('Expires', 'Sun, 12 Jul 2015 19:01:00 GMT'); + } + + return $response; + } +} diff --git a/tests/SecurityHeaderTest.php b/tests/SecurityHeaderTest.php index 2bde890ad..10551fc55 100644 --- a/tests/SecurityHeaderTest.php +++ b/tests/SecurityHeaderTest.php @@ -119,6 +119,15 @@ class SecurityHeaderTest extends TestCase $this->assertEquals('base-uri \'self\'', $scriptHeader); } + public function test_cache_control_headers_are_strict_on_responses_when_logged_in() + { + $this->asEditor(); + $resp = $this->get('/'); + $resp->assertHeader('Cache-Control', 'max-age=0, no-store, private'); + $resp->assertHeader('Pragma', 'no-cache'); + $resp->assertHeader('Expires', 'Sun, 12 Jul 2015 19:01:00 GMT'); + } + /** * Get the value of the first CSP header of the given type. */