label, requires
Labels let one taint rule track several kinds of taint, and report a sink only for some of them, or for a combination. A label is a name given to the taint that a source produces:
pattern-sources:
- label: USER_INPUT
pattern: request.args.get(...)A source without label produces taint with the label __SOURCE__.
requires takes an expression over labels, built with and, or, not and parentheses. It is true for a piece of tainted data when the data carries the labels the expression asks for:
- on a sink, a finding is reported only for tainted data for which the expression is true. A sink without
requiresreports the taint labeled__SOURCE__, so in a rule whose sources all have labels, every sink needsrequires; - on a source, the source applies only to data for which the expression is true. Such a source adds its label to data that already carries others, to mark a later stage of the flow;
- on a propagator, only the taint for which the expression is true is passed on.
A propagator can also relabel the taint it passes on. With label, the taint receives that label instead of its own. With replace-labels, a list of labels, only the taint that carries one of them is relabeled; other taint is passed on unchanged.
Examples
A path built from user input
The second source applies only to a path joined from data that carries the label USER, and the sink requires the label PATH. User input opened directly, or a path built from constants, is not reported.
rules: - id: user-path mode: taint pattern-sources: - label: USER pattern: request.args.get(...) - label: PATH requires: USER pattern: os.path.join(...) pattern-sinks: - requires: PATH pattern: open(...) message: a path built from user input is opened languages: [python] severity: ERRORimport osdef download(): name = request.args.get("file") # ruleid: user-path open(os.path.join("/srv/files", name)) # ok: user-path open(name) # ok: user-path open(os.path.join("/srv/files", "index.html"))$ opengrep test .
1/1: ✓ All tests passed
No tests for fixes found.Relabeling in a propagator
The propagator turns RAW taint into ESCAPED taint, and passes the TRUSTED taint on unchanged.
rules: - id: relabel mode: taint pattern-sources: - label: RAW pattern: request.args.get(...) - label: TRUSTED pattern: settings.get(...) pattern-propagators: - pattern: $TO.update($FROM) from: $FROM to: $TO label: ESCAPED replace-labels: [RAW] pattern-sinks: - requires: ESCAPED pattern: render_escaped(...) - requires: RAW pattern: render_raw(...) message: data reaches a template of the wrong kind languages: [python] severity: ERRORuser = request.args.get("name")config = settings.get("name")context = {}context.update(user)# ruleid: relabelrender_escaped(context)# ok: relabelrender_raw(context)defaults = {}defaults.update(config)# ok: relabelrender_escaped(defaults)$ opengrep test .
1/1: ✓ All tests passed
No tests for fixes found.