Taint analysis

Field Description
source Specifies the input or expression where tracking begins.
sanitizer Specifies an operation that this rule treats as stopping taint propagation. The engine does not automatically prove that the function's implementation is safe.
sink Specifies where to report a finding when a tracked value reaches that location.
method Selects calls by method name in a sanitizer or sink. If the rule must distinguish argument positions or call forms, specify those conditions as well.

The following example detects a particular flow of input through Java code.

  • The language is Java.
  • The rule reports a finding when the return value of getInput() is passed as the first argument to unsafeSink and the second argument is "unsafe_option".
  • The example assumes that sanitizerValue processes the input appropriately for this use and treats its return value as untainted. When writing a real rule, verify that this assumption matches the function's behavior.
yaml
rule:
  taint:
    source:
      pattern: getInput()
    sanitizer:
      method:
        - sanitizerValue
    sink:
      pattern: unsafeSink($IN, "unsafe_option")

Only the call in unsafe() below meets this rule's detection conditions. The absence of findings for the other calls means that they do not meet these conditions; it does not guarantee that the code is safe overall. The implementations of the example functions are omitted.

java
public class TaintExample {
    public void unsafe() {
        String userInput = getInput();
        unsafeSink(userInput, "unsafe_option"); // Reported: the input and option match
    }

    public void safe_1() {
        String userInput = getInput();
        unsafeSink(userInput, "safe_option"); // Not reported: the second argument does not match
    }

    public void safe_2() {
        String userInput = getInput();
        userInput = sanitizerValue(userInput);
        unsafeSink(userInput,"unsafe_option"); // Not reported: uses the sanitizer's return value
    }

    public void safe_3() {
        String userInput = getInput();
        unsafeSink("something", userInput); // Not reported: the input is not the first argument
    }
}