001
014
015 package com.liferay.portal.security.xml;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.util.PropsValues;
020
021 import javax.xml.XMLConstants;
022 import javax.xml.parsers.DocumentBuilderFactory;
023 import javax.xml.stream.XMLInputFactory;
024
025 import org.apache.xerces.parsers.SAXParser;
026
027 import org.xml.sax.XMLReader;
028
029
032 public class SecureXMLFactoryProviderImpl implements SecureXMLFactoryProvider {
033
034 @Override
035 public DocumentBuilderFactory newDocumentBuilderFactory() {
036 DocumentBuilderFactory documentBuilderFactory =
037 DocumentBuilderFactory.newInstance();
038
039 if (!PropsValues.XML_SECURITY_ENABLED) {
040 return documentBuilderFactory;
041 }
042
043 try {
044 documentBuilderFactory.setFeature(
045 XMLConstants.FEATURE_SECURE_PROCESSING, true);
046 }
047 catch (Exception e) {
048 _log.error(
049 "Unable to initialize safe document builder factory to " +
050 "protect from XML Bomb attacks",
051 e);
052 }
053
054 try {
055 documentBuilderFactory.setFeature(
056 _FEATURES_DISALLOW_DOCTYPE_DECL, true);
057 }
058 catch (Exception e) {
059 _log.error(
060 "Unable to initialize safe document builder factory to " +
061 "protect from XML Bomb attacks",
062 e);
063 }
064
065 try {
066 documentBuilderFactory.setExpandEntityReferences(false);
067 documentBuilderFactory.setFeature(
068 _FEATURES_EXTERNAL_GENERAL_ENTITIES, false);
069 documentBuilderFactory.setFeature(
070 _FEATURES_EXTERNAL_PARAMETER_ENTITIES, false);
071 }
072 catch (Exception e) {
073 _log.error(
074 "Unable to initialize safe document builder factory to " +
075 "protect from XXE attacks",
076 e);
077 }
078
079 return documentBuilderFactory;
080 }
081
082 @Override
083 public XMLInputFactory newXMLInputFactory() {
084 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
085
086 if (!PropsValues.XML_SECURITY_ENABLED) {
087 return xmlInputFactory;
088 }
089
090 xmlInputFactory.setProperty(
091 XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
092 xmlInputFactory.setProperty(
093 XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
094 xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
095
096 return xmlInputFactory;
097 }
098
099 @Override
100 public XMLReader newXMLReader() {
101 XMLReader xmlReader = new SAXParser();
102
103 if (!PropsValues.XML_SECURITY_ENABLED) {
104 return xmlReader;
105 }
106
107 xmlReader = new StripDoctypeXMLReader(new SAXParser());
108
109 try {
110 xmlReader.setFeature(_FEATURES_DISALLOW_DOCTYPE_DECL, true);
111 }
112 catch (Exception e) {
113 _log.error(
114 "Unable to initialize safe SAX parser to protect from XML " +
115 "Bomb attacks",
116 e);
117 }
118
119 try {
120 xmlReader.setFeature(_FEATURES_EXTERNAL_GENERAL_ENTITIES, false);
121 xmlReader.setFeature(_FEATURES_EXTERNAL_PARAMETER_ENTITIES, false);
122 }
123 catch (Exception e) {
124 _log.error(
125 "Unable to initialize safe SAX parser to protect from XXE " +
126 "attacks",
127 e);
128 }
129
130 return xmlReader;
131 }
132
133 private static final String _FEATURES_DISALLOW_DOCTYPE_DECL =
134 "http:
135
136 private static final String _FEATURES_EXTERNAL_GENERAL_ENTITIES =
137 "http:
138
139 private static final String _FEATURES_EXTERNAL_PARAMETER_ENTITIES =
140 "http:
141
142 private static Log _log = LogFactoryUtil.getLog(
143 SecureXMLFactoryProviderImpl.class);
144
145 }