| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package org.apache.cloudstack.utils.security; |
| |
| import javax.xml.XMLConstants; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.parsers.SAXParserFactory; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerFactory; |
| |
| import org.apache.log4j.Logger; |
| import org.xml.sax.SAXNotRecognizedException; |
| import org.xml.sax.SAXNotSupportedException; |
| |
| public class ParserUtils { |
| private static final Logger LOGGER = Logger.getLogger(ParserUtils.class); |
| |
| public static DocumentBuilderFactory getSaferDocumentBuilderFactory() throws ParserConfigurationException { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| |
| // REDHAT https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf |
| // OWASP https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html |
| // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks" |
| factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); |
| factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", 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); |
| factory.setXIncludeAware(false); |
| factory.setExpandEntityReferences(false); |
| |
| return factory; |
| } |
| |
| public static TransformerFactory getSaferTransformerFactory() { |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| try { |
| factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); |
| } catch (final TransformerConfigurationException e) { |
| LOGGER.warn("Failed to set safer feature on TransformerFactory: ", e); |
| } |
| return factory; |
| } |
| |
| public static SAXParserFactory getSaferSAXParserFactory() { |
| SAXParserFactory factory = SAXParserFactory.newInstance(); |
| try { |
| factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); |
| factory.setFeature("http://xml.org/sax/features/external-general-entities", false); |
| factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); |
| } catch (final ParserConfigurationException | SAXNotRecognizedException | SAXNotSupportedException e) { |
| LOGGER.warn("Failed to set safer feature on SAXParserFactory: ", e); |
| } |
| return factory; |
| } |
| } |