Skip to content

roland/miscbff#297

Merged
RolandGuijt merged 7 commits intomainfrom
roland/miscbff
Feb 11, 2026
Merged

roland/miscbff#297
RolandGuijt merged 7 commits intomainfrom
roland/miscbff

Conversation

@RolandGuijt
Copy link
Contributor

Update Docker sample to .NET 10 and BFF v4

roland and others added 7 commits February 10, 2026 15:36
Improve readability of `ProxyingOpenApiDocument` logic. Update OpenAPI document writing method to handle JSON serialization asynchronously and add inline comments for future compatibility issues with OpenAPI library and .NET 10.
@@ -0,0 +1 @@
window.location.href = document.querySelector("meta[http-equiv=refresh]").getAttribute("data-url");

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 3 days ago

In general, the problem is that an attribute value from the DOM is treated as a fully trusted URL and used to navigate without any validation or encoding. To fix this safely without changing overall behavior, we should: (1) read the data-url attribute into a variable, (2) validate/normalize it using the URL constructor, (3) restrict acceptable schemes (e.g., only http: and https:), and optionally (4) prevent open redirects by allowing only same-origin URLs or a known set of domains. If validation fails, we should avoid navigating.

Specifically for BFF/v4/TokenExchange/TokenExchange.IdentityServer/wwwroot/js/signin-redirect.js, we can replace the one-liner with a small block:

  1. Retrieve the element via document.querySelector("meta[http-equiv=refresh]").
  2. Get the data-url attribute into a local variable.
  3. If no element or attribute is present, do nothing.
  4. Construct a URL object with the value and window.location.origin as base, so we handle relative URLs safely.
  5. Check that the resulting URL’s protocol is http: or https: (and optionally that its origin matches window.location.origin to avoid leaving the site).
  6. Only then assign window.location.href = url.toString();.

No external libraries are needed; URL is a standard web API. Changes are localized to the shown file and only expand the existing logic.

Suggested changeset 1
BFF/v4/TokenExchange/TokenExchange.IdentityServer/wwwroot/js/signin-redirect.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/BFF/v4/TokenExchange/TokenExchange.IdentityServer/wwwroot/js/signin-redirect.js b/BFF/v4/TokenExchange/TokenExchange.IdentityServer/wwwroot/js/signin-redirect.js
--- a/BFF/v4/TokenExchange/TokenExchange.IdentityServer/wwwroot/js/signin-redirect.js
+++ b/BFF/v4/TokenExchange/TokenExchange.IdentityServer/wwwroot/js/signin-redirect.js
@@ -1 +1,24 @@
-window.location.href = document.querySelector("meta[http-equiv=refresh]").getAttribute("data-url");
+(function () {
+    var metaRefresh = document.querySelector("meta[http-equiv=refresh]");
+    if (!metaRefresh) {
+        return;
+    }
+
+    var dataUrl = metaRefresh.getAttribute("data-url");
+    if (!dataUrl) {
+        return;
+    }
+
+    try {
+        // Resolve relative URLs against the current origin
+        var targetUrl = new URL(dataUrl, window.location.origin);
+
+        // Allow only HTTP(S) and same-origin navigation
+        if ((targetUrl.protocol === "http:" || targetUrl.protocol === "https:") &&
+            targetUrl.origin === window.location.origin) {
+            window.location.href = targetUrl.toString();
+        }
+    } catch (e) {
+        // Invalid URL; do not redirect
+    }
+})();
EOF
@@ -1 +1,24 @@
window.location.href = document.querySelector("meta[http-equiv=refresh]").getAttribute("data-url");
(function () {
var metaRefresh = document.querySelector("meta[http-equiv=refresh]");
if (!metaRefresh) {
return;
}

var dataUrl = metaRefresh.getAttribute("data-url");
if (!dataUrl) {
return;
}

try {
// Resolve relative URLs against the current origin
var targetUrl = new URL(dataUrl, window.location.origin);

// Allow only HTTP(S) and same-origin navigation
if ((targetUrl.protocol === "http:" || targetUrl.protocol === "https:") &&
targetUrl.origin === window.location.origin) {
window.location.href = targetUrl.toString();
}
} catch (e) {
// Invalid URL; do not redirect
}
})();
Copilot is powered by AI and may make mistakes. Always verify output.
}

// If the URL is valid (for web), perform the redirect
window.location.href = url;

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 3 days ago

In general, the fix is to stop treating arbitrary DOM-derived text as a fully trusted navigation target and to validate or constrain it before assigning it to window.location.href. Since the current script is for a “signin redirect,” it is typically sufficient (and safer) to only allow redirects within the same origin or to relative URLs generated by the server. This avoids interpreting attacker-controlled, absolute external URLs and keeps the redirect strictly within the application’s control.

