/* // This software is subject to the terms of the Eclipse Public License v1.0 // Agreement, available at the following URL: // http://www.eclipse.org/legal/epl-v10.html. // You must accept the terms of that agreement to use this software. // // Copyright (C) 2003-2005 Julian Hyde // Copyright (C) 2005-2016 Pentaho // All Rights Reserved. */ package mondrian.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.io.SAXReader; import org.xml.sax.EntityResolver; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; /** * Class was created to prevent XXE Security Vulnerabilities * http://jira.pentaho.com/browse/PPP-3506 * * Created by Yury_Bakhmutski on 10/21/2016. */ public class XmlParserFactoryProducer { private static final Log logger = LogFactory.getLog(XmlParserFactoryProducer.class); /** * Creates an instance of {@link DocumentBuilderFactory} class * with enabled {@link XMLConstants#FEATURE_SECURE_PROCESSING} property. * Enabling this feature prevents from some XXE attacks (e.g. XML bomb) * See PPP-3506 for more details. * * @throws ParserConfigurationException if feature can't be enabled * */ public static DocumentBuilderFactory createSecureDocBuilderFactory() throws ParserConfigurationException { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); docBuilderFactory.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true); docBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); return docBuilderFactory; } /** * Creates an instance of {@link SAXParserFactory} class with enabled {@link XMLConstants#FEATURE_SECURE_PROCESSING} property. * Enabling this feature prevents from some XXE attacks (e.g. XML bomb) * * @throws ParserConfigurationException if a parser cannot * be created which satisfies the requested configuration. * * @throws SAXNotRecognizedException When the underlying XMLReader does * not recognize the property name. * * @throws SAXNotSupportedException When the underlying XMLReader * recognizes the property name but doesn't support the * property. */ public static SAXParserFactory createSecureSAXParserFactory() throws SAXNotSupportedException, SAXNotRecognizedException, ParserConfigurationException { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); factory.setFeature("http://xml.org/sax/features/external-general-entities", false); factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); return factory; } public static SAXReader getSAXReader(final EntityResolver resolver) { SAXReader reader = new SAXReader(); if (resolver != null) { reader.setEntityResolver(resolver); } try { reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); reader.setFeature("http://xml.org/sax/features/external-general-entities", false); reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); } catch (SAXException e) { logger.error("Some parser properties are not supported."); } reader.setIncludeExternalDTDDeclarations(false); reader.setIncludeInternalDTDDeclarations(false); return reader; } } // End XmlParserFactoryProducer.java