From 2e478e52d85450bb9bcd42e3fe6cdf6b2f8a5569 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 6 Oct 2026 14:51:27 +0200 Subject: [PATCH] Document the XXE threat model of SourceHttpMessageConverter This commit adds Javadoc content to the `SourceHttpMessageConverter` to better explain the threat model around XMLserialization/deserialization. Closes gh-37407 --- .../xml/SourceHttpMessageConverter.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java index dc5d04ae824..2d266aa3127 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java @@ -61,6 +61,26 @@ import org.springframework.util.StreamUtils; * Implementation of {@link org.springframework.http.converter.HttpMessageConverter} * that can read and write {@link Source} objects. * + *

Security considerations: {@link #setSupportDtd supportDtd} + * and {@link #setProcessExternalEntities processExternalEntities} only apply + * when reading a request body into a {@code DOMSource}, + * {@code SAXSource} or {@code StAXSource}. They do not apply to writing. + * Spring Framework trusts the application and its data sources, so the XML being written + * is assumed to be application-controlled. Only reading untrusted XML is + * protected against XXE. + * + *

When a handler declares a {@code StreamSource} (or a plain {@code Source}, + * which resolves to it), the application opts in to receiving the raw, + * unparsed request body. That body is not processed by this converter + * and the application is responsible for any later processing of it, including + * writing it back out in a response. Echoing untrusted XML back to the client + * is an application-level decision; the application must parse or sanitize + * that XML safely first (for example by declaring a {@code DOMSource}). + * + *

This behavior is by design and is not considered a vulnerability in + * Spring Framework. Reports of XXE on the write path, or from raw + * {@code StreamSource} pass-through, will be closed as such. + * * @author Arjen Poutsma * @author Rossen Stoyanchev * @author Juergen Hoeller @@ -102,8 +122,11 @@ public class SourceHttpMessageConverter extends AbstractHttpMe /** - * Indicate whether DTD parsing should be supported. + * Indicate whether DTD parsing should be supported when reading + * {@code DOMSource}, {@code SAXSource} and {@code StAXSource} request content. *

Default is {@code false} meaning that DTD is disabled. + *

This setting does not apply to raw {@code StreamSource} content or to + * writing {@code Source} instances; see the class-level documentation. */ public void setSupportDtd(boolean supportDtd) { this.supportDtd = supportDtd; @@ -122,6 +145,8 @@ public class SourceHttpMessageConverter extends AbstractHttpMe /** * Indicate whether external XML entities are processed when converting to a Source. *

Default is {@code false}, meaning that external entities are not resolved. + *

This setting does not apply to raw {@code StreamSource} content or to + * writing {@code Source} instances; see the class-level documentation. *

Note: setting this option to {@code true} also * automatically sets {@link #setSupportDtd} to {@code true}. */