Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

SV.USAGERULES.PERMISSIONS

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 can't do.

Although elevated privileges may be needed only temporarily, many programs never drop the elevated privileges and continue to run with unnecessary root privileges.

To drop privileges, a process needs to set its effective user and group IDs to those of the less privileged user or group using the seteuid() and setegid() system calls to drop them temporarily, or setuid() and setgid() to drop them permanently.

When a low-privileged program needs to perform a high-privileged operation, such as opening a privileged file, the program needs to elevate privileges using setuid. The setuid feature allows executables launched as a user to run with root privileges. Again, it's common that the program fails to revert to its lower privileges at soon as it finishes performing the high-privileged operation.

The SV.USAGERULES.PERMISSIONS checker finds instances of calls for privilege elevation to setegid(), seteuid(), setuid(), setregid(), and setreuid(), as well as AddAccessAllowedAce() or AddAccessAllowedAceEx(), and flags them for review.

Vulnerability and risk

To reduce the possibility of unauthorized code being able to get control, the system should run with the least privilege necessary. 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 operation at 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.

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, doesn't 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.

For less exposure to malicious attack, use the following approaches:

  • Run under an account with less privilege whenever possible, raising privileges as late as possible and lowering them as soon as possible. One way to do this is to use PrivilegeCheck 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. You can authenticate the user by calling CredUIPromptForCredentials (GUI) or CredUICmdLinePromptForCredentials (command line) to obtain user name and password.
  • Impersonate the user. A process that starts under a highly privileged account like the system can impersonate a user account by calling ImpersonateLoggedOnUser or similar impersonate functions to reduce the privilege level. A call to RevertToSelf is injected into the thread to return the process to the original system privileges.
  • 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.
  • Make sure elevated privileges are dropped successfully. It is important to check the return values from the following calls:
    • setuid
    • setguid
    • RpcImpersonateClient
    • ImpersonateNamedPipeClient
    • ImpersonateSelf
    • SetThreatToken
    • ImpersonateLoggedOnUser
    • CoImpersonateClient
    • ImpersonateAnonymousToken
    • ImpersonateDdeClientWindow
    • ImpersonateSecurityContext
When the program is manipulating privileges, a call to any of these functions failing may result in privileges not being reduced. If the return value isn't checked and appropriate action taken, the program may continue operation as the privileged account.