Bug 55969

Summary: Security-related enhancements to the Windows Installer
Product: Tomcat 8 Reporter: Konstantin Preißer <kpreisser>
Component: PackagingAssignee: Tomcat Developers Mailing List <dev>
Severity: enhancement    
Priority: P2    
Version: 8.0.x-trunk   
Target Milestone: ----   
Hardware: PC   

Description Konstantin Preißer 2014-01-07 17:58:54 UTC

as discussed on the Tomcat Users List [1], I'd like to propose the following enhancements to the Windows Installer (explanations are below):

1. Provide an option to automatically adjust file permissions (ACLs) of the Tomcat installation directory so that only the Windows user under which the Tomcat service runs (see 2.) has full access (additionaly to mandatory users like Administrators and SYSTEM), but normal users don't have any access.

2. Provide an option to let the user chose under which Windows user the Tomcat service should run, and set the "LocalService" user [2] (instead of SYSTEM) as default. "LocalService" exists since Windows XP and Windows Server 2003.

3. (optional) 
Change the default value for the shutdown port to -1 (or disable the shutdown port textbox and always use -1).


1) When installing Tomcat with the Windows Service Installer, it installs by default in "%ProgramFiles%\Apache Software Foundation\Tomcat 8.0". A problem that I see here is that this directory is intended to be the place for binaries of programs that every user which has an account on this Windows installation should be able to use (read). However, by default, Tomcat places not only binaries, but also data (conf, logs, webapps, work, temp) in this directory (I think it's possible to run Tomcat with a different data directory by setting a different CATALINA_BASE env, but the Installer doesn't seem to do this).

This means e.g. if you have some passwords in your Tomcat config, every other user on the server will be able to read them (or, webapp binaries which you place in the webapps directory, etc.). Of course, a user which installs a program on the server should know how to secure the data, but I think a Installer should make sure that by default, everything is secure. 

For example, if you install Microsoft SQL Server 2012, it will place binaries and data files into C:\Program Files\Microsoft SQL Server, but the setup adjusts the permissions for the DATA directory so that ordinary users can't access it.

Therefore, the Tomcat Installer should adjust the permissions of the Tomcat Installation directory so that normal users don't have access.

I have not yet looked into how this can be done with the NSIS script, but it seems it should be possible using the "Access Control" plugin [3].

If using the command line, a way to adjust the permissions so that only Administrators, SYSTEM and LocalService (if 2. is implemented and the service runs as LocalService) have full access would be the following command (see [4] for well-known SIDs in Windows):

"%SystemRoot%\system32\icacls.exe" "<Tomcat-Install-Directory>" /inheritance:r /grant *S-1-5-19:(OI)(CI)(F) /grant *S-1-5-32-544:(OI)(CI)(F) /grant *S-1-5-18:(OI)(CI)(F)

Note: When UAC is turned on and you are not logged in with the integrated Administrator account, you cannot open the Tomcat folder with the Windows Explorer, because even if your user is a member of the "Administrators" group, with enabled UAC the Explorer has reduced rights, so the ACL act as if you are not a member of the Administrators group and you therefore cannot display the contents of this folder.

However, if you double-click on the Tomcat folder, the Explorer asks you if you would like to gain full access rights to this folder. This will change the ACL so that your current user gets full access. This has the side-effect that other applications that you execute can write to the Tomcat directory even they are executed with reduced rights, but I think this is OK on a server. (Previously, you could browse the Tomcat Installation directory but not change any file. Windows Explorer would ask you for administrative rights to copy a file into it or delete one. This however did not change the File ACLs.)

Maybe the installer could also add "read" or "full access" rights for the current user to the Tomcat directory.

Note that on a Windows Server (2012), the default "Administrator" account seems to not be impacted by UAC - this user always runs with full privileges.

2) By default, the installer sets the Tomcat Service to run under the LocalSystem account which as administrative privileges.

Normally, Tomcat shouldn't run as root/Administrator user for security reasons. An alternative would be to run as LocalService or NetworkService which are users that exist by default and don't have administrative privileges (i.e. they has only normal user rights) [2]. AFAIK, this user can only be used for run services, but it cannot be used with things like the "runas" command so every other user will not be able to access data with NetworkUser privileges. (This is also done e.g. by VisualSVN Server - it runs as NetworkService.)

If Tomcat is running under the System account and Tomcat or one of its web applications had a security vulnerability that allowed a remote attacker to execute code on the local machine, they could access everything so the whole system is compromised. However, if Tomcat runs under NetworkService or LocalService, only the data where this user has access is compromised.

Note that in this case, if 1) is applied, the installer would need to additionally give full access to the NetworkService for the "Tomcat 8" directory. 

Note: By default, the users "LocalService" and "NetworkService" do not have the "LogonAsService" privilege. If one opens the Windows Service manager and manually changes the user of a service to "LocalService" or "NetworkService", it will display a message that this user has been given the right to logon as a service.

3) When running the installer, it asks for the Server Shutdown port which has a value of "8005" by default. However, when running Tomcat as a service, the shutdown port is not needed as the daemon service wrapper implements the logic to shutdown Tomcat. When the shutdown port is not disabled, everyone which can connect from localhost (e.g. other users for which PHP- or ASP.Net-like webapps are hosted on the server) can connect to the shutdown port and shutdown Tomcat.

When I have some more time available, I can look into providing a patch if no one else already did it.

[1] http://markmail.org/message/wtz37kxm64qprbz6
[2] http://msdn.microsoft.com/en-us/library/windows/desktop/ms684188%28v=vs.85%29.aspx
[3] http://nsis.sourceforge.net/AccessControl_plug-in
[4] http://support.microsoft.com/kb/243330/en-us
Comment 1 Mark Thomas 2019-05-23 20:57:49 UTC
Just a note to say that I am working on this. I have updated Commons Daemon to offer LocalService and NetworkService in the UI. Note it will need a Commons Daemon release to make this available to Tomcat and there are still some open issues to fix in Daemon.
Comment 2 Mark Thomas 2019-07-08 13:23:00 UTC
The Daemon 1.2.0 release has now happened and I am working on integrating this into the Tomcat installer.

Providing an option to select a user looks to be a significant amount of work. Therefore, I propose to use the default (which has changed to LocalService). The user still has the option to configure the user via the Commons Daemon UI.
Comment 3 Mark Thomas 2019-07-08 14:46:46 UTC
Fixed in:
- master for 9.0.23 onwards
- 8.5.x for 8.5.44 onwards
- 7.0.x for 7.0.95 onwards
Comment 4 Konstantin Preißer 2019-07-08 18:03:02 UTC
Hi Mark,

thanks a lot for your work on this! (It seems I'm getting old, as I didn't even remember having opened this issue when I got the emails today...)