Skip to content

Safer parser defaults

Aaron S. Hawley edited this page May 14, 2021 · 1 revision

Internally, Scala XML makes use of the JDK SAXParser library, which by default enables support for a number of standard XML features that can cause security issues when exposed to untrusted input, allowing for denial of service attacks through resource exhaustion, exfiltration and exposure of local files or network resources, among other issues.

To be more robust against these attacks out-of-the-box, the default parser settings have now been changed to a more restricted and safer subset, disabling potentially exploitable features such as external/remote schemas, doctype and entities as well as XIncludes and namespaces.

Should you require support for any of these features and are confident your application is prevented from processing untrusted XML input, or have another need to customize these settings, you can create and use a custom XMLLoader instance like this:

import scala.xml.Elem
import scala.xml.factory.XMLLoader
import javax.xml.parsers.{SAXParser, SAXParserFactory}

object CustomXML extends XMLLoader[Elem] {
  override def parser: SAXParser = {
    val factory = SAXParserFactory.newInstance()
    factory.setFeature("http://xml.org/sax/features/validation", false)
    factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false)
    factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false)
    factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
    factory.newSAXParser()
  }
}
...
val elem = CustomXML.load(reader)

or this

import scala.xml.{XML, Elem}
import scala.xml.factory.XMLLoader
import javax.xml.parsers.{SAXParser, SAXParserFactory}

val customXML: XMLLoader[Elem] = XML.withSAXParser {
  val factory = SAXParserFactory.newInstance()
  factory.setFeature("http://xml.org/sax/features/validation", false)
  factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false)
  factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false)
  factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
  factory.newSAXParser()
}
...
val elem = customXML.load(reader)
Clone this wiki locally