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