Exposure to privilege escalation
Some functions require special privileges to run correctly, or are only able to be run by certain users or members of certain groups, such as local administrators. Other functions require the user's account to have specific privileges enabled, for instance to obtain access to a system resource. For example, in a network service, super-user privileges are often required to allocate a privileged TCP or UDP port, which a normal user cannot do.
Although elevated privileges may be needed only temporarily, many programs never drop the elevated privileges and continue to run with unnecessary root privileges.
When a low-privileged program needs to perform a high-privileged operation, such as opening a privileged file, the program needs to elevate privileges by using setuid. The setuid feature allows executables launched as a user to run with root privileges. Again, it is common that the program fails to revert to its lower privileges at soon as it finishes performing the high-privileged operation.
The CS.SV.USAGERULES.PERMISSIONS checker finds instances of calls to some commonly used privilege elevation functions and flags them for review.
Vulnerability and risk
Applications that need to call functions that require special privileges can leave the system open to attack by hackers. Running with extra privileges can disable the normal security checks in the operating system or environment, and pre-existing weaknesses turn into security vulnerabilities during operations that use raised privileges. Applications should be designed to run with elevated privileges only for short periods of time and should inform the user of the security implications involved. To reduce the possibility of unauthorized code being able to get control, the system should run with the lowest privilege level that is necessary.
Mitigation and prevention
The first step in establishing which type of account your application needs to run under is to examine the resources the application will use and the privileged APIs it will call. You may find that the application, or large parts of it, does not need administrator privileges. Writing Secure Code, by Michael Howard and David LeBlanc, offers an excellent description of how to carry out this assessment, and is highly recommended.
To reduce exposure to malicious attacks, use the following approaches:
- Run under an account with lower privileges whenever possible; raise privileges as late as possible and lower privileges as soon as possible. One way to do this is to use Privilege Check to determine what privileges are enabled in a token. If the available privileges are not adequate for the current operation, you can disable that code and ask the user to log in to an account with administrator privileges.
- Make sure users are authenticated adequately by user name and password.
- Isolate privileged code. Break functions that need administrator permissions into separate applications.
- Drop privileges with the correct revocation order. In the case of setuid and setguid programs, it's important to drop the group-level privileges and then the user-level privileges.
- Validate that elevated privileges are dropped successfully.
The CS.SV.USAGERULES.PERMISSIONS checker flags the following calls for a review:
- Android.Systems.Os.Chmod o Android.Systems.Os.Chown o Android.Systems.Os.Setegid
- Android.Systems.Os.Setenv o Android.Systems.Os.Seteuid o Android.Systems.Os.Setgid
- Android.Systems.Os.Setsid o Android.Systems.Os.Setuid o Android.Systems.Os.Fchmod
- Android.Systems.Os.Fchown o System.ServiceProcess.ServiceControllerPermissionAttribute.CreatePermission
- System.Net.DnsPermissionAttribute.CreatePermission o System.Net.SocketPermission.AddPermission
- System.Net.SocketPermissionAttribute.CreatePermission o System.Net.WebPermission.AddPermission