Skip to content

Precision: refute flows without a tainted origin and open recognise() to more proof shapes #98

Closed

Description

@SizzleUnrlsd

Two limits of the refutation pass found during reconnaissance. Investigate before committing to a design.

  • if origins and all(...): a flow with no tainted origin can never be refuted and is reported as a vulnerability with "no guard on the path to the sink". Measure how many findings of the regression corpus this concerns, then decide.
  • recognise() accepts four proof shapes (isdigit-like methods, Validator model, membership in a constant collection, equality to a constant). List the shapes seen in the corpus that it misses; add the ones that pay.
  • Each change is backed by a corpus finding that flips from vulnerability to refuted. Not met, see below.

Result (measured on the regression corpus, 2026-09-24)

The corpus has 66 reported taint findings (30 vulnerabilities, 36 hotspots). The original criterion is not met: no change to either point turns a corpus vulnerability into a refuted flow.

  • Flows without a tainted origin: 3 findings.
    • httpie client.py:114 ×2: the tainted values all lie on the redirect loop (prepared_request = response.next).
    • luigi contrib/lsf.py:263 ×1: the taint goes through a field, self.job_id = int(...).
    • Neither would be refuted by a fix. httpie has no proof and would at best become a hotspot; luigi would need origins traced through fields plus numeric reasoning.
  • Proof shapes recognise() misses: none that is general. The unproven guards are truthiness, os.path.isfile, len({...}) and ORM existence checks, and none of them proves anything. The two real proofs are project functions (healthchecks' _allow_redirect and check_signature). They are tracked in Precision: validators and sanitizers apply through project functions #134 and in enterprise enterprise-validators.

What was actually found. Precision was lost in the opposite direction. 17 of the 28 "guard does not prove the value safe" hotspots come from a guard that only reads another attribute of the object the flow reads, such as if request.method == 'POST': before request.POST[...]. That downgrades real vulnerabilities to MEDIUM. Each of the 17 was reviewed:

The rule itself is #135.

Activity

  1. SizzleUnrlsd commented on Sep 24, 2026

    @SizzleUnrlsd
    ContributorAuthor

    Investigation complete; the result is in the issue text. The original criterion (a corpus vulnerability turning into a refuted flow) was not met. What the measurement found, a guard reading another attribute of the object, is fixed by #135 (PR #136), after the model fixes #128, #130 and #132. What remains is tracked: project validators and sanitizers through summaries, #134.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions