{"record":{"id":"6bcade90ede95d18","repo":"spring-projects/spring-security","slug":"failed-to-decode-samlresponse","errorCode":null,"errorMessage":"Failed to decode SAMLResponse","messagePattern":"Failed to decode SAMLResponse","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/Saml2Utils.java","lineNumber":189,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// in cases of an incomplete final chunk, ensure the unused bits are zero\n\t\t\t\tswitch (goodChars % 4) {\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\treturn true;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\treturn (lastGoodCharVal & 0b1111) == 0;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\treturn (lastGoodCharVal & 0b11) == 0;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvoid checkAcceptable(String ins) {\n\t\t\t\tif (!isAcceptable(ins)) {\n\t\t\t\t\tthrow new IllegalArgumentException(\"Failed to decode SAMLResponse\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tstatic class CappedOutputStream extends OutputStream {\n\n\t\tprivate static final long MAX_SIZE = 1024 * 1024;\n\n\t\tprivate final OutputStream delegate;\n\n\t\tprivate int size;\n\n\t\tCappedOutputStream(OutputStream delegate) {\n\t\t\tthis.delegate = delegate;\n\t\t}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/Saml2Utils.java#L171-L207","documentation":"Thrown by the EncodingConfigurer's checkAcceptable when a Base64-decoded SAML input contains characters not acceptable in a SAML XML document. The library validates the decoded string against an acceptability predicate to block invalid/hostile input before parsing; IllegalArgumentException \"Failed to decode SAMLResponse\" signals the decoded content is not acceptable XML content.","triggerScenarios":"Saml2Utils.withDecoded(...).checkAcceptable(ins) is called during redirect-binding decoding; isAcceptable(ins) returns false (disallowed characters/encoding tricks) so an IllegalArgumentException with message \"Failed to decode SAMLResponse\" is thrown.","commonSituations":"SAMLResponse parameter URL-decoded or Base64-decoded incorrectly (wrong decoder, double decoding) producing garbage; malicious request attempting XML/decoder confusion attacks (the check is a hardening measure); non-UTF8 bytes introduced before inflation.","solutions":["Ensure the SAMLResponse is Base64-decoded exactly once with the correct decoder before decoding to string","Ensure the decoded XML is valid UTF-8 without control/binary characters","Check for proxies/gateways mangling the SAMLResponse query parameter","If it appears during a security test, expect the rejection — this check intentionally blocks non-XML input"],"exampleFix":"// before\n String xml = new String(Base64.getDecoder().decode(param), StandardCharsets.ISO_8859_1); // wrong charset\n// after\n String xml = new String(inflate(Base64.getDecoder().decode(param)), StandardCharsets.UTF_8);","handlingStrategy":"validation","validationCode":"// pre-validate decoded SAML content looks like XML\nString xml = new String(inflated, StandardCharsets.UTF_8);\nboolean acceptable = xml.startsWith(\"<\") && xml.chars().noneMatch(c -> c < 0x20 && c != '\\t' && c != '\\n' && c != '\\r');","typeGuard":null,"tryCatchPattern":"try {\n    String xml = Saml2Utils.withDecoded(decoded).checkAcceptable(...);\n} catch (IllegalArgumentException e) {\n    // reject request: decoded content is not acceptable SAML XML\n}","preventionTips":["Decode Base64 exactly once; use UTF-8 when converting to string","URL-decode query parameters before Base64-decoding","Strip or reject control/binary characters before processing","Treat validation failure as untrusted input, not a library bug"],"tags":["saml2","base64","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}