Class FactorySupport
Every create* method returns a factory pre-configured to resist
common XML attack vectors (XXE, billion laughs, external resource
resolution). Overloads accepting flags let callers relax specific defaults
when they legitimately need DOCTYPE support or external resource resolution.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefault bound on how deeply elements may nest in a parsed document. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic DocumentBuilderFactoryCreates a new hardenedDocumentBuilderFactory.static DocumentBuilderFactorycreateDocumentBuilderFactory(boolean allowDocTypeDeclaration) Creates a new hardenedDocumentBuilderFactory.static SAXParsercreateSaxParser(SAXParserFactory factory) Creates aSAXParserfrom the supplied factory, bounded byDEFAULT_MAX_ELEMENT_DEPTH.static SAXParserFactoryCreates a new hardenedSAXParserFactory.static SAXParserFactorycreateSaxParserFactory(boolean allowDocTypeDeclaration) Creates a new hardenedSAXParserFactory.static SchemaFactorycreateSchemaFactory(String schemaLanguage) Creates a new hardenedSchemaFactoryfor the requested schema language.static TransformerFactorycreateTransformerFactory(boolean allowDocTypeDeclaration, boolean allowExternalResources) Creates a new hardenedTransformerFactory.static XMLInputFactoryCreates a new hardenedXMLInputFactoryfor StAX parsing.static XMLInputFactorycreateXMLInputFactory(boolean allowDocTypeDeclaration) Creates a new hardenedXMLInputFactoryfor StAX parsing.static XPathFactoryCreates a new hardenedXPathFactory.
-
Field Details
-
DEFAULT_MAX_ELEMENT_DEPTH
public static final int DEFAULT_MAX_ELEMENT_DEPTHDefault bound on how deeply elements may nest in a parsed document.XMLConstants.FEATURE_SECURE_PROCESSINGdoes not bound element depth: the JAXPjdk.xml.maxElementDepthlimit defaults to0, meaning unlimited. The parse itself survives an arbitrarily deep document, because SAX tracks nesting on the heap, but the first consumer to walk the result recursively —Node.text(),XmlNodePrinter,GPathResult.toString(),XmlUtil.serialize— runs one stack frame per level and dies with aStackOverflowError. That is anError, so it escapes thecatch (Exception)an application would reasonably use to handle a malformed document. Bounding the depth at parse time turns it into an ordinary parse failure, at one check point, before any of those consumers is reached.The value matches
groovy.json's nesting bound, and sits far above any realistic document.- Since:
- 6.0.0
- See Also:
-
-
Constructor Details
-
FactorySupport
public FactorySupport()
-
-
Method Details
-
createDocumentBuilderFactory
public static DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationExceptionCreates a new hardenedDocumentBuilderFactory.Equivalent to
createDocumentBuilderFactory(false): DOCTYPE declarations are rejected andXMLConstants.FEATURE_SECURE_PROCESSINGis enabled. PasstruetocreateDocumentBuilderFactory(boolean)if DOCTYPE support is required.Note: prior to Groovy 6.0.0 this method returned a bare JDK factory with no hardening applied. Callers that previously parsed DOCTYPE-bearing documents through the returned factory must switch to
createDocumentBuilderFactory(true).- Returns:
- a newly created, hardened document builder factory
- Throws:
ParserConfigurationException- if the factory cannot be created
-
createDocumentBuilderFactory
public static DocumentBuilderFactory createDocumentBuilderFactory(boolean allowDocTypeDeclaration) throws ParserConfigurationException Creates a new hardenedDocumentBuilderFactory.The returned factory has
XMLConstants.FEATURE_SECURE_PROCESSINGenabled, the Apachedisallow-doctype-declfeature toggled according to theallowDocTypeDeclarationflag, XInclude disabled, and entity reference expansion disabled.- Parameters:
allowDocTypeDeclaration- whetherDOCTYPEdeclarations are allowed in parsed documents (defaults should befalsefor untrusted input)- Returns:
- a newly created, hardened document builder factory
- Throws:
ParserConfigurationException- if the factory cannot be created- Since:
- 6.0.0
-
createSaxParserFactory
Creates a new hardenedSAXParserFactory.Equivalent to
createSaxParserFactory(false): DOCTYPE declarations are rejected andXMLConstants.FEATURE_SECURE_PROCESSINGis enabled. PasstruetocreateSaxParserFactory(boolean)if DOCTYPE support is required.Note: prior to Groovy 6.0.0 this method returned a bare JDK factory with no hardening applied. Callers that previously parsed DOCTYPE-bearing documents through the returned factory must switch to
createSaxParserFactory(true).- Returns:
- a newly created, hardened SAX parser factory
- Throws:
ParserConfigurationException- if the factory cannot be created
-
createSaxParserFactory
public static SAXParserFactory createSaxParserFactory(boolean allowDocTypeDeclaration) throws ParserConfigurationException Creates a new hardenedSAXParserFactory.The returned factory has
XMLConstants.FEATURE_SECURE_PROCESSINGenabled and the Apachedisallow-doctype-declfeature toggled according to theallowDocTypeDeclarationflag.- Parameters:
allowDocTypeDeclaration- whetherDOCTYPEdeclarations are allowed in parsed documents (defaults should befalsefor untrusted input)- Returns:
- a newly created, hardened SAX parser factory
- Throws:
ParserConfigurationException- if the factory cannot be created- Since:
- 6.0.0
-
createXMLInputFactory
Creates a new hardenedXMLInputFactoryfor StAX parsing.Equivalent to
createXMLInputFactory(false): DTD support and external entity resolution are disabled.- Returns:
- a newly created, hardened StAX input factory
- Since:
- 6.0.0
-
createXMLInputFactory
Creates a new hardenedXMLInputFactoryfor StAX parsing.The returned factory disables external entity resolution unconditionally and toggles
XMLInputFactory.SUPPORT_DTDaccording to theallowDocTypeDeclarationflag.- Parameters:
allowDocTypeDeclaration- whetherDOCTYPEdeclarations are allowed in parsed documents (defaults should befalsefor untrusted input)- Returns:
- a newly created, hardened StAX input factory
- Since:
- 6.0.0
-
createTransformerFactory
public static TransformerFactory createTransformerFactory(boolean allowDocTypeDeclaration, boolean allowExternalResources) Creates a new hardenedTransformerFactory.The returned factory has
XMLConstants.FEATURE_SECURE_PROCESSINGenabled and the Apachedisallow-doctype-declfeature toggled according to theallowDocTypeDeclarationflag. Access to external DTDs and stylesheets is blocked unlessallowExternalResourcesistrue.- Parameters:
allowDocTypeDeclaration- whetherDOCTYPEdeclarations are allowed in transformed documentsallowExternalResources- whether<xsl:import>/<xsl:include>may resolve external DTDs or stylesheets- Returns:
- a newly created, hardened transformer factory
- Since:
- 6.0.0
-
createSchemaFactory
Creates a new hardenedSchemaFactoryfor the requested schema language.The returned factory has
XMLConstants.FEATURE_SECURE_PROCESSINGenabled, which by default already restricts resolution of external schemas and DTDs. That default can be widened by a globaljavax.xml.accessExternalSchema/javax.xml.accessExternalDTDsystem property or ajaxp.propertiesentry; if you need external access denied regardless of such global configuration, setXMLConstants.ACCESS_EXTERNAL_SCHEMAandXMLConstants.ACCESS_EXTERNAL_DTDto""on the returned factory (a property set directly on the factory takes precedence over the global configuration).- Parameters:
schemaLanguage- the schema language URI (seeXMLConstants)- Returns:
- a newly created, hardened schema factory
- Since:
- 6.0.0
-
createXPathFactory
Creates a new hardenedXPathFactory.The returned factory has
XMLConstants.FEATURE_SECURE_PROCESSINGenabled.- Returns:
- a newly created, hardened XPath factory
- Since:
- 6.0.0
-
createSaxParser
public static SAXParser createSaxParser(SAXParserFactory factory) throws ParserConfigurationException, SAXException Creates aSAXParserfrom the supplied factory, bounded byDEFAULT_MAX_ELEMENT_DEPTH.The depth limit cannot be set on a
SAXParserFactory— it is a parser property — so SAX callers should obtain their parser here rather than callingSAXParserFactory.newSAXParser()directly, or the bound will not be applied.- Parameters:
factory- the factory to create the parser from- Returns:
- a newly created parser with the element-depth bound applied
- Throws:
ParserConfigurationException- if the parser cannot be createdSAXException- if the parser cannot be created- Since:
- 6.0.0
-