1Panel-dev/1Panel · error · Error
Unsupported SAML2 navigation protocol
Error message
Unsupported SAML2 navigation protocol
What it means
validateNavigationURL in frontend/src/utils/saml2.ts:15 throws when the URL supplied by the SAML2 IdP response (redirectURL or postURL) resolves to a protocol other than http/https. It is a deliberate security guard: SAML responses are attacker-forgeable input, and letting javascript:/data: URLs through location.assign() or a form action would be XSS. Note it uses `new URL(value, window.location.origin)`, so relative IdP URLs resolve against the panel origin and pass.
Source
Thrown at frontend/src/utils/saml2.ts:15
export type SAML2Navigation =
| {
binding: 'redirect';
redirectURL: string;
}
| {
binding: 'post';
postURL: string;
fields: Record<string, string>;
};
const validateNavigationURL = (value: string) => {
const url = new URL(value, window.location.origin);
if (!['http:', 'https:'].includes(url.protocol)) {
throw new Error('Unsupported SAML2 navigation protocol');
}
return url.toString();
};
export const submitSAML2Navigation = (navigation: SAML2Navigation, targetWindow: Window = window) => {
if (navigation.binding === 'redirect' && navigation.redirectURL) {
targetWindow.location.assign(validateNavigationURL(navigation.redirectURL));
return;
}
if (navigation.binding !== 'post' || !navigation.postURL || !navigation.fields) {
throw new Error('Invalid SAML2 navigation response');
}
const form = targetWindow.document.createElement('form');
form.method = 'POST';
form.action = validateNavigationURL(navigation.postURL);
form.style.display = 'none';
View on GitHub (pinned to 5ac7c80881)
Solutions
- Inspect the IdP's SAML response (browser devtools or an SAML tracer extension) and find the actual redirectURL/postURL value
- Fix the IdP-side configuration so SingleSignOnService/AssertionConsumerService URLs are absolute http(s) URLs
- If the URL is relative by design, it resolves against the panel origin and passes — keep it relative rather than adding a bogus scheme
Example fix
// IdP config before: javascript: or mistyped scheme → throws // after: proper absolute endpoint // redirectURL: 'https://idp.example.com/saml/sso'
Defensive patterns
Strategy: try-catch
Validate before calling
const isSafeNavigationUrl = (u: string) => { try { const parsed = new URL(u, window.location.origin); return parsed.protocol === 'http:' || parsed.protocol === 'https:'; } catch { return false; } }; Type guard
const isHttpNavigationUrl = (v: string): boolean => { try { return ['http:', 'https:'].includes(new URL(v, window.location.origin).protocol); } catch { return false; } }; Try / catch
try { submitSAML2Navigation(nav); }
catch (e) {
// do NOT navigate on failure; log the offending URL and show an auth error
logger.warn('rejected SAML2 navigation URL', e);
showError('SAML login returned an unsafe redirect target');
} Prevention
- Never loosen this check — it blocks javascript:/data: XSS via forged SAML responses
- Keep IdP metadata URLs absolute http(s)
- Monitor this error: repeated hits suggest probing or IdP misconfiguration
When it happens
Trigger: An IdP (or crafted response) returns an ACS/redirect endpoint like 'javascript:alert(1)', 'data:text/html,...', or 'ftp://host'; a misconfigured IdP emits a destination containing a typo such as 'httpss://'.
Common situations: Misconfigured SAML2 IdP whose SSO redirect/POST URL has a wrong scheme; penetration tests probing the SAML flow; IdP metadata pasted with a corrupted binding URL.
Related errors
AI-assisted analysis of 1Panel-dev/1Panel@5ac7c80881 (2026-08-15).
Data as JSON: /api/errors/59c08a151a82594e.
Report an issue: GitHub.