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