CWE-273

Improper Check for Dropped Privileges. [Privilege-Issues, Improper-Check-Or-Handling-Of-Exceptional-Conditions]

Required inputs: IR

The product attempts to drop privileges but does not check or incorrectly checks to see if the drop succeeded. If the drop fails, the product will continue to run with the raised privileges, which might provide additional access to unprivileged users.
Background Details Demonstrative Examples
In Windows based environments that have access control, impersonation is used so that access checks can be performed on a client identity by a server with higher privileges. By impersonating the client, the server is restricted to client-level security -- although in different threads it may have much higher privileges.
Background Details Demonstrative Examples
Example 1

This code attempts to take on the privileges of a user before creating a file, thus avoiding performing the action with unnecessarily high privileges:

Example Language:C++
    bool DoSecureStuff(HANDLE hPipe) {
        bool fDataWritten = false;
        ImpersonateNamedPipeClient(hPipe);
        HANDLE hFile = CreateFile(...);
        /../
        RevertToSelf()
        /../
    }

The call to ImpersonateNamedPipeClient may fail, but the return value is not checked. If the call fails, the code may execute with higher privileges than intended. In this case, an attacker could exploit this behavior to write a file to a location that the attacker does not have access to.

Excerpts from CWE [https://cwe.mitre.org], Copyright (C) 2006-2026, the MITRE Corporation. See section 9.4. "3rd-Party Licenses" in the documentation for full details.

Possible Messages

Key

Text

Severity

Disabled

check_privilege_drop

setuid(getuid()) call must be followed by a setuid(0) != -1 check.

None

False

discarded_return_with_entity

Return value of function discarded.

None

False

unhandled_return_value

Return value of function call not properly checked.

None

False

Options

allow_assignment_to_globals

allow_assignment_to_globals : bool = False

Whether assignment to global / static variables should be allowed. If set to false, an error will be reported if the returned value is assigned to a global variable and any call is performed before checking the return (i.e., some other routine could access the return value before checking it).
 

allow_assignment_to_variables_with_pointers

allow_assignment_to_variables_with_pointers : bool = True

Whether assignment to variables of which the address has been taken somewhere should be allowed. If set to false, an error will be reported if the return value is assigned to such a variable, to ensure that the return value is checked locally, before any access from outside is possible.
 

allowed_functions

allowed_functions : set[bauhaus.analysis.config.FunctionName] = {'memcpy', 'memmove', 'memset', 'strcat', 'strcpy', 'strncat', 'strncpy'}

Calls to these functions are ignored.
 

check_operators

check_operators : bool = False

Also check operator calls. Unused return values of assignment operators are only reported if given in function style syntax.
 

functions

functions

Type: dict[bauhaus.analysis.config.QualifiedName, bauhaus.ir.common.algorithms.matchers.Matcher]

Default:

{
   'ImpersonateNamedPipeClient': <bauhaus.rules.axivion.expressions.calls.unhandled_return_value.BinaryRelationAnyMatcher object at 0x7f6f1b83a0b0>
}
Allows to declare function names for which a check must exist. The check is expressed as an IR pattern.
 

known_check_functions

known_check_functions : set[bauhaus.analysis.config.FunctionName] = set()

Collection of functions which are known to test return values of functions under test.
 

report_references

report_references : bool = False

Report returned references. For operators, unused returned references are only reported if given in function style syntax.