From 0a8f50fafa18fb879a586e08e9a92e3b9f24631f Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 23 Jul 2025 07:40:45 +0200 Subject: [PATCH] No issue - Adjust CSP URI reporting more closely with the spec. According to the W3C discussion we should allow websocket URIs to be reported aside from http/https/ftp ones. This rewrites things slightly and updates comments to clarify. We do retain the non-standard reduction to origin only in case the report is for cross-origin URIs (stops leaking full URIs to the CSP reported destination). See https://github.com/w3c/webappsec-csp/issues/735 --- dom/security/nsCSPContext.cpp | 56 +++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index 9a6fa568e2..2e31681eec 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -810,33 +810,51 @@ StripURIForReporting(nsIURI* aURI, nsIURI* aSelfURI, nsACString& outStrippedURI) { - // 1) If the origin of uri is a globally unique identifier (for example, - // aURI has a scheme of data, blob, or filesystem), then return the - // ASCII serialization of uri’s scheme. - bool isHttpOrFtp = - (NS_SUCCEEDED(aURI->SchemeIs("http", &isHttpOrFtp)) && isHttpOrFtp) || - (NS_SUCCEEDED(aURI->SchemeIs("https", &isHttpOrFtp)) && isHttpOrFtp) || - (NS_SUCCEEDED(aURI->SchemeIs("ftp", &isHttpOrFtp)) && isHttpOrFtp); + bool isAllowedScheme = + (NS_SUCCEEDED(aURI->SchemeIs("http", &isAllowedScheme)) && isAllowedScheme) || + (NS_SUCCEEDED(aURI->SchemeIs("https", &isAllowedScheme)) && isAllowedScheme) || + (NS_SUCCEEDED(aURI->SchemeIs("ftp", &isAllowedScheme)) && isAllowedScheme) || + (NS_SUCCEEDED(aURI->SchemeIs("ws", &isAllowedScheme)) && isAllowedScheme) || + (NS_SUCCEEDED(aURI->SchemeIs("wss", &isAllowedScheme)) && isAllowedScheme); - if (!isHttpOrFtp) { - // not strictly spec compliant, but what we really care about is - // http/https and also ftp. If it's not http/https or ftp, then treat aURI - // as if it's a globally unique identifier and just return the scheme. + if (!isAllowedScheme) { + // Step 1. If url's scheme is not an allowed scheme, then just return url's scheme, + // i.e. treat aURI as a globally unique identifier. + // What we really care about reporting is http/https/ftp. + // https://github.com/w3c/webappsec-csp/issues/735: We also allow WS(S) schemes. aURI->GetScheme(outStrippedURI); return; } - // 2) If the origin of uri is not the same as the origin of the protected - // resource, then return the ASCII serialization of uri’s origin. - if (!NS_SecurityCompareURIs(aSelfURI, aURI, false)) { - // cross origin redirects also fall into this category, see: - // http://www.w3.org/TR/CSP/#violation-reports - aURI->GetPrePath(outStrippedURI); + // Step 2. Set url's fragment to the empty string. + // Implicit in GetSpecIgnoringRef() below. + + // Step 3. Set url's username/password to the empty string. + nsCOMPtr stripped; + nsresult rv = aURI->Clone(getter_AddRefs(stripped)); + if (NS_FAILED(rv)) { + // Cloning the URI failed for some reason, just return the scheme. + aURI->GetScheme(outStrippedURI); + return; + } + rv = stripped->SetUserPass(EmptyCString()); + if (NS_FAILED(rv)) { + // Mutating the URI failed for some reason, just return the scheme. + aURI->GetScheme(outStrippedURI); return; } - // 3) Return uri, with any fragment component removed. - aURI->GetSpecIgnoringRef(outStrippedURI); + // Non-standard: https://github.com/w3c/webappsec-csp/issues/735 + // We match other browsers here: To avoid leaking the whole URL when blocking + // (or reporting!) cross-origin navigations inside a frame, we restrict the URLs + // to just the (ASCII serialization of) uri's origin. + if (!NS_SecurityCompareURIs(aSelfURI, stripped, false)) { + stripped->GetPrePath(outStrippedURI); + return; + } + + // Step 4. Return uri, with any unwanted component removed. + stripped->GetSpecIgnoringRef(outStrippedURI); } nsresult