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 StripDoctypeXMLReader(new SAXParser());
102
103 if (!PropsValues.XML_SECURITY_ENABLED) {
104 return xmlReader;
105 }
106
107 try {
108 xmlReader.setFeature(_FEATURES_DISALLOW_DOCTYPE_DECL, true);
109 }
110 catch (Exception e) {
111 _log.error(
112 "Unable to initialize safe SAX parser to protect from XML " +
113 "Bomb attacks",
114 e);
115 }
116
117 try {
118 xmlReader.setFeature(_FEATURES_EXTERNAL_GENERAL_ENTITIES, false);
119 xmlReader.setFeature(_FEATURES_EXTERNAL_PARAMETER_ENTITIES, false);
120 }
121 catch (Exception e) {
122 _log.error(
123 "Unable to initialize safe SAX parser to protect from XXE " +
124 "attacks",
125 e);
126 }
127
128 return xmlReader;
129 }
130
131 private static final String _FEATURES_DISALLOW_DOCTYPE_DECL =
132 "http:
133
134 private static final String _FEATURES_EXTERNAL_GENERAL_ENTITIES =
135 "http:
136
137 private static final String _FEATURES_EXTERNAL_PARAMETER_ENTITIES =
138 "http:
139
140 private static Log _log = LogFactoryUtil.getLog(
141 SecureXMLFactoryProviderImpl.class);
142
143 }