{"record":{"id":"103415045e10e559","repo":"spring-projects/spring-security","slug":"unable-to-inflate-string-103415","errorCode":null,"errorMessage":"Unable to inflate string","messagePattern":"Unable to inflate string","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/metadata/Saml2Utils.java","lineNumber":74,"sourceCode":"\t\t\tdeflater.write(s.getBytes(StandardCharsets.UTF_8));\n\t\t\tdeflater.finish();\n\t\t\treturn b.toByteArray();\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new Saml2Exception(\"Unable to deflate string\", ex);\n\t\t}\n\t}\n\n\tstatic String samlInflate(byte[] b) {\n\t\ttry {\n\t\t\tByteArrayOutputStream out = new ByteArrayOutputStream();\n\t\t\tInflaterOutputStream iout = new InflaterOutputStream(new CappedOutputStream(out), new Inflater(true));\n\t\t\tiout.write(b);\n\t\t\tiout.finish();\n\t\t\treturn new String(out.toByteArray(), StandardCharsets.UTF_8);\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new Saml2Exception(\"Unable to inflate string\", ex);\n\t\t}\n\t}\n\n\tstatic EncodingConfigurer withDecoded(String decoded) {\n\t\treturn new EncodingConfigurer(decoded);\n\t}\n\n\tstatic DecodingConfigurer withEncoded(String encoded) {\n\t\treturn new DecodingConfigurer(encoded);\n\t}\n\n\tstatic final class EncodingConfigurer {\n\n\t\tprivate final String decoded;\n\n\t\tprivate boolean deflate;\n\n\t\tprivate EncodingConfigurer(String decoded) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/metadata/Saml2Utils.java#L56-L92","documentation":"Saml2Utils.samlInflate decompresses a raw-DEFLATE payload from a SAML redirect-binding request back into XML. This Saml2Exception wraps the IOException thrown by InflaterOutputStream when the input bytes are not valid deflate data or stream operations fail.","triggerScenarios":"Calling samlInflate with byte[] that is not valid raw-DEFLATE data (wrong compression, corrupted, or URL-decoded incorrectly) while processing an HTTP-Redirect binding SAML message.","commonSituations":"An IdP sends an incorrectly compressed SAMLRequest/SAMLResponse via redirect binding; a gateway/proxy mangles or re-encodes the query parameter; tests feed plain XML or gzip (with header) instead of raw deflate; custom serialization of the SAML message.","solutions":["Verify the IdP compresses with raw DEFLATE (zlib wrapper must not be present) before base64/URL-encoding","Check the bytes are correctly base64-decoded and URL-decoded exactly once before inflation","Test inflation manually: new Inflater(true) on the payload in a scratch program to confirm data integrity","Inspect intermediary proxies/gateways for query-parameter rewriting","If you control the sender, compare its compression output with Spring Security's own samlDeflate"],"exampleFix":"// before: feeding URL-encoded value directly\nbyte[] b = Base64.getDecoder().decode(requestParam);\n// after: URL-decode first, then decode and inflate\nbyte[] b = Base64.getDecoder().decode(URLDecoder.decode(requestParam, StandardCharsets.UTF_8));","handlingStrategy":"validation","validationCode":"boolean isProbablyDeflated(byte[] b) {\n    if (b == null || b.length == 0) return false;\n    try (var in = new InflaterInputStream(new ByteArrayInputStream(b), new Inflater(true))) {\n        in.read(new byte[16]);\n        return true;\n    } catch (IOException ex) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    String xml = Saml2Utils.samlInflate(bytes);\n} catch (Saml2Exception ex) {\n    logger.warn(\"Invalid deflate payload from sender {}\", senderEntityId, ex.getCause());\n    // fall back to treating payload as uncompressed XML if your protocol allows\n}","preventionTips":["URL-decode and base64-decode the query parameter exactly once before inflating","Confirm the IdP uses raw DEFLATE (no zlib header) for redirect binding","Test the full round-trip deflate/inflate against the real IdP in staging"],"tags":["saml","compression","inflate","io"],"backgroundTag":"saml-inflate-failed","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}