Author: markt Date: Thu Jan 16 15:12:59 2014 New Revision: 1558828 URL: http://svn.apache.org/r1558828 Log: Add an option to the Context to control the blocking of XML external entities when parsing XML configuration files and enable this blocking by default when a security manager is used. The block is implemented via a custom resolver to enable the logging of any blocked entities.
Modified: tomcat/tc6.0.x/trunk/STATUS.txt tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/DigesterFactory.java tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/Constants.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/JspC.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml tomcat/tc6.0.x/trunk/webapps/docs/config/context.xml Modified: tomcat/tc6.0.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/STATUS.txt (original) +++ tomcat/tc6.0.x/trunk/STATUS.txt Thu Jan 16 15:12:59 2014 @@ -36,14 +36,7 @@ None PATCHES PROPOSED TO BACKPORT: [ New proposals should be added at the end of the list ] -* Add an option to the Context to control the blocking of XML external entities - when parsing XML configuration files and enable this blocking by default when - a security manager is used. The block is implemented via a custom resolver to - enable the logging of any blocked entities. - Backport of https://svn.apache.org/r1549529 - http://people.apache.org/~markt/patches/2014-01-13-xml-block-external-tc6-v1.patch - +1: markt, mturk, funkman, remm - -1: +None PATCHES/ISSUES THAT ARE STALLED: Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Context.java Thu Jan 16 15:12:59 2014 @@ -601,6 +601,25 @@ public interface Context extends Contain /** + * Will the parsing of web.xml, web-fragment.xml, *.tld, *.jspx, *.tagx and + * tagplugin.xml files for this Context block the use of external entities? + * + * @return true if access to external entities is blocked + */ + public boolean getXmlBlockExternal(); + + + /** + * Controls whether the parsing of web.xml, web-fragment.xml, *.tld, *.jspx, + * *.tagx and tagplugin.xml files for this Context will block the use of + * external entities. + * + * @param xmlBlockExternal true to block external entities + */ + public void setXmlBlockExternal(boolean xmlBlockExternal); + + + /** * Will the parsing of *.tld files for this Context be performed by a * validating parser? * Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/Globals.java Thu Jan 16 15:12:59 2014 @@ -360,4 +360,15 @@ public final class Globals { */ public static final String JASPER_XML_VALIDATION_TLD_INIT_PARAM = "org.apache.jasper.XML_VALIDATE_TLD"; + + + /** + * Name of the ServletContext init-param that determines if the JSP engine + * will block external entities from being used in *.tld, *.jspx, *.tagx and + * tagplugin.xml files. + * <p> + * This must be kept in sync with org.apache.jasper.Constants + */ + public static final String JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM = + "org.apache.jasper.XML_BLOCK_EXTERNAL"; } Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/ant/ValidatorTask.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,15 +24,16 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import org.apache.catalina.Globals; import org.apache.catalina.startup.Constants; -import org.apache.catalina.startup.DigesterFactory; +import org.apache.tomcat.util.descriptor.DigesterFactory; import org.apache.tomcat.util.digester.Digester; import org.apache.tools.ant.BuildException; import org.xml.sax.InputSource; /** - * Task for validating a web application deployment descriptor, using XML + * Task for validating a web application deployment descriptor, using XML * schema validation. * * @author Remy Maucherat @@ -89,10 +90,13 @@ public class ValidatorTask extends BaseR Thread.currentThread().setContextClassLoader (ValidatorTask.class.getClassLoader()); - Digester digester = DigesterFactory.newDigester(true, true, null); + // Called through trusted manager interface. If running under a + // SecurityManager assume that untrusted applications may be deployed. + Digester digester = DigesterFactory.newDigester( + true, true, null, Globals.IS_SECURITY_ENABLED); try { file = file.getCanonicalFile(); - InputStream stream = + InputStream stream = new BufferedInputStream(new FileInputStream(file)); InputSource is = new InputSource(file.toURL().toExternalForm()); is.setByteStream(stream); Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/ApplicationContext.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -237,14 +237,14 @@ public class ApplicationContext } } - + /** * Return the main path associated with this context. */ public String getContextPath() { return context.getPath(); } - + /** * Return the value of the specified initialization parameter, or @@ -259,7 +259,14 @@ public class ApplicationContext context.getTldValidation()) { return "true"; } - + if (Globals.JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM.equals(name)) { + if (context.getXmlBlockExternal()) { + return "true"; + } else if (Globals.IS_SECURITY_ENABLED) { + // System admin has explicitly changed the default + return "false"; + } + } return parameters.get(name); } @@ -268,7 +275,7 @@ public class ApplicationContext if (parameters.containsKey(name)) { return false; } - + parameters.put(name, value); return true; } @@ -286,6 +293,9 @@ public class ApplicationContext if (context.getTldValidation()) { names.add(Globals.JASPER_XML_VALIDATION_TLD_INIT_PARAM); } + if (context.getXmlBlockExternal() || Globals.IS_SECURITY_ENABLED) { + names.add(Globals.JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM); + } return Collections.enumeration(names); } @@ -347,7 +357,7 @@ public class ApplicationContext Wrapper wrapper = (Wrapper) context.findChild(name); if (wrapper == null) return (null); - + return new ApplicationDispatcher(wrapper, null, null, null, null, name); } @@ -403,7 +413,7 @@ public class ApplicationContext if (path == null) return (null); - pos = path.length(); + pos = path.length(); // Use the thread local URI and mapping data DispatchData dd = dispatchData.get(); @@ -454,10 +464,10 @@ public class ApplicationContext String pathInfo = mappingData.pathInfo.toString(); mappingData.recycle(); - + // Construct a RequestDispatcher to process this request return new ApplicationDispatcher - (wrapper, uriCC.toString(), wrapperPath, pathInfo, + (wrapper, uriCC.toString(), wrapperPath, pathInfo, queryString, null); } @@ -483,7 +493,7 @@ public class ApplicationContext if (!path.startsWith("/") && Globals.STRICT_SERVLET_COMPLIANCE) throw new MalformedURLException(sm.getString("applicationContext.requestDispatcher.iae", path)); - + path = RequestUtil.normalize(path); if (path == null) return (null); @@ -685,7 +695,7 @@ public class ApplicationContext * <code>log(String, Throwable)</code> instead */ public void log(Exception exception, String message) { - + context.getLogger().error(message, exception); } @@ -698,7 +708,7 @@ public class ApplicationContext * @param throwable Exception to be reported */ public void log(String message, Throwable throwable) { - + context.getLogger().error(message, throwable); } @@ -839,7 +849,7 @@ public class ApplicationContext protected StandardContext getContext() { return this.context; } - + protected Map getReadonlyAttributes() { return this.readOnlyAttributes; } @@ -862,10 +872,10 @@ public class ApplicationContext String key = (String) keys.next(); removeAttribute(key); } - + } - - + + /** * Return the facade associated with this ApplicationContext. */ Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/core/StandardContext.java Thu Jan 16 15:12:59 2014 @@ -647,6 +647,13 @@ public class StandardContext protected int cacheMaxSize = 10240; // 10 MB + + /** + * Attribute used to turn on/off the use of external entities. + */ + private boolean xmlBlockExternal = Globals.IS_SECURITY_ENABLED; + + /** * Cache object max size in KB. */ @@ -5884,6 +5891,16 @@ public class StandardContext } + public void setXmlBlockExternal(boolean xmlBlockExternal) { + this.xmlBlockExternal = xmlBlockExternal; + } + + + public boolean getXmlBlockExternal() { + return xmlBlockExternal; + } + + public void setTldValidation(boolean tldValidation){ this.tldValidation = tldValidation; } Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java Thu Jan 16 15:12:59 2014 @@ -51,6 +51,7 @@ import org.apache.catalina.deploy.Securi import org.apache.catalina.util.StringManager; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; +import org.apache.tomcat.util.descriptor.DigesterFactory; import org.apache.tomcat.util.descriptor.XmlErrorHandler; import org.apache.tomcat.util.digester.Digester; import org.apache.tomcat.util.digester.RuleSet; @@ -520,9 +521,11 @@ public class ContextConfig implements Li protected void createWebXmlDigester(boolean namespaceAware, boolean validation) { + boolean blockExternal = context.getXmlBlockExternal(); + webRuleSet = new WebRuleSet(); webDigester = DigesterFactory.newDigester(validation, - namespaceAware, webRuleSet); + namespaceAware, webRuleSet, blockExternal); webDigester.getParser(); } Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/DigesterFactory.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/DigesterFactory.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/DigesterFactory.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/DigesterFactory.java Thu Jan 16 15:12:59 2014 @@ -28,7 +28,10 @@ import org.apache.tomcat.util.digester.R * Wrapper class around the Digester that hide Digester's initialization details * * @author Jean-Francois Arcand + * + * @deprecated Use {@link org.apache.tomcat.util.descriptor.DigesterFactory} */ +@Deprecated public class DigesterFactory { /** * The log. Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/startup/TldConfig.java Thu Jan 16 15:12:59 2014 @@ -49,6 +49,7 @@ import org.apache.catalina.LifecycleList import org.apache.catalina.core.StandardContext; import org.apache.catalina.core.StandardHost; import org.apache.catalina.util.StringManager; +import org.apache.tomcat.util.descriptor.DigesterFactory; import org.apache.tomcat.util.descriptor.XmlErrorHandler; import org.apache.tomcat.util.digester.Digester; import org.xml.sax.InputSource; @@ -141,20 +142,21 @@ public final class TldConfig implements * Create (if necessary) and return a Digester configured to process the * tld. */ - private static Digester createTldDigester(boolean validation) { + private static Digester createTldDigester(boolean validation, + boolean blockExternal) { Digester digester = null; if (!validation) { if (tldDigesters[0] == null) { tldDigesters[0] = DigesterFactory.newDigester(validation, - true, new TldRuleSet()); + true, new TldRuleSet(), blockExternal); tldDigesters[0].getParser(); } digester = tldDigesters[0]; } else { if (tldDigesters[1] == null) { tldDigesters[1] = DigesterFactory.newDigester(validation, - true, new TldRuleSet()); + true, new TldRuleSet(), blockExternal); tldDigesters[1].getParser(); } digester = tldDigesters[1]; @@ -705,7 +707,8 @@ public final class TldConfig implements ((StandardHost) context.getParent()).getXmlValidation(); } - tldDigester = createTldDigester(context.getTldValidation()); + tldDigester = createTldDigester(context.getTldValidation(), + context.getXmlBlockExternal()); } } } Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/Constants.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/Constants.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/Constants.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/Constants.java Thu Jan 16 15:12:59 2014 @@ -213,4 +213,13 @@ public class Constants { */ public static final String XML_VALIDATION_TLD_INIT_PARAM = "org.apache.jasper.XML_VALIDATE_TLD"; + + /** + * Name of the ServletContext init-param that determines if the XML parsers + * will block the resolution of external entities. + * <p> + * This must be kept in sync with org.apache.catalina.Globals + */ + public static final String XML_BLOCK_EXTERNAL_INIT_PARAM = + "org.apache.jasper.XML_BLOCK_EXTERNAL"; } Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/JspC.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/JspC.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/JspC.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/JspC.java Thu Jan 16 15:12:59 2014 @@ -124,7 +124,7 @@ public class JspC extends Task implement protected static final String SWITCH_SMAP = "-smap"; protected static final String SWITCH_DUMP_SMAP = "-dumpsmap"; protected static final String SWITCH_VALIDATE_TLD = "-validateTld"; - + protected static final String SWITCH_BLOCK_EXTERNAL = "-blockExternal"; protected static final String SHOW_SUCCESS ="-s"; protected static final String LIST_ERRORS = "-l"; protected static final int INC_WEBXML = 10; @@ -145,6 +145,7 @@ public class JspC extends Task implement protected boolean trimSpaces = false; protected boolean genStringAsCharArray = false; protected boolean validateTld; + protected boolean blockExternal; protected boolean xpoweredBy; protected boolean mappedFile = false; protected boolean poolingEnabled = true; @@ -355,6 +356,8 @@ public class JspC extends Task implement smapDumped = true; } else if (tok.equals(SWITCH_VALIDATE_TLD)) { setValidateTld(true); + } else if (tok.equals(SWITCH_BLOCK_EXTERNAL)) { + setBlockExternal(true); } else { if (tok.startsWith("-")) { throw new JasperException("Unrecognized option: " + tok + @@ -848,6 +851,14 @@ public class JspC extends Task implement return validateTld; } + public void setBlockExternal( boolean b ) { + this.blockExternal = b; + } + + public boolean isBlockExternal() { + return blockExternal; + } + public void setListErrors( boolean b ) { listErrors = b; } @@ -1436,6 +1447,9 @@ public class JspC extends Task implement if (isValidateTld()) { context.setInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM, "true"); } + if (isBlockExternal()) { + context.setInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM, "true"); + } rctxt = new JspRuntimeContext(context, this); jspConfig = new JspConfig(context); Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.Set; import java.util.Vector; +import javax.servlet.ServletContext; import javax.servlet.jsp.tagext.FunctionInfo; import javax.servlet.jsp.tagext.TagFileInfo; import javax.servlet.jsp.tagext.TagInfo; @@ -37,7 +38,7 @@ import org.apache.jasper.xmlparser.TreeN /** * Class responsible for generating an implicit tag library containing tag - * handlers corresponding to the tag files in "/WEB-INF/tags/" or a + * handlers corresponding to the tag files in "/WEB-INF/tags/" or a * subdirectory of it. * * @author Jan Luehe @@ -108,7 +109,7 @@ class ImplicitTagLibraryInfo extends Tag * of the "imaginary" <tag-file> element */ String suffix = path.endsWith(TAG_FILE_SUFFIX) ? - TAG_FILE_SUFFIX : TAGX_FILE_SUFFIX; + TAG_FILE_SUFFIX : TAGX_FILE_SUFFIX; String tagName = path.substring(path.lastIndexOf("/") + 1); tagName = tagName.substring(0, tagName.lastIndexOf(suffix)); @@ -118,17 +119,27 @@ class ImplicitTagLibraryInfo extends Tag try { in = ctxt.getResourceAsStream(path); if (in != null) { - + // Add implicit TLD to dependency list if (pi != null) { pi.addDependant(path); } - + + ServletContext servletContext = ctxt.getServletContext(); boolean validate = Boolean.parseBoolean( - ctxt.getServletContext().getInitParameter( + servletContext.getInitParameter( Constants.XML_VALIDATION_TLD_INIT_PARAM)); + String blockExternalString = + servletContext.getInitParameter( + Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } - ParserUtils pu = new ParserUtils(validate); + ParserUtils pu = new ParserUtils(validate, blockExternal); TreeNode tld = pu.parseXMLDocument(uri, in); if (tld.findAttribute("version") != null) { @@ -174,8 +185,8 @@ class ImplicitTagLibraryInfo extends Tag } } } - } - + } + } /** Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspConfig.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -86,12 +86,20 @@ public class JspConfig { is = uri.openStream(); InputSource ip = new InputSource(is); - ip.setSystemId(uri.toExternalForm()); + ip.setSystemId(uri.toExternalForm()); boolean validate = Boolean.parseBoolean( ctxt.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM)); - - ParserUtils pu = new ParserUtils(validate); + String blockExternalString = + ctxt.getInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } + + ParserUtils pu = new ParserUtils(validate, blockExternal); TreeNode webApp = pu.parseXMLDocument(WEB_XML, ip); if (webApp == null @@ -232,7 +240,7 @@ public class JspConfig { defaultIsELIgnored, defaultIsScriptingInvalid, null, null, null, - defaultDeferedSyntaxAllowedAsLiteral, + defaultDeferedSyntaxAllowedAsLiteral, defaultTrimDirectiveWhitespaces); initialized = true; } @@ -285,7 +293,7 @@ public class JspConfig { init(); - // JSP Configuration settings do not apply to tag files + // JSP Configuration settings do not apply to tag files if (jspProperties == null || uri.endsWith(".tag") || uri.endsWith(".tagx")) { return defaultJspProperty; @@ -406,7 +414,7 @@ public class JspConfig { } return new JspProperty(isXml, isELIgnored, isScriptingInvalid, - pageEncoding, includePreludes, includeCodas, + pageEncoding, includePreludes, includeCodas, isDeferedSyntaxAllowedAsLiteral, isTrimDirectiveWhitespaces); } @@ -496,7 +504,7 @@ public class JspConfig { public JspProperty(String isXml, String elIgnored, String scriptingInvalid, String pageEncoding, Vector includePrelude, Vector includeCoda, - String deferedSyntaxAllowedAsLiteral, + String deferedSyntaxAllowedAsLiteral, String trimDirectiveWhitespaces) { this.isXml = isXml; @@ -532,11 +540,11 @@ public class JspConfig { public Vector getIncludeCoda() { return includeCoda; } - + public String isDeferedSyntaxAllowedAsLiteral() { return deferedSyntaxAllowedAsLiteral; } - + public String isTrimDirectiveWhitespaces() { return trimDirectiveWhitespaces; } Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java Thu Jan 16 15:12:59 2014 @@ -31,8 +31,11 @@ import javax.servlet.jsp.tagext.TagLibra import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import org.apache.jasper.Constants; import org.apache.jasper.JasperException; import org.apache.jasper.JspCompilationContext; +import org.apache.tomcat.util.descriptor.DigesterFactory; +import org.apache.tomcat.util.descriptor.LocalResolver; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.Locator; @@ -40,6 +43,7 @@ import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.ext.DefaultHandler2; +import org.xml.sax.ext.EntityResolver2; import org.xml.sax.helpers.AttributesImpl; /** @@ -93,6 +97,7 @@ class JspDocumentParser private boolean inDTD; private boolean isValidating; + private final EntityResolver2 entityResolver; private ErrorDispatcher err; private boolean isTagFile; @@ -121,6 +126,20 @@ class JspDocumentParser this.isTagFile = isTagFile; this.directivesOnly = directivesOnly; this.isTop = true; + + String blockExternalString = ctxt.getServletContext().getInitParameter( + Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } + + this.entityResolver = new LocalResolver( + DigesterFactory.SERVLET_API_PUBLIC_IDS, + DigesterFactory.SERVLET_API_SYSTEM_IDS, + blockExternal); } /* @@ -241,9 +260,24 @@ class JspDocumentParser @Override + public InputSource getExternalSubset(String name, String baseURI) + throws SAXException, IOException { + return entityResolver.getExternalSubset(name, baseURI); + } + + + + @Override + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException { + return entityResolver.resolveEntity(publicId, systemId); + } + + + @Override public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException { - return null; + return entityResolver.resolveEntity(name, publicId, baseURI, systemId); } Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -33,6 +33,7 @@ import java.util.Vector; import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import javax.servlet.ServletContext; import javax.servlet.jsp.tagext.FunctionInfo; import javax.servlet.jsp.tagext.PageData; import javax.servlet.jsp.tagext.TagAttributeInfo; @@ -55,7 +56,7 @@ import org.apache.juli.logging.LogFactor /** * Implementation of the TagLibraryInfo class from the JSP spec. - * + * * @author Anil K. Vijendran * @author Mandar Raje * @author Pierre Delisle @@ -68,7 +69,7 @@ class TagLibraryInfoImpl extends TagLibr private Log log = LogFactory.getLog(TagLibraryInfoImpl.class); private JspCompilationContext ctxt; - + private PageInfo pi; private ErrorDispatcher err; @@ -206,7 +207,7 @@ class TagLibraryInfoImpl extends TagLibr Collection coll = pi.getTaglibs(); return (TagLibraryInfo[]) coll.toArray(new TagLibraryInfo[0]); } - + /* * @param ctxt The JSP compilation context @param uri The TLD's uri @param * in The TLD's input stream @param jarFileUrl The JAR file containing the @@ -218,12 +219,20 @@ class TagLibraryInfoImpl extends TagLibr Vector tagFileVector = new Vector(); Hashtable functionTable = new Hashtable(); - boolean validate = Boolean.parseBoolean( - ctxt.getServletContext().getInitParameter( + ServletContext servletContext = ctxt.getServletContext(); + boolean validate = Boolean.parseBoolean(servletContext.getInitParameter( Constants.XML_VALIDATION_TLD_INIT_PARAM)); - + String blockExternalString = servletContext.getInitParameter( + Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } + // Create an iterator over the child elements of our <taglib> element - ParserUtils pu = new ParserUtils(validate); + ParserUtils pu = new ParserUtils(validate, blockExternal); TreeNode tld = pu.parseXMLDocument(uri, in); // Check to see if the <taglib> root element contains a 'version' @@ -307,7 +316,7 @@ class TagLibraryInfoImpl extends TagLibr /* * @param uri The uri of the TLD @param ctxt The compilation context - * + * * @return String array whose first element denotes the path to the TLD. If * the path to the TLD points to a jar file, then the second element denotes * the name of the TLD entry in the jar file, which is hardcoded to @@ -444,11 +453,11 @@ class TagLibraryInfoImpl extends TagLibr /* * Parses the tag file directives of the given TagFile and turns them into a * TagInfo. - * + * * @param elem The <tag-file> element in the TLD @param uri The location of * the TLD, in case the tag file is specified relative to it @param jarFile * The JAR file, in case the tag file is packaged in a JAR - * + * * @return TagInfo correspoding to tag file directives */ private TagFileInfo createTagFileInfo(TreeNode elem, String uri, @@ -469,8 +478,8 @@ class TagLibraryInfoImpl extends TagLibr // Ignore <example> element: Bugzilla 33538 } else if ("tag-extension".equals(tname)) { // Ignore <tag-extension> element: Bugzilla 33538 - } else if ("icon".equals(tname) - || "display-name".equals(tname) + } else if ("icon".equals(tname) + || "display-name".equals(tname) || "description".equals(tname)) { // Ignore these elements: Bugzilla 38015 } else { @@ -589,7 +598,7 @@ class TagLibraryInfoImpl extends TagLibr // translation time) the type is fixed at java.lang.String. type = "java.lang.String"; } - + return new TagAttributeInfo(name, required, type, rtexprvalue, isFragment, null, deferredValue, deferredMethod, expectedType, methodSignature); @@ -741,7 +750,7 @@ class TagLibraryInfoImpl extends TagLibr /** * The instance (if any) for the TagLibraryValidator class. - * + * * @return The TagLibraryValidator instance, if any. */ public TagLibraryValidator getTagLibraryValidator() { @@ -752,7 +761,7 @@ class TagLibraryInfoImpl extends TagLibr * Translation-time validation of the XML document associated with the JSP * page. This is a convenience method on the associated TagLibraryValidator * class. - * + * * @param thePage * The JSP page object * @return A string indicating whether the page is valid or not. Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TagPluginManager.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,6 +21,7 @@ import java.util.*; import java.io.*; import javax.servlet.ServletContext; +import org.apache.jasper.Constants; import org.apache.jasper.JasperException; import org.apache.jasper.xmlparser.ParserUtils; import org.apache.jasper.xmlparser.TreeNode; @@ -65,7 +66,7 @@ public class TagPluginManager { }); } - + private void init(ErrorDispatcher err) throws JasperException { if (initialized) return; @@ -74,8 +75,18 @@ public class TagPluginManager { if (is == null) return; - TreeNode root = (new ParserUtils(false)).parseXMLDocument(TAG_PLUGINS_XML, - is); + String blockExternalString = ctxt.getInitParameter( + Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } + + ParserUtils pu = new ParserUtils(false, blockExternal); + + TreeNode root = pu.parseXMLDocument(TAG_PLUGINS_XML, is); if (root == null) { return; } @@ -118,7 +129,7 @@ public class TagPluginManager { } /** - * Invoke tag plugin for the given custom tag, if a plugin exists for + * Invoke tag plugin for the given custom tag, if a plugin exists for * the custom tag's tag handler. * * The given custom tag node will be manipulated by the plugin. @@ -221,7 +232,7 @@ public class TagPluginManager { } public void generateBody() { - // Since we'll generate the body anyway, this is really a nop, + // Since we'll generate the body anyway, this is really a nop, // except for the fact that it lets us put the Java sources the // plugins produce in the correct order (w.r.t the body). curNodes = node.getAtETag(); Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java Thu Jan 16 15:12:59 2014 @@ -5,9 +5,9 @@ * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -45,7 +45,7 @@ import org.apache.juli.logging.LogFactor /** * A container for all tag libraries that are defined "globally" * for the web application. - * + * * Tag Libraries can be defined globally in one of two ways: * 1. Via <taglib> elements in web.xml: * the uri and location of the tag-library are specified in @@ -165,16 +165,16 @@ public class TldLocationsCache { noTldJars.add("tools.jar"); noTldJars.add("sunpkcs11.jar"); } - + public TldLocationsCache(ServletContext ctxt) { this(ctxt, true); } - /** Constructor. + /** Constructor. * - * @param ctxt the servlet context of the web application in which Jasper + * @param ctxt the servlet context of the web application in which Jasper * is running - * @param redeployMode if true, then the compiler will allow redeploying + * @param redeployMode if true, then the compiler will allow redeploying * a tag library from the same jar, at the expense of slowing down the * server a bit. Note that this may only work on JDK 1.3.1_01a and later, * because of JDK bug 4211817 fixed in this release. @@ -190,8 +190,8 @@ public class TldLocationsCache { /** * Sets the list of JARs that are known not to contain any TLDs. * - * @param jarNames List of comma-separated names of JAR files that are - * known not to contain any TLDs + * @param jarNames List of comma-separated names of JAR files that are + * known not to contain any TLDs */ public static void setNoTldJars(String jarNames) { if (jarNames != null) { @@ -210,7 +210,7 @@ public class TldLocationsCache { * in the web application. A tag library is 'exposed' either explicitly in * web.xml or implicitly via the uri tag in the TLD of a taglib deployed * in a jar file (WEB-INF/lib). - * + * * @param uri The taglib uri * * @return An array of two Strings: The first element denotes the real @@ -226,7 +226,7 @@ public class TldLocationsCache { return (String[]) mappings.get(uri); } - /** + /** * Returns the type of a URI: * ABS_URI * ROOT_REL_URI @@ -257,7 +257,7 @@ public class TldLocationsCache { /* * Populates taglib map described in web.xml. - */ + */ private void processWebDotXml() throws Exception { InputStream is = null; @@ -291,19 +291,29 @@ public class TldLocationsCache { } is = uri.openStream(); InputSource ip = new InputSource(is); - ip.setSystemId(uri.toExternalForm()); + ip.setSystemId(uri.toExternalForm()); boolean validate = Boolean.parseBoolean( ctxt.getInitParameter( Constants.XML_VALIDATION_TLD_INIT_PARAM)); - + String blockExternalString = ctxt.getInitParameter( + Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } + // Parse the web application deployment descriptor + ParserUtils pu = new ParserUtils(validate, blockExternal); + TreeNode webtld = null; // altDDName is the absolute path of the DD if (altDDName != null) { - webtld = new ParserUtils(validate).parseXMLDocument(altDDName, ip); + webtld = pu.parseXMLDocument(altDDName, ip); } else { - webtld = new ParserUtils(validate).parseXMLDocument(WEB_XML, ip); + webtld = pu.parseXMLDocument(WEB_XML, ip); } // Allow taglib to be an element of the root or jsp-config (JSP2.0) @@ -462,15 +472,23 @@ public class TldLocationsCache { * Returns the value of the uri element of the given TLD, or null if the * given TLD does not contain any such element. */ - private String getUriFromTld(String resourcePath, InputStream in) + private String getUriFromTld(String resourcePath, InputStream in) throws JasperException { boolean validate = Boolean.parseBoolean( ctxt.getInitParameter( Constants.XML_VALIDATION_TLD_INIT_PARAM)); + String blockExternalString = ctxt.getInitParameter( + Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); + boolean blockExternal; + if (blockExternalString == null) { + blockExternal = Constants.IS_SECURITY_ENABLED; + } else { + blockExternal = Boolean.parseBoolean(blockExternalString); + } - // Parse the tag library descriptor at the specified resource path - TreeNode tld = new ParserUtils(validate).parseXMLDocument(resourcePath, in); + ParserUtils pu = new ParserUtils(validate, blockExternal); + TreeNode tld = pu.parseXMLDocument(resourcePath, in); TreeNode uri = tld.findChild("uri"); if (uri != null) { String body = uri.getBody(); @@ -484,7 +502,7 @@ public class TldLocationsCache { /* * Scans all JARs accessible to the webapp's classloader and its * parent classloaders for TLDs. - * + * * The list of JARs always includes the JARs under WEB-INF/lib, as well as * all shared JARs in the classloader delegation chain of the webapp's * classloader. @@ -492,7 +510,7 @@ public class TldLocationsCache { * Considering JARs in the classloader delegation chain constitutes a * Tomcat-specific extension to the TLD search * order defined in the JSP spec. It allows tag libraries packaged as JAR - * files to be shared by web applications by simply dropping them in a + * files to be shared by web applications by simply dropping them in a * location that all web applications have access to (e.g., * <CATALINA_HOME>/common/lib). * Modified: tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/jasper/xmlparser/ParserUtils.java Thu Jan 16 15:12:59 2014 @@ -23,6 +23,7 @@ import javax.xml.parsers.DocumentBuilder import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.apache.jasper.Constants; import org.apache.jasper.JasperException; import org.apache.jasper.compiler.Localizer; import org.apache.tomcat.util.descriptor.DigesterFactory; @@ -59,7 +60,7 @@ public class ParserUtils { /** * @deprecated Unused. Will be removed in Tomcat 7. - * Use {@link ParserUtils#ParserUtils(boolean)} instead. + * Use {@link ParserUtils#ParserUtils(boolean,boolean)} instead. */ @Deprecated public static boolean validating = false; @@ -68,19 +69,19 @@ public class ParserUtils { /** * @deprecated Unused. Will be removed in Tomcat 7. - * Use {@link ParserUtils#ParserUtils(boolean)} instead. + * Use {@link ParserUtils#ParserUtils(boolean,boolean)} instead. */ @Deprecated public ParserUtils() { - this(true); + this(true, Constants.IS_SECURITY_ENABLED); } - public ParserUtils(boolean useValidation) { + public ParserUtils(boolean useValidation, boolean blockExternal) { this.useValidation = useValidation; if (entityResolver == null) { this.entityResolverInstance = new LocalResolver( DigesterFactory.SERVLET_API_PUBLIC_IDS, - DigesterFactory.SERVLET_API_SYSTEM_IDS, false); + DigesterFactory.SERVLET_API_SYSTEM_IDS, blockExternal); } else { this.entityResolverInstance = entityResolver; } Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Thu Jan 16 15:12:59 2014 @@ -99,6 +99,12 @@ Ensure that sessions IDs are not parsed from URLs for Contexts where <code>disableURLRewriting</code> is <code>true</code>. (markt) </fix> + <add> + Add an option to the Context to control the blocking of XML external + entities when parsing XML configuration files and enable this blocking + by default when a security manager is used. The block is implemented via + a custom resolver to enable the logging of any blocked entities. (markt) + </add> </changelog> </subsection> <subsection name="Coyote"> Modified: tomcat/tc6.0.x/trunk/webapps/docs/config/context.xml URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/config/context.xml?rev=1558828&r1=1558827&r2=1558828&view=diff ============================================================================== --- tomcat/tc6.0.x/trunk/webapps/docs/config/context.xml (original) +++ tomcat/tc6.0.x/trunk/webapps/docs/config/context.xml Thu Jan 16 15:12:59 2014 @@ -361,6 +361,16 @@ Context. If not specified, a standard default value will be used.</p> </attribute> + <attribute name="xmlBlockExternal" required="false"> + <p>If the value of this flag is <code>true</code>, the parsing of + <code>web.xml</code>, <code>web-fragment.xml</code>, <code>*.tld</code>, + <code>*.jspx</code>, <code>*.tagx</code> and <code>tagPlugins.xml</code> + files for this web application will not permit external entities to be + loaded. If a <code>SecurityManager</code> is configured then the default + value of this attribute will be <code>true</code>, else the default + value will be <code>false</code>.</p> + </attribute> + <attribute name="xmlNamespaceAware" required="false"> <p>If the value of this flag is <code>true</code>, the parsing of the <code>web.xml</code> file for this web application will be --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org