Merge: argument-taint (call args / binary-expr operands)
ober
bbb9d1875b53cc456b4d9f9c6872d7e846c56135
--- a/lib/semgrep/scan.sls +++ b/lib/semgrep/scan.sls @@ -31826,6 +31826,36 @@ arg-text (metavariable-binding-text (cdr entry)))) (finding-metavars source)))))) + (def (simple-identifier-text? s) + (let* ([t (string-trim s)] [len (string-length t)]) + (and (> len 0) + (let loop ([i 0]) + (or (>= i len) + (and (identifier-char? (string-ref t i)) + (loop (+ i 1)))))))) + (def (original-bare-variable-source? + source-state + source-text) + (let ([finding (taint-state-finding source-state)]) + (and finding + (not (taint-state-side-effect? source-state)) + (equal? (taint-state-origin source-state) finding) + (simple-identifier-text? + (finding-text finding source-text))))) + (def (source-token-in-sink-arg? + source-state + sink + source-text) + (and (original-bare-variable-source? + source-state + source-text) + (let ([arg-text (direct-call-argument-text + sink + source-text)] + [st (finding-text + (taint-state-finding source-state) + source-text)]) + (and arg-text (string-contains-token? arg-text st))))) (def (line-indent line) (let ([len (string-length line)]) (let loop ([i 0]) @@ -31912,6 +31942,10 @@ source sink source-text) + (source-token-in-sink-arg? + source-state + sink + source-text) (and (taint-state-token? source-state) (source-token-in-sink/except? source @@ -32929,6 +32963,7 @@ sink source-text)) (source-base-of-sink-arg? source sink source-text) + (source-token-in-sink-arg? source-state sink source-text) (and (finding-range-contains? sink source) (not (finding-range-equal? sink source)) (echo-or-print-statement-sink? sink source-text) @@ -33168,7 +33203,13 @@ (metavariable-binding-text from-binding)) (field-source-taints-base-text? (metavariable-binding-text from-binding) - (finding-text source-finding source))))))) + (finding-text source-finding source)) + (and (original-bare-variable-source? + source-state + source) + (string-contains-token? + (metavariable-binding-text from-binding) + (finding-text source-finding source)))))))) (def (propagator-blocked-by-sanitizer? source-state from-finding --- a/src/semgrep/scan.ss +++ b/src/semgrep/scan.ss @@ -31775,6 +31775,28 @@ (metavariable-binding-text (cdr entry)))) (finding-metavars source)))))) +(def (simple-identifier-text? s) + (let* ([t (string-trim s)] + [len (string-length t)]) + (and (> len 0) + (let loop ([i 0]) + (or (>= i len) + (and (identifier-char? (string-ref t i)) + (loop (+ i 1)))))))) + +(def (original-bare-variable-source? source-state source-text) + (let ([finding (taint-state-finding source-state)]) + (and finding + (not (taint-state-side-effect? source-state)) + (equal? (taint-state-origin source-state) finding) + (simple-identifier-text? (finding-text finding source-text))))) + +(def (source-token-in-sink-arg? source-state sink source-text) + (and (original-bare-variable-source? source-state source-text) + (let ([arg-text (direct-call-argument-text sink source-text)] + [st (finding-text (taint-state-finding source-state) source-text)]) + (and arg-text (string-contains-token? arg-text st))))) + (def (line-indent line) (let ([len (string-length line)]) (let loop ([i 0]) @@ -31859,6 +31881,7 @@ sink source-text) (source-base-of-sink-arg? source sink source-text) + (source-token-in-sink-arg? source-state sink source-text) (and (taint-state-token? source-state) (source-token-in-sink/except? source @@ -32808,6 +32831,7 @@ (and (not (taint-state-token? source-state)) (direct-call-argument-source? source sink source-text)) (source-base-of-sink-arg? source sink source-text) + (source-token-in-sink-arg? source-state sink source-text) (and (finding-range-contains? sink source) (not (finding-range-equal? sink source)) (echo-or-print-statement-sink? sink source-text) @@ -33084,7 +33108,15 @@ ;; gates above keep this name-based reach within one method. (field-source-taints-base-text? (metavariable-binding-text from-binding) - (finding-text source-finding source))))))) + (finding-text source-finding source)) + ;; bare variable source used inside the RHS expression + ;; (`t = wrap(x)`, `w = v + x.getSomething()`): the assigned + ;; target carries the taint. Restricted to original tracked + ;; variables by original-bare-variable-source?. + (and (original-bare-variable-source? source-state source) + (string-contains-token? + (metavariable-binding-text from-binding) + (finding-text source-finding source)))))))) (def (propagator-blocked-by-sanitizer? source-state from-finding sanitizers source) (any? (lambda (sanitizer-state)