001
014
015 package com.liferay.portal.kernel.xml;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
020 import com.liferay.portal.kernel.util.PropsKeys;
021 import com.liferay.portal.kernel.util.PropsUtil;
022 import com.liferay.portal.kernel.util.StringBundler;
023 import com.liferay.portal.kernel.util.StringPool;
024
025 import java.io.File;
026 import java.io.InputStream;
027 import java.io.Reader;
028
029 import java.net.MalformedURLException;
030 import java.net.URL;
031
032 import java.util.List;
033 import java.util.Map;
034
035
038 public class SAXReaderUtil {
039
040 public static Attribute createAttribute(
041 Element element, QName qName, String value) {
042
043 return getSecureSAXReader().createAttribute(element, qName, value);
044 }
045
046 public static Attribute createAttribute(
047 Element element, String name, String value) {
048
049 return getSecureSAXReader().createAttribute(element, name, value);
050 }
051
052 public static Document createDocument() {
053 return getSecureSAXReader().createDocument();
054 }
055
056 public static Document createDocument(Element rootElement) {
057 return getSecureSAXReader().createDocument(rootElement);
058 }
059
060 public static Document createDocument(String encoding) {
061 return getSecureSAXReader().createDocument(encoding);
062 }
063
064 public static Element createElement(QName qName) {
065 return getSecureSAXReader().createElement(qName);
066 }
067
068 public static Element createElement(String name) {
069 return getSecureSAXReader().createElement(name);
070 }
071
072 public static Entity createEntity(String name, String text) {
073 return getSecureSAXReader().createEntity(name, text);
074 }
075
076 public static Namespace createNamespace(String uri) {
077 return getSecureSAXReader().createNamespace(uri);
078 }
079
080 public static Namespace createNamespace(String prefix, String uri) {
081 return getSecureSAXReader().createNamespace(prefix, uri);
082 }
083
084 public static ProcessingInstruction createProcessingInstruction(
085 String target, Map<String, String> data) {
086
087 return getSecureSAXReader().createProcessingInstruction(target, data);
088 }
089
090 public static ProcessingInstruction createProcessingInstruction(
091 String target, String data) {
092
093 return getSecureSAXReader().createProcessingInstruction(target, data);
094 }
095
096 public static QName createQName(String localName) {
097 return getSecureSAXReader().createQName(localName);
098 }
099
100 public static QName createQName(String localName, Namespace namespace) {
101 return getSecureSAXReader().createQName(localName, namespace);
102 }
103
104 public static Text createText(String text) {
105 return getSecureSAXReader().createText(text);
106 }
107
108 public static XPath createXPath(String xPathExpression) {
109 return getSecureSAXReader().createXPath(xPathExpression);
110 }
111
112 public static XPath createXPath(
113 String xPathExpression, Map<String, String> namespaceContextMap) {
114
115 return getSecureSAXReader().createXPath(
116 xPathExpression, namespaceContextMap);
117 }
118
119 public static XPath createXPath(
120 String xPathExpression, String prefix, String namespace) {
121
122 return getSecureSAXReader().createXPath(
123 xPathExpression, prefix, namespace);
124 }
125
126
129 public static SAXReader getSAXReader() {
130 return getSecureSAXReader();
131 }
132
133 public static SAXReader getSecureSAXReader() {
134 PortalRuntimePermission.checkGetBeanProperty(SAXReaderUtil.class);
135
136 if (isCallerWhitelisted()) {
137 return getUnsecureSAXReader();
138 }
139
140 return _saxReader;
141 }
142
143 public static SAXReader getUnsecureSAXReader() {
144 PortalRuntimePermission.checkGetBeanProperty(
145 SAXReaderUtil.class, "unsecureSAXReader");
146
147 return _unsecureSAXReader;
148 }
149
150 public static Document read(File file) throws DocumentException {
151 return getSecureSAXReader().read(file);
152 }
153
154 public static Document read(File file, boolean validate)
155 throws DocumentException {
156
157 return getSecureSAXReader().read(file, validate);
158 }
159
160 public static Document read(InputStream is) throws DocumentException {
161 return getSecureSAXReader().read(is);
162 }
163
164 public static Document read(InputStream is, boolean validate)
165 throws DocumentException {
166
167 return getSecureSAXReader().read(is, validate);
168 }
169
170 public static Document read(Reader reader) throws DocumentException {
171 return getSecureSAXReader().read(reader);
172 }
173
174 public static Document read(Reader reader, boolean validate)
175 throws DocumentException {
176
177 return getSecureSAXReader().read(reader, validate);
178 }
179
180 public static Document read(String xml) throws DocumentException {
181 return getSecureSAXReader().read(xml);
182 }
183
184 public static Document read(String xml, boolean validate)
185 throws DocumentException {
186
187 return getSecureSAXReader().read(xml, validate);
188 }
189
190 public static Document read(String xml, XMLSchema xmlSchema)
191 throws DocumentException {
192
193 return getSecureSAXReader().read(xml, xmlSchema);
194 }
195
196 public static Document read(URL url) throws DocumentException {
197 return getSecureSAXReader().read(url);
198 }
199
200 public static Document read(URL url, boolean validate)
201 throws DocumentException {
202
203 return getSecureSAXReader().read(url, validate);
204 }
205
206 public static Document readURL(String url)
207 throws DocumentException, MalformedURLException {
208
209 return getSecureSAXReader().readURL(url);
210 }
211
212 public static Document readURL(String url, boolean validate)
213 throws DocumentException, MalformedURLException {
214
215 return getSecureSAXReader().readURL(url, validate);
216 }
217
218 public static List<Node> selectNodes(
219 String xPathFilterExpression, List<Node> nodes) {
220
221 return getSecureSAXReader().selectNodes(xPathFilterExpression, nodes);
222 }
223
224 public static List<Node> selectNodes(
225 String xPathFilterExpression, Node node) {
226
227 return getSecureSAXReader().selectNodes(xPathFilterExpression, node);
228 }
229
230 public static void sort(List<Node> nodes, String xPathExpression) {
231 getSecureSAXReader().sort(nodes, xPathExpression);
232 }
233
234 public static void sort(
235 List<Node> nodes, String xPathExpression, boolean distinct) {
236
237 getSecureSAXReader().sort(nodes, xPathExpression, distinct);
238 }
239
240 public void setSecureSAXReader(SAXReader saxReader) {
241 PortalRuntimePermission.checkSetBeanProperty(getClass());
242
243 _saxReader = saxReader;
244 }
245
246 public void setUnsecureSAXReader(SAXReader unsecureSAXReader) {
247 PortalRuntimePermission.checkSetBeanProperty(
248 getClass(), "unsecureSAXReader");
249
250 _unsecureSAXReader = unsecureSAXReader;
251 }
252
253 protected static boolean isCallerWhitelisted() {
254 StringBundler sb = new StringBundler(3);
255
256 Exception e = new Exception();
257
258 StackTraceElement[] stackTraceElements = e.getStackTrace();
259
260 StackTraceElement stackTraceElement = stackTraceElements[2];
261
262 String methodName = stackTraceElement.getMethodName();
263
264 if (!methodName.startsWith("read")) {
265 return false;
266 }
267
268 stackTraceElement = stackTraceElements[3];
269
270 sb.append(stackTraceElement.getClassName());
271 sb.append(StringPool.POUND);
272 sb.append(stackTraceElement.getMethodName());
273
274 String callerSignature = sb.toString();
275
276 for (String whitelistSignature : _XML_SECURITY_WHITELIST) {
277 if (callerSignature.startsWith(whitelistSignature)) {
278 if (_log.isDebugEnabled()) {
279 _log.debug(
280 "Unsecure SAX reader allowed for " + callerSignature +
281 " based on the \"" + whitelistSignature +
282 "\" whitelist");
283 }
284
285 return true;
286 }
287 }
288
289 if (_log.isDebugEnabled()) {
290 _log.debug("Unsecure SAX reader disallowed for " + callerSignature);
291 }
292
293 return false;
294 }
295
296 private static Log _log = LogFactoryUtil.getLog(SAXReaderUtil.class);
297
298 private static final String[] _XML_SECURITY_WHITELIST = PropsUtil.getArray(
299 PropsKeys.XML_SECURITY_WHITELIST);
300
301 private static SAXReader _saxReader;
302 private static SAXReader _unsecureSAXReader;
303
304 }