{"record":{"id":"59c08a151a82594e","repo":"1Panel-dev/1Panel","slug":"unsupported-saml2-navigation-protocol","errorCode":null,"errorMessage":"Unsupported SAML2 navigation protocol","messagePattern":"Unsupported SAML2 navigation protocol","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/utils/saml2.ts","lineNumber":15,"sourceCode":"export type SAML2Navigation =\n    | {\n          binding: 'redirect';\n          redirectURL: string;\n      }\n    | {\n          binding: 'post';\n          postURL: string;\n          fields: Record<string, string>;\n      };\n\nconst validateNavigationURL = (value: string) => {\n    const url = new URL(value, window.location.origin);\n    if (!['http:', 'https:'].includes(url.protocol)) {\n        throw new Error('Unsupported SAML2 navigation protocol');\n    }\n    return url.toString();\n};\n\nexport const submitSAML2Navigation = (navigation: SAML2Navigation, targetWindow: Window = window) => {\n    if (navigation.binding === 'redirect' && navigation.redirectURL) {\n        targetWindow.location.assign(validateNavigationURL(navigation.redirectURL));\n        return;\n    }\n    if (navigation.binding !== 'post' || !navigation.postURL || !navigation.fields) {\n        throw new Error('Invalid SAML2 navigation response');\n    }\n\n    const form = targetWindow.document.createElement('form');\n    form.method = 'POST';\n    form.action = validateNavigationURL(navigation.postURL);\n    form.style.display = 'none';\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/1Panel-dev/1Panel/blob/5ac7c808815b0691009cd390414f03471312262f/frontend/src/utils/saml2.ts#L1-L33","documentation":"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.","triggerScenarios":"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://'.","commonSituations":"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.","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"],"exampleFix":"// IdP config before: javascript: or mistyped scheme → throws\n// after: proper absolute endpoint\n//   redirectURL: 'https://idp.example.com/saml/sso'","handlingStrategy":"try-catch","validationCode":"const isSafeNavigationUrl = (u: string) => { try { const parsed = new URL(u, window.location.origin); return parsed.protocol === 'http:' || parsed.protocol === 'https:'; } catch { return false; } };","typeGuard":"const isHttpNavigationUrl = (v: string): boolean => { try { return ['http:', 'https:'].includes(new URL(v, window.location.origin).protocol); } catch { return false; } };","tryCatchPattern":"try { submitSAML2Navigation(nav); }\ncatch (e) {\n    // do NOT navigate on failure; log the offending URL and show an auth error\n    logger.warn('rejected SAML2 navigation URL', e);\n    showError('SAML login returned an unsafe redirect target');\n}","preventionTips":["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"],"tags":["saml2","security","xss","url-validation"],"backgroundTag":null,"analyzedSha":"5ac7c808815b0691009cd390414f03471312262f","analyzedAt":"2026-08-15T14:02:06.953Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}