From b7d35e8fd7bab2817b20e55c03200437b32fa935 Mon Sep 17 00:00:00 2001 From: Jonathan Gamble Date: Wed, 10 Apr 2024 13:25:29 -0500 Subject: [PATCH] Revert "readd credentialless headers to HttpFilter" This reverts commit 126c9493669fb46f7b57c5b0c76dac90c303d33f. --- app/http/CtrlExtensions.scala | 10 +++++++--- app/http/HttpFilter.scala | 9 +-------- app/http/ResponseHeaders.scala | 11 ++++------- modules/common/src/main/HTTPRequest.scala | 12 ++++-------- 4 files changed, 16 insertions(+), 26 deletions(-) diff --git a/app/http/CtrlExtensions.scala b/app/http/CtrlExtensions.scala index 43962c7faaffc..c3d668f5282af 100644 --- a/app/http/CtrlExtensions.scala +++ b/app/http/CtrlExtensions.scala @@ -26,10 +26,14 @@ trait CtrlExtensions extends ControllerHelpers: result.withHeaders(LINK -> s"<${env.net.baseUrl}${url}>; rel=\"canonical\"") def withCanonical(url: Call): Result = withCanonical(url.url) def enforceCrossSiteIsolation(using req: RequestHeader): Result = + val coep = + if HTTPRequest.isChrome96Plus(req) || + (HTTPRequest.isFirefox119Plus(req) && !HTTPRequest.isMobileBrowser(req)) + then "credentialless" + else "require-corp" result.withHeaders( - ResponseHeaders.embedderPolicy( - if HTTPRequest.supportsCoepCredentialless(req) then "credentialless" else "require-corp" - )* + "Cross-Origin-Embedder-Policy" -> coep, + "Cross-Origin-Opener-Policy" -> "same-origin" ) def noCache: Result = result.withHeaders( CACHE_CONTROL -> "no-cache, no-store, must-revalidate", diff --git a/app/http/HttpFilter.scala b/app/http/HttpFilter.scala index a60fd33ba25e2..c427c864ee211 100644 --- a/app/http/HttpFilter.scala +++ b/app/http/HttpFilter.scala @@ -21,8 +21,7 @@ final class HttpFilter(env: Env)(using val mat: Materializer)(using Executor) handle(req).map: result => monitoring(req, startTime): addContextualResponseHeaders(req): - addEmbedderPolicyHeaders(req): - result + result } private def monitoring(req: RequestHeader, startTime: Long)(result: Result) = @@ -53,9 +52,3 @@ final class HttpFilter(env: Env)(using val mat: Materializer)(using Executor) if HTTPRequest.isApiOrApp(req) then result.withHeaders(headersForApiOrApp(using req)*) else result.withHeaders(permissionsPolicyHeader) - - private def addEmbedderPolicyHeaders(req: RequestHeader)(result: Result) = - val actionName = HTTPRequest.actionName(req) - if actionName != "Plan.index" && actionName != "Plan.list" && HTTPRequest.supportsCoepCredentialless(req) - then result.withHeaders(embedderPolicy("credentialless")*) - else result diff --git a/app/http/ResponseHeaders.scala b/app/http/ResponseHeaders.scala index d7374634bde7d..d523078c1a799 100644 --- a/app/http/ResponseHeaders.scala +++ b/app/http/ResponseHeaders.scala @@ -39,7 +39,10 @@ trait ResponseHeaders extends HeaderNames: "Cross-Origin-Embedder-Policy" -> "require-corp" // for Stockfish worker ) - def embedderPolicy = ResponseHeaders.embedderPolicy + val credentiallessHeaders = List( + "Cross-Origin-Opener-Policy" -> "same-origin", + "Cross-Origin-Embedder-Policy" -> "credentialless" + ) val permissionsPolicyHeader = "Permissions-Policy" -> List( @@ -56,9 +59,3 @@ trait ResponseHeaders extends HeaderNames: def asAttachmentStream(name: String)(res: Result) = noProxyBuffer(asAttachment(name)(res)) def lastModified(date: Instant) = LAST_MODIFIED -> date.atZone(utcZone) - -object ResponseHeaders: - def embedderPolicy(policy: "credentialless" | "require-corp") = List( - "Cross-Origin-Opener-Policy" -> "same-origin", - "Cross-Origin-Embedder-Policy" -> policy - ) diff --git a/modules/common/src/main/HTTPRequest.scala b/modules/common/src/main/HTTPRequest.scala index 6aa7379932365..0dc2bdee8bded 100644 --- a/modules/common/src/main/HTTPRequest.scala +++ b/modules/common/src/main/HTTPRequest.scala @@ -40,14 +40,10 @@ object HTTPRequest: def userAgent(req: RequestHeader): Option[UserAgent] = UserAgent.from: req.headers.get(HeaderNames.USER_AGENT) - val isChrome96Plus = UaMatcher("""Chrome/(?:\d{3,}|9[6-9])""") - val isChrome113Plus = UaMatcher("""Chrome/(?:11[3-9]|1[2-9]\d)""") - val isFirefox119Plus = UaMatcher("""Firefox/(?:119|1[2-9]\d)""") - val isMobileBrowser = UaMatcher("""(?i)iphone|ipad|ipod|android.+mobile""") - - def supportsCoepCredentialless(req: RequestHeader) = - isChrome96Plus(req) || (isFirefox119Plus(req) && !HTTPRequest.isMobileBrowser(req)) - + val isChrome96Plus = UaMatcher("""Chrome/(?:\d{3,}|9[6-9])""") + val isChrome113Plus = UaMatcher("""Chrome/(?:11[3-9]|1[2-9]\d)""") + val isFirefox119Plus = UaMatcher("""Firefox/(?:119|1[2-9]\d)""") + val isMobileBrowser = UaMatcher("""(?i)iphone|ipad|ipod|android.+mobile""") def isLichessMobile(ua: UserAgent): Boolean = ua.value.startsWith("Lichess Mobile/") def isLichessMobile(req: RequestHeader): Boolean = userAgent(req).exists(isLichessMobile) def isLichobile(req: RequestHeader) = userAgent(req).exists(_.value.contains("Lichobile/"))