From 5fb64ebe047a0b8fca4d0e52287c61c3f33b5f98 Mon Sep 17 00:00:00 2001 From: Richard Bradley Date: Mon, 20 Oct 2025 13:12:36 +0100 Subject: [PATCH] #2422 add support for deep links bypassing password entry --- lib/authentication.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/authentication.js b/lib/authentication.js index 6a40b24a4e..72711eb8cf 100644 --- a/lib/authentication.js +++ b/lib/authentication.js @@ -38,6 +38,31 @@ function authentication () { next() } else if (isAuthenticated(config.getConfig().passwords, req)) { next() + } else if (config.getConfig().passwords.includes(req.query?.password)) { + // If unauthenticated users land on the site with the correct password + // in the query string, then authenticate them and continue. + // + // This may look suspicious to put a password in a URL, but it can be + // useful for user research where users may struggle to enter the password + // but can be given a link with the password in it. + // Or when following a QR code to transition from desktop to mobile, testers + // may want to bypass the password entry page. + // + // It's not ideal to pass the password in the query string, but Chrome has + // stopped passing passwords in the RFC-1738 :@ fields to remote + // servers unless they respond with a WWW-Authenticate header, so this will have to do. + // + // Care should be taken to avoid leaking URLs containing the password where + // web crawlers like Google might find them, because if Google indexes the prototype + // site then it can get flagged as a gov.uk impersonating phishing site and + // globally blocked. + res.cookie('authentication', encryptPassword(req.query.password), { + maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days + sameSite: 'None', // Allows GET and POST requests from other domains + httpOnly: true, + secure: true + }) + res.redirect(req.path) } else { sendUserToPasswordPage(req, res) }