Main Content

Tainted source used with sensitive function

Data obtained from an untrusted source is passed to user-defined sensitive function

Since R2023b

Description

This defect occurs when data obtained from an untrusted source is passed to a sensitive function.

Untrusted sources include data obtained from:

For this checker, you have to explicitly define functions that must be considered as sensitive. See Extend Checker.

Risk

If you pass untrusted data to a sensitive function without validating and cleaning up (sanitizing) the data, an attacker can pass malicious data to perform tasks other than what the function is supposed to do. Such attacks can gain access to secured resources, or trigger data corruption or system failures.

Fix

Perform appropriate validation and sanitization on untrusted data before passing the data to a sensitive function. To prevent the checker from flagging sanitized data, specify your sanitization function to the analysis.

Extend Checker

For the checker to report defects as expected, you have to specify the following in a checker definition file:

  • Untrusted sources (optional)

  • Sensitive function (mandatory)

  • Sanitization function (mandatory)

Suppose that you want to specify the following information:

  • The return value of the function getResponse() is untrusted.

  • The function changeSystemState() is a sensitive function that is vulnerable to attacks via its n_sensitive-th argument.

  • The function ensureSafeResponse() takes a pointer input as its n_sanitize-th argument and sanitizes the data that the input points to.

To create a checker with this information:

  1. In a file with extension .dl, add this code:

    .include "models/interfaces/tainted_source_use_custom.dl"
    .include "pql/checkers/tainted_source_use_custom_impl.dl"
    
    .comp checkerConfig : CustomTainted {
        Basic.taintSource("getResponse",$OutReturnValue(),"Data from getResponse() is tainted.").
        Basic.sensitive("changeSystemState",$InParameterValue(n_sensitive-1),"changeSystemState() must not use tainted data.").
        Basic.sanitizing("ensureSafeResponse",$OutParameterDeref(n_sanitize-1)).
    }
    
    .init customTaintedChecker = tainted_source_use_custom<checkerConfig>

    If n_sensitive and n_sanitize are both 1 (that is, the first parameters of each function are the parameters of interest), then the statements become:

    .include "models/interfaces/tainted_source_use_custom.dl"
    .include "pql/checkers/tainted_source_use_custom_impl.dl"
    
    .comp checkerConfig : CustomTainted {
        Basic.taintSource("getResponse",$OutReturnValue(),"Data from getResponse() is tainted.").
        Basic.sensitive("changeSystemState",$InParameterValue(0),"changeSystemState() must not use tainted data.").
        Basic.sanitizing("ensureSafeResponse",$OutParameterDeref(0)).
    }
    
    .init customTaintedChecker = tainted_source_use_custom<checkerConfig>

  2. Specify this file using the option -create-checkers. For instance, if the file is named taintSourcesAndSinks.dl, use the analysis option when enabling the checker:

    -create-checkers taintSourcesAndSinks.dl -checkers TAINTED_SOURCE_USE_CUSTOM

Examples

expand all

Create a checker by specifying the following information:

  • The return value of the function getResponse() is untrusted.

  • The function changeSystemState() is a sensitive function that is vulnerable to attacks via its first argument.

You specify the information in a checker definition file (with extension .dl) written as follows:

.include "models/interfaces/tainted_source_use_custom.dl"
.include "pql/checkers/tainted_source_use_custom_impl.dl"

.comp checkerConfig : CustomTainted {
    Basic.taintSource("getResponse",$OutReturnValue(),"Data from getResponse() is tainted.").
    Basic.sensitive("changeSystemState",$InParameterValue(0),"changeSystemState() must not use tainted data.").
}

.init customTaintedChecker = tainted_source_use_custom<checkerConfig>

If you specify the checker definition file as argument to the option -create-checkers and also enable the checker Tainted source used with sensitive function, the checker flags cases where there is a data flow from the return value of the getResponse() function to the first argument of the changeSystemState() function.

The simplest example of such a data flow looks like this:

extern int getResponse(void);
extern void changeSystemState(int); 

void main() {
    int response = getResponse();
    changeSystemState(response);
}

Correction — Sanitize Data Before Passing to Validation Function

You can sanitize data obtained from untrusted sources by using a sanitization function. The sanitization function can check for unsafe data and remove or clean up the data as needed.

In the preceding example, you can add a line in the checkers definition file specifying that the function ensureSafeResponse() takes a pointer input and sanitizes the data that the input points to. The modified checker definition file is shown below.

.include "models/interfaces/tainted_source_use_custom.dl"
.include "pql/checkers/tainted_source_use_custom_impl.dl"

.comp checkerConfig : CustomTainted {
    Basic.taintSource("getResponse",$OutReturnValue(),"Data from getResponse() is tainted.").
    Basic.sensitive("changeSystemState",$InParameterValue(0),"changeSystemState() must not use tainted data.").
    Basic.sanitizing("ensureSafeResponse",$OutParameterDeref(0)).
}

.init customTaintedChecker = tainted_source_use_custom<checkerConfig>

If a call to the ensureSafeResponse() function breaks the data flow from the untrusted source to the sensitive function, the checker no longer reports a defect. The corrected code might look like the following:

extern int getResponse(void);
extern void ensureSafeResponse(int*); 
extern void changeSystemState(int); 

void main() {
    int response = getResponse();
    ensureSafeResponse(&response);
    changeSystemState(response);
}

Result Information

Group: Tainted Data
Language: C | C++
Default: Off
Command-Line Syntax: TAINTED_SOURCE_USE_CUSTOM
Impact: High

Version History

Introduced in R2023b