From 30b275b902afbd28d84fce23a564b138c54c548a Mon Sep 17 00:00:00 2001 From: Timothy Allen Date: Sat, 26 Sep 2026 14:20:01 +0200 Subject: [PATCH] Send HSTS on HTTPS pages. --- session.lib.php | 2 ++ tests/php/Pages/FrontPagesTest.php | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/session.lib.php b/session.lib.php index 745e12c..0a0d8f6 100644 --- a/session.lib.php +++ b/session.lib.php @@ -10,6 +10,8 @@ header('X-Frame-Options: DENY'); header("Content-Security-Policy: frame-ancestors 'none'"); if (isset($_SERVER['HTTPS'])) { + // Browsers use HTTPS for this host for a year, without a plain request first + header('Strict-Transport-Security: max-age=31536000'); session_cache_limiter('private'); session_set_cookie_params(array('lifetime' => 0, 'path' => '/', 'domain' => cookie_domain(), 'secure' => TRUE, 'httponly' => TRUE, 'samesite' => 'Lax')); session_start(); diff --git a/tests/php/Pages/FrontPagesTest.php b/tests/php/Pages/FrontPagesTest.php index 796d69f..4078b40 100644 --- a/tests/php/Pages/FrontPagesTest.php +++ b/tests/php/Pages/FrontPagesTest.php @@ -49,6 +49,14 @@ class FrontPagesTest extends PageTestCase { $this->assertSame('DENY', $this->header($this->get('/', array('X-Test-Plain' => '1')), 'X-Frame-Options')); } + // Browsers then use HTTPS for a year, so nobody can catch the first plain request + public function testHttpsPagesSendHsts(): void { + foreach (array('/', '/publish', '/publish/login') as $path) + $this->assertSame('max-age=31536000', $this->header($this->get($path), 'Strict-Transport-Security'), $path); + // Browsers ignore the header over plain HTTP + $this->assertNull($this->header($this->get('/', array('X-Test-Plain' => '1')), 'Strict-Transport-Security')); + } + public function testPlainHttpStartsNoSession(): void { $page = $this->get('/', array('X-Test-Plain' => '1')); $this->assertSame(200, $page['status']);