ASF Bugzilla – Attachment 26519 Details for
Bug 22405
warn if not deploy with umask "0077" or if deployed as "root" and provide tutorial URL "Secure deployment"
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch for Tomcat 7
bug22405.patch (text/plain), 16.93 KB, created by
Mark Thomas
on 2011-01-19 13:45:40 UTC
(
hide
)
Description:
Proposed patch for Tomcat 7
Filename:
MIME Type:
Creator:
Mark Thomas
Created:
2011-01-19 13:45:40 UTC
Size:
16.93 KB
patch
obsolete
>Index: bin/catalina.sh >=================================================================== >--- bin/catalina.sh (revision 1060345) >+++ bin/catalina.sh (working copy) >@@ -276,6 +276,7 @@ > -sourcepath "$CATALINA_HOME"/../../java \ > -Djava.security.manager \ > -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \ >+ -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask` \ > -Dcatalina.base="$CATALINA_BASE" \ > -Dcatalina.home="$CATALINA_HOME" \ > -Djava.io.tmpdir="$CATALINA_TMPDIR" \ >@@ -284,6 +285,7 @@ > exec "$_RUNJDB" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \ > -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \ > -sourcepath "$CATALINA_HOME"/../../java \ >+ -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask` \ > -Dcatalina.base="$CATALINA_BASE" \ > -Dcatalina.home="$CATALINA_HOME" \ > -Djava.io.tmpdir="$CATALINA_TMPDIR" \ >@@ -303,6 +305,7 @@ > -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \ > -Djava.security.manager \ > -Djava.security.policy==\"$CATALINA_BASE/conf/catalina.policy\" \ >+ -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask` \ > -Dcatalina.base=\"$CATALINA_BASE\" \ > -Dcatalina.home=\"$CATALINA_HOME\" \ > -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \ >@@ -310,6 +313,7 @@ > else > eval \"$_RUNJAVA\" \"$LOGGING_CONFIG\" $JAVA_OPTS $CATALINA_OPTS \ > -Djava.endorsed.dirs=\"$JAVA_ENDORSED_DIRS\" -classpath \"$CLASSPATH\" \ >+ -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask` \ > -Dcatalina.base=\"$CATALINA_BASE\" \ > -Dcatalina.home=\"$CATALINA_HOME\" \ > -Djava.io.tmpdir=\"$CATALINA_TMPDIR\" \ >Index: conf/server.xml >=================================================================== >--- conf/server.xml (revision 1060345) >+++ conf/server.xml (working copy) >@@ -21,6 +21,7 @@ > --> > <Server port="8005" shutdown="SHUTDOWN"> > >+ <Listener className="org.apache.catalina.security.SecurityListener" /> > <!--APR library loader. Documentation at /docs/apr.html --> > <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> > <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> >Index: java/org/apache/catalina/security/Constants.java >=================================================================== >--- java/org/apache/catalina/security/Constants.java (revision 0) >+++ java/org/apache/catalina/security/Constants.java (revision 0) >@@ -0,0 +1,25 @@ >+/* >+ * Licensed to the Apache Software Foundation (ASF) under one or more >+ * contributor license agreements. See the NOTICE file distributed with >+ * this work for additional information regarding copyright ownership. >+ * 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. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+package org.apache.catalina.security; >+ >+public class Constants { >+ >+ public static final String PACKAGE = "org.apache.catalina.security"; >+ >+ public static final String LINE_SEP = System.getProperty("line.separator"); >+ public static final String CRLF = "\r\n"; >+} > >Property changes on: java\org\apache\catalina\security\Constants.java >___________________________________________________________________ >Added: svn:eol-style > + native > >Index: java/org/apache/catalina/security/LocalStrings.properties >=================================================================== >--- java/org/apache/catalina/security/LocalStrings.properties (revision 1060345) >+++ java/org/apache/catalina/security/LocalStrings.properties (working copy) >@@ -14,4 +14,7 @@ > # limitations under the License. > > SecurityUtil.doAsPrivilege=An exception occurs when running the PrivilegedExceptionAction block. >- >+SecurityListener.checkUmaskFail=Start attempted with umask setting of [{0}]. Running Tomcat without a umask at least as restrictive as [{}] has been blocked by the Lifecycle listener org.apache.catalina.security.SecurityListener (usually configured in CATALINA_BASE/conf/server.xml) >+SecurityListener.checkUmaskNone=No umask setting was found in system property [{0}]. However, it appears Tomcat is running on a platform that supports umask. The system property is typically set in CATALINA_HOME/bin/catalina.sh. The Lifecycle listener org.apache.catalina.security.SecurityListener (usually configured in CATALINA_BASE/conf/server.xml) expects a umask at least as restrictive as [{1}] >+SecurityListener.checkUmaskSkip=Unable to determine umask. It appears Tomcat is running on Windows so skip the umask check. >+SecurityListener.checkUserWarning=Start attempted while running as user [{0}]. Running Tomcat as this user has been blocked by the Lifecycle listener org.apache.catalina.security.SecurityListener (usually configured in CATALINA_BASE/conf/server.xml) >\ No newline at end of file >Index: java/org/apache/catalina/security/SecurityListener.java >=================================================================== >--- java/org/apache/catalina/security/SecurityListener.java (revision 0) >+++ java/org/apache/catalina/security/SecurityListener.java (revision 0) >@@ -0,0 +1,186 @@ >+/* >+ * Licensed to the Apache Software Foundation (ASF) under one or more >+ * contributor license agreements. See the NOTICE file distributed with >+ * this work for additional information regarding copyright ownership. >+ * 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. >+ * See the License for the specific language governing permissions and >+ * limitations under the License. >+ */ >+package org.apache.catalina.security; >+ >+import java.util.HashSet; >+import java.util.Iterator; >+import java.util.Set; >+ >+import org.apache.catalina.Lifecycle; >+import org.apache.catalina.LifecycleEvent; >+import org.apache.catalina.LifecycleListener; >+import org.apache.juli.logging.Log; >+import org.apache.juli.logging.LogFactory; >+import org.apache.tomcat.util.res.StringManager; >+ >+public class SecurityListener implements LifecycleListener { >+ >+ private static final Log log = LogFactory.getLog(SecurityListener.class); >+ >+ private static final StringManager sm = >+ StringManager.getManager(Constants.PACKAGE); >+ >+ private static final String UMASK_PROPERTY_NAME = >+ Constants.PACKAGE + ".SecurityListener.UMASK"; >+ >+ private static final String UMASK_FORMAT = "%04o"; >+ >+ /** >+ * The list of operating system users not permitted to run Tomcat. >+ */ >+ private Set<String> checkedOsUsers = new HashSet<String>(); >+ >+ /** >+ * The minimum umask that must be configured for the operating system user >+ * running Tomcat. The umask is handled as an octal. >+ */ >+ private Integer minimumUmask = Integer.valueOf(7); >+ >+ >+ public SecurityListener() { >+ checkedOsUsers.add("root"); >+ } >+ >+ >+ @Override >+ public void lifecycleEvent(LifecycleEvent event) { >+ // This is the earliest event in Lifecycle >+ if (event.getType().equals(Lifecycle.BEFORE_INIT_EVENT)) { >+ doChecks(); >+ } >+ } >+ >+ >+ /** >+ * Set the list of operating system users not permitted to run Tomcat. By >+ * default, only root is prevented from running Tomcat. Calling this method >+ * with null or the empty string will clear the list of users and >+ * effectively disables this check. User names will always be checked in a >+ * case insensitive manner. >+ * >+ * @param userList A comma separated list of operating system users not >+ * permitted to run Tomcat >+ */ >+ public void setCheckedOsUsers(String userNameList) { >+ if (userNameList == null || userNameList.length() == 0) { >+ checkedOsUsers.clear(); >+ } else { >+ String[] userNames = userNameList.split(","); >+ for (String userName : userNames) { >+ if (userName.length() > 0) { >+ checkedOsUsers.add(userName); >+ } >+ } >+ } >+ } >+ >+ >+ /** >+ * Returns the current list of operating system users not permitted to run >+ * Tomcat. >+ * >+ * @return A comma separated list of operating sytem user names. >+ */ >+ public String getCheckedOsUsers() { >+ if (checkedOsUsers.size() == 0) { >+ return ""; >+ } >+ >+ StringBuilder result = new StringBuilder(); >+ Iterator<String> iter = checkedOsUsers.iterator(); >+ result.append(iter.next()); >+ while (iter.hasNext()) { >+ result.append(','); >+ result.append(iter.next()); >+ } >+ return result.toString(); >+ } >+ >+ >+ /** >+ * Set the minimum umask that must be configured before Tomcat will start. >+ * >+ * @param umask The 4-digit umask as returned by the OS command <i>umask</i> >+ */ >+ public void setMinimumUmask(String umask) { >+ if (umask == null || umask.length() == 0) { >+ minimumUmask = Integer.valueOf(0); >+ } else { >+ minimumUmask = Integer.valueOf(umask, 8); >+ } >+ } >+ >+ >+ /** >+ * Get the minimum umask that must be configured before Tomcat will start. >+ * >+ * @return The 4-digit umask as used by the OS command <i>umask</i> >+ */ >+ public String getMinimumUmask() { >+ return String.format(UMASK_FORMAT, minimumUmask); >+ } >+ >+ >+ /** >+ * Execute the security checks. Each check should be in a separate method. >+ */ >+ protected void doChecks() { >+ checkOsUser(); >+ checkUmask(); >+ } >+ >+ >+ protected void checkOsUser() { >+ String userName = System.getProperty("user.name"); >+ if (userName != null) { >+ String userNameLC = userName.toLowerCase(); >+ >+ if (checkedOsUsers.contains(userNameLC)) { >+ // Have to throw Error to force start process to be aborted >+ throw new Error(sm.getString( >+ "SecurityListener.checkUserWarning", userName)); >+ } >+ } >+ } >+ >+ >+ protected void checkUmask() { >+ Integer umask = Integer.getInteger(UMASK_PROPERTY_NAME, null); >+ if (umask == null) { >+ if (Constants.CRLF.equals(Constants.LINE_SEP)) { >+ // Probably running on Windows so no umask >+ if (log.isDebugEnabled()) { >+ log.debug(sm.getString("SecurityListener.checkUmaskSkip")); >+ } >+ return; >+ } else { >+ if (minimumUmask.intValue() > 0) { >+ log.warn(sm.getString( >+ "SecurityListener.checkUmaskNone", >+ UMASK_PROPERTY_NAME, getMinimumUmask())); >+ } >+ return; >+ } >+ } >+ >+ if ((umask.intValue() & minimumUmask.intValue()) != >+ minimumUmask.intValue()) { >+ throw new Error(sm.getString("SecurityListener.checkUmaskFail", >+ String.format(UMASK_FORMAT, umask), getMinimumUmask())); >+ } >+ } >+} > >Property changes on: java\org\apache\catalina\security\SecurityListener.java >___________________________________________________________________ >Added: svn:eol-style > + native > >Index: java/org/apache/catalina/security/SecurityUtil.java >=================================================================== >--- java/org/apache/catalina/security/SecurityUtil.java (revision 1060345) >+++ java/org/apache/catalina/security/SecurityUtil.java (working copy) >@@ -73,8 +73,6 @@ > private static final org.apache.juli.logging.Log log= > org.apache.juli.logging.LogFactory.getLog( SecurityUtil.class ); > >- private static String PACKAGE = "org.apache.catalina.security"; >- > private static boolean packageDefinitionEnabled = > (System.getProperty("package.definition") == null && > System.getProperty("package.access") == null) ? false : true; >@@ -83,7 +81,7 @@ > * The string resources for this package. > */ > private static final StringManager sm = >- StringManager.getManager(PACKAGE); >+ StringManager.getManager(Constants.PACKAGE); > > > /** >Index: res/confinstall/server_1.xml >=================================================================== >--- res/confinstall/server_1.xml (revision 1060345) >+++ res/confinstall/server_1.xml (working copy) >@@ -21,6 +21,7 @@ > --> > <Server port="8005" shutdown="SHUTDOWN"> > >+ <Listener className="org.apache.catalina.security.SecurityListener" /> > <!--APR library loader. Documentation at /docs/apr.html --> > <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> > <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> >Index: webapps/docs/changelog.xml >=================================================================== >--- webapps/docs/changelog.xml (revision 1060627) >+++ webapps/docs/changelog.xml (working copy) >@@ -54,6 +54,13 @@ > length names being provided for users, roles and groups in the > <code>MemoryRealm</code> and <code>UserDatabaseRealm</code>. (markt) > </add> >+ <add> >+ <bug>22405</bug>: Add a new Lifecycle listener, >+ <code>org.apache.catalina.security.SecurityListener</code> that, by >+ default, prevents Tomcat from starting insecurely. It requires that >+ Tomcat is not started as root and that a umask at least as restrictive >+ as 0007 is used. (markt) >+ </add> > <update> > Improve fix for <bug>50205</bug> to trigger an error earlier if invalid > configuration is used. (markt) >Index: webapps/docs/setup.xml >=================================================================== >--- webapps/docs/setup.xml (revision 1060345) >+++ webapps/docs/setup.xml (working copy) >@@ -131,8 +131,12 @@ > <p>jsvc has other useful parameters, such as <code>-user</code> which > causes it to switch to another user after the daemon initialization is > complete. This allows, for example, running Tomcat as a non privileged >- user while still being able to use privileged ports. >- <code>jsvc --help</code> will return the full jsvc usage >+ user while still being able to use privileged ports. Note that if you >+ use this option and start Tomcat as root, you'll need to disable the >+ <code>org.apache.catalina.security.SecurityListener</code> check that >+ prevents Tomcat starting when running as root.</p> >+ >+ <p><code>jsvc --help</code> will return the full jsvc usage > information. In particular, the <code>-debug</code> option is useful > to debug issues running jsvc.</p> > >Index: webapps/docs/config/listeners.xml >=================================================================== >--- webapps/docs/config/listeners.xml (revision 1060345) >+++ webapps/docs/config/listeners.xml (working copy) >@@ -333,6 +333,36 @@ > > </attributes> > >+ <h3>Security Lifecycle Listener (org.apache.catalina.security.SecurityListener)</h3> >+ >+ <p>The <strong>Security Lifecycle Listener</strong> performs a number of >+ security checks when Tomcat starts and prevents Tomcat from starting if they >+ fail.</p> >+ >+ <p>This listener must only be nested within <a href="server.html">Server</a> >+ elements.</p> >+ >+ <p>The following additional attributes are supported by the <strong>Security >+ Lifecycle Listener</strong>:</p> >+ >+ <attributes> >+ >+ <attribute name="checkedOsUsers" required="false"> >+ <p>A comma separated list of OS users that must not be used to start >+ Tomcat. If not specified, the default value of <b>root</b> is used. To >+ disable this check, set the attribute to the empty string. Usernames >+ are checked in a case-insensitive manner.</p> >+ </attribute> >+ >+ <attribute name="minimumUmask" required="false"> >+ <p>The least rectrictive umask that must be configured before Tomcat >+ will start. If not specified, the default value of <b>0007</b> is used. >+ To disable this check, set the attribute to the empty string. The check >+ is not performed on Windows platforms.</p> >+ </attribute> >+ >+ </attributes> >+ > </subsection> > > </section>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 22405
: 26519