The best minimal change, without altering overall behavior more than necessary, is:

  1. Keep the existing scheme validation for defense in depth.
  2. Additionally restrict the redirect so that:
    • Relative URLs (starting with /, ./, or ../) are allowed.
    • Absolute URLs are only allowed if their origin matches window.location.origin.
  3. Use the URL constructor to safely parse absolute URLs, catching any invalid ones, and only then redirect.

This approach continues to support the intended redirect functionality for legitimate values while preventing the use of arbitrary, attacker-controlled URLs as redirect targets. All changes are confined to BFF/v4/docker/ContainerizedIdentityServer/wwwroot/js/signin-redirect.js, around the logic that validates and uses url (currently lines 19–29). No new imports are needed; we rely on standard browser URL and window.location APIs.

Suggested changeset 1
BFF/v4/docker/ContainerizedIdentityServer/wwwroot/js/signin-redirect.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/BFF/v4/docker/ContainerizedIdentityServer/wwwroot/js/signin-redirect.js b/BFF/v4/docker/ContainerizedIdentityServer/wwwroot/js/signin-redirect.js
--- a/BFF/v4/docker/ContainerizedIdentityServer/wwwroot/js/signin-redirect.js
+++ b/BFF/v4/docker/ContainerizedIdentityServer/wwwroot/js/signin-redirect.js
@@ -16,15 +16,27 @@
     return;
   }
 
-  // *** Protocol Validation (https://codeql.github.com/codeql-query-help/javascript/js-xss-through-dom/)  ***
-  // Ensure the URL starts with http: or https: to prevent potential XSS via javascript: URIs
+  // *** URL Validation (https://codeql.github.com/codeql-query-help/javascript/js-xss-through-dom/)  ***
+  // First, ensure that any absolute URL starts with http: or https: to prevent javascript:, data:, etc.
   // Convert to lowercase for case-insensitive comparison.
   var lowerUrl = url.toLowerCase();
-  if (!lowerUrl.startsWith("http:") && !lowerUrl.startsWith("https:")) {
+  if (lowerUrl.indexOf(":") !== -1 && !lowerUrl.startsWith("http:") && !lowerUrl.startsWith("https:")) {
     console.error("Signin redirect URL has an invalid scheme:", url);
     return;
   }
 
-  // If the URL is valid (for web), perform the redirect
-  window.location.href = url;
+  // Next, enforce that the redirect stays on the same origin or uses a relative URL.
+  try {
+    var targetUrl = new URL(url, window.location.href);
+    if (targetUrl.origin !== window.location.origin) {
+      console.error("Signin redirect URL has an invalid origin:", url);
+      return;
+    }
+  } catch (e) {
+    console.error("Signin redirect URL is not a valid URL:", url);
+    return;
+  }
+
+  // If the URL is valid and same-origin, perform the redirect.
+  window.location.href = targetUrl.href;
 })();
EOF
@@ -16,15 +16,27 @@
return;
}

// *** Protocol Validation (https://codeql.github.com/codeql-query-help/javascript/js-xss-through-dom/) ***
// Ensure the URL starts with http: or https: to prevent potential XSS via javascript: URIs
// *** URL Validation (https://codeql.github.com/codeql-query-help/javascript/js-xss-through-dom/) ***
// First, ensure that any absolute URL starts with http: or https: to prevent javascript:, data:, etc.
// Convert to lowercase for case-insensitive comparison.
var lowerUrl = url.toLowerCase();
if (!lowerUrl.startsWith("http:") && !lowerUrl.startsWith("https:")) {
if (lowerUrl.indexOf(":") !== -1 && !lowerUrl.startsWith("http:") && !lowerUrl.startsWith("https:")) {
console.error("Signin redirect URL has an invalid scheme:", url);
return;
}

// If the URL is valid (for web), perform the redirect
window.location.href = url;
// Next, enforce that the redirect stays on the same origin or uses a relative URL.
try {
var targetUrl = new URL(url, window.location.href);
if (targetUrl.origin !== window.location.origin) {
console.error("Signin redirect URL has an invalid origin:", url);
return;
}
} catch (e) {
console.error("Signin redirect URL is not a valid URL:", url);
return;
}

// If the URL is valid and same-origin, perform the redirect.
window.location.href = targetUrl.href;
})();
Copilot is powered by AI and may make mistakes. Always verify output.
@RolandGuijt RolandGuijt merged commit 9ce9dd7 into main Feb 11, 2026
2 of 3 checks passed
@RolandGuijt RolandGuijt deleted the roland/miscbff branch February 11, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants