From 2fb156eb524ea64b36df86ef4cbf1c29e4a36071 Mon Sep 17 00:00:00 2001 From: David Baker Effendi Date: Wed, 26 Aug 2026 11:17:02 +0200 Subject: [PATCH 1/3] Preregister the benchmark-controlled taint-modeling matrix (#15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Twelve modeling templates in six categories — declared sources and sinks, propagators, sanitizers, opaque summaries, framework entry points, and persistence boundaries — each with one positive and one minimally different negative, fixed before any modeling fixture, model file, or run exists. The challenge tier's amendment contract applies verbatim. Each model is defined analyzer-neutrally as entity identity, role, and binding semantics, so the four adapters encode the same declaration in their own native surfaces. Per-tool capability partitions are preregistered from the pinned tools: Semgrep CE 1.174.0 and CodeQL 2.26.3 were probed directly, Joern's flow-semantics surface from a local distribution, and everything unverifiable is recorded as unsupported until shown otherwise. Modeling is a new score tier rather than a fold into core, because it asks a different question from the kernels. Schema groundwork is additive only: score_tier gains "modeling" in the case and freeze schemas and in the result tier ordering. No new negative mechanism was needed — the enum's existing "sanitizer" value already means what the sketch's "sanitizer-kill" would have. No fixtures, no cases, no model files, no runs, no adapter changes. Co-Authored-By: Claude Fable 5 --- docs/milestones.md | 15 + docs/modeling-matrix.md | 1141 ++++++++++++++++++++++++++++++++++++ docs/scoring.md | 11 + schemas/case.schema.json | 4 +- schemas/freeze.schema.json | 2 +- src/main.rs | 12 +- 6 files changed, 1181 insertions(+), 4 deletions(-) create mode 100644 docs/modeling-matrix.md diff --git a/docs/milestones.md b/docs/milestones.md index 831358a..07e398c 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -192,6 +192,21 @@ Add balanced categories for sources and sinks, propagators, sanitizers, opaque library summaries, framework entry points, and persistence boundaries. Publish benchmark-controlled and tool-native model profiles separately. +### M3 begins: the preregistered modeling matrix + +M3 opens with the [taint-modeling matrix](modeling-matrix.md), preregistered +before any modeling fixture, model file, or run exists, under the same amendment +contract as the challenge tier. It fixes twelve templates in those six +categories — one positive and one minimally different negative each, 24 +assertions per language — for Java, JavaScript, and Python, defines each model in +analyzer-neutral terms so the four adapters encode the same declaration in their +own native surfaces, and preregisters per-tool capability partitions so that a +category a tool cannot activate is recorded as `unsupported` in advance rather +than discovered as a failure. Unlike the challenge tier, these templates are +**not** `core`: `score_tier` gains `modeling`, and modeling assertions have their +own scorecards and never enter any language's core denominator. Issue #16's +tool-native profiles build on the same category taxonomy and supply no models. + ## M4: real-project confirmation Add a small, pinned, manually reviewed corpus drawn from executable or diff --git a/docs/modeling-matrix.md b/docs/modeling-matrix.md new file mode 100644 index 0000000..d0b7c6a --- /dev/null +++ b/docs/modeling-matrix.md @@ -0,0 +1,1141 @@ +# Benchmark-controlled taint-modeling matrix + +This document is the **preregistration artifact** for twelve taint-modeling +templates, in six balanced categories. It merges before any modeling fixture +exists, before any model file is authored for any analyzer, and before any +number derived from them is published. Its purpose is to fix the definitions +while the outcomes are still unknown. + +Nothing in this document is a result. It is a contract about what will be +measured, stated in advance so that the measurement cannot later be shaped +around what the measurement produced. + +It closes issue #15 and opens milestone M3. + +## What this matrix tests + +The propagation kernels — the sixteen classic templates and the thirteen +[challenge templates](challenge-tier.md) — test whether an engine can **follow +flow it can see**. Every construct in them is in the language's own manual, and +an engine with no models at all can score full marks. + +This matrix tests something else: whether an engine can **be told things**. +Given equivalent benchmark-supplied models — a source it did not know, a +propagator whose body it cannot read, a sanitizer, a procedure summary, an entry +point, a persistence boundary — does the analysis *activate* them, and does +activation produce the *modeled semantics* rather than something adjacent to it? + +Modeling correctness is a different competence from propagation correctness. +An engine can be excellent at one and absent at the other, and pooling the two +would hide exactly that. So the modeling matrix is scored on its own tier and is +never pooled with any core kernel. + +Two framings are worth stating before any run, because both will otherwise be +misread: + +- **A high modeling score is not a high propagation score.** An engine that + activates every model but follows no dispatch is a good modeling substrate and + a weak analysis. The two scorecards answer different questions and are never + added together. +- **A low modeling score is frequently a product decision, not a defect.** A + standalone CLI that deliberately ships no external-model catalog will decline + whole categories here. That decline is recorded as `unsupported` with a + retained reason, exactly as [the scoring contract](scoring.md) requires, and it + is not a wrong answer. + +## Governance + +This section is the load-bearing part of the document. The template definitions +are only worth as much as the discipline around them. + +### Preregistration and immutability + +**The amendment contract of the [challenge tier](challenge-tier.md#preregistration-and-immutability) +applies to this document verbatim.** Restated so that it cannot be lost in a +cross-reference: this document merges before any modeling fixture is authored. +From the moment the first analyzer executes against the first modeling fixture, +the twelve template definitions below — semantic intent, model declaration, +positive shape, negative shape, negative mechanism, and the per-tool capability +partition — are **immutable**. + +A defect discovered after that point is corrected by a documented **amendment**, +never by a silent edit. An amendment: + +1. appears in a dated `## Amendments` section at the foot of this document; +2. states what changed, why, and which template IDs and languages it touches; +3. states which already-published freezes it invalidates, if any; +4. is a separate commit from any fixture, model, or result change. + +A template that turns out to be badly posed is **retired by amendment**, not +rewritten. Its `template_id` is never reused for different semantics. + +The per-tool capability partition tables carry the same immutability, and for +the same reason. A partition decided after a run is not a capability +classification, it is a result being relabelled. If a tool turns out to express +a category the tables here call unsupported, that is an amendment with a date on +it, and the run that revealed it is reported as the run that revealed it. + +The challenge tier does not need to change for this document to land, and it is +not changed by it. Nothing here amends `docs/challenge-tier.md`. + +### Fairness constraint: standard library only + +Modeling fixtures use **only the target language's standard library**. No +frameworks, no third-party dependencies, no build-tool plugins. This is the same +rule the challenge tier states, and here it is doing more work than usual, so it +is worth spelling out why it does not contradict itself. + +The challenge tier excludes frameworks because a framework fixture would measure +whether the analyzer ships a model for that framework. This matrix measures +model *activation* — and it does so by supplying the model itself, to every tool +equally, for code that is entirely inside the fixture. The +`Config.fetchRemote()` of template 1 is not a real remote call and does not +pretend to be one; it is an ordinary fixture method whose *only* claim to being +a source is that the benchmark declared it so. That is the whole point. If the +fixture used a real framework entry point, an engine with a shipped model for it +would pass without ever reading the benchmark's model, and the assertion would +stop being about activation. + +Framework-shipped coverage is a genuine and separate product question. It is +issue #16's `tool-native` profile, and it is out of scope here. + +### Lineage + +The category taxonomy — sources and sinks, propagators, sanitizers, opaque +library summaries, framework entry points, persistence boundaries — is the one +[M3 recorded in the milestones](milestones.md#m3-taint-modeling) before any of +this was designed, and it is the standard decomposition used by every +configurable taint engine: CodeQL's models-as-data rows (`sourceModel`, +`sinkModel`, `summaryModel`, `barrierModel`, `neutralModel`), Joern's flow +semantics, Semgrep's `pattern-sources` / `pattern-sinks` / +`pattern-propagators` / `pattern-sanitizers`, and Bifrost's RQLP endpoint sets. +The taxonomy is not invented here; what is invented here is a balanced, +polarity-paired way to *test* it. + +Fixtures themselves are original authored code — `fixture_provenance.kind` is +`authored`, origin `DataFlowBench`, revision `m3-modeling-`, license +`MIT`, per [fixture provenance](fixture-provenance.md). + +### Initial languages + +Java, JavaScript, and Python — the floor issue #15 sets, and the three languages +whose kernels are most mature. Per-language sketches for those three are given +with every template below. + +The remaining ten languages are **deliberately not classified in this +document**. The challenge tier classified all thirteen up front because its +constructs are language features, and a language whose cells were classified +later would have had its denominator decided by implementation convenience. +Modeling applicability is a different question: it depends on each analyzer's +declaration surface *for that language*, which is a per-adapter fact, not a +per-language one. Those cells are decided by a later applicability pass with the +same three-way vocabulary the +[applicability matrix](applicability-matrix.md#classification-vocabulary) +already defines. Until that pass merges, no language outside Java, JavaScript, +and Python has a modeling denominator at all — which is different from having a +zero. + +## Population mechanics + +### A new score tier + +`score_tier` gains the value **`modeling`**. This is the opposite of the +challenge tier's decision, and the difference is not arbitrary. Challenge +templates fold into the core because they ask the core's question — can the +engine follow this flow — one notch harder. Modeling templates ask a different +question, so a denominator that mixed them would mean nothing. + +The consequences, stated plainly: + +- Modeling cases have **their own scorecards**, per language and per adapter. +- They are **never** in a core denominator, in any language, in any release. +- They are never pooled with `core`, `language-extension`, `calibration`, or + `real-project` populations. +- No headline number combines a modeling score with a kernel score. +- Adding the enum value does not touch any existing freeze. Freeze validation is + manifest-scoped: a manifest binds the cases and reports of its own release, and + an added enum value changes nothing a v0.3.0 or v0.4.0 manifest asserts. + +### Identifiers + +- Templates: `dfb-template-model--`. +- Cases: `dfb-taint--model--`. + +Both follow the corpus conventions already enforced by the case schema's `id` +and `template_id` patterns. + +### Model profile + +Every case in this matrix carries `model_profile: "benchmark-controlled"`. That +is not a formality — **this whole matrix is the benchmark-controlled modeling +instrument.** The profile field says the models came from DataFlowBench and were +supplied equally to every tool. + +Its counterpart is issue #16's `tool-native` profile, which evaluates the models +a tool ships on its own. #16 builds on this document's category taxonomy — it +reports tool-native coverage in the same six categories, so the two can be read +side by side — but it supplies **no models**, and it is **out of scope here**. +The two profiles are never combined, as +[the scoring contract](scoring.md#model-profiles) already requires. + +### Balanced pairs, for the reason the blind baseline gives + +Each of the twelve templates contributes exactly one positive and one minimally +different negative case per language — **24 assertions per language** where all +twelve cells apply. A modeling-population validator enforces the balance; it is +specified below and implemented when the first fixtures land. + +The pairing is balanced for exactly the reason +[the scoring contract's blind-baseline section](scoring.md#balanced-pairs-and-the-blind-baseline) +gives for the kernels, and the hazard is sharper here. On the kernels, an engine +that cannot see a construct but answers anyway banks one free true negative per +pair. On this matrix, an engine that **ignores the model entirely** does the +same thing: it answers "no flow" on both cells of every category it did not +activate, collects half the assertions, and looks like it partially supports +modeling. Balanced pairs make that floor visible; per-category +true-positive/false-positive rates, not the raw correct count, are what +distinguish activation from silence. + +There is a second, modeling-specific form of the same hazard, and it decides +several partition cells below: an engine whose **unmodeled-call default is +optimistic** will carry taint through a declared propagator whether or not it +read the declaration. Its positive cell is then correct for a reason that has +nothing to do with the model. This matrix therefore requires that, for any +category to be scored for a tool, the tool's modeling configuration must make +the model load-bearing — the default must not already decide the cell. See +[the load-bearing-model requirement](#the-load-bearing-model-requirement). + +## The model declaration language + +Every template below defines its model in **analyzer-neutral** terms, in exactly +three parts. This vocabulary is the equivalence contract's unit of comparison: +two adapters encode the *same* declaration when all three parts agree. + +**Entity identity.** What the declaration binds to, as a +type-plus-member-plus-position triple: the declaring type (or module), the +member name, and — where the role needs it — a parameter position, counted from +**0** for the first declared parameter, with the receiver excluded and the +return value written as `return`. Identity binding is always by this triple, +never by name shape and never by a substring: `Audit.record` and `Audit.discard` +are different entities, and a model for one says nothing about the other. Half +the negatives in this matrix exist to prove that. + +**Role.** Exactly one of: + +| Role | Meaning | +| --- | --- | +| `source` | the named entity's bound position produces tainted data | +| `sink` | tainted data arriving at the named entity's bound position is a finding | +| `propagator` | taint at the named input position appears at the named output position; the entity's body is irrelevant | +| `sanitizer` | taint arriving at the named input position does not leave the entity at any position | +| `summary` | a propagator for an entity whose body the contract says must be ignored even when it is present | +| `entry-point` | the named entity is an analysis root that is never called from the fixture; the named parameter position is tainted on entry | +| `store-write` | the named entity writes its input position into the named store, under a key given by another position | +| `store-read` | the named entity reads from the named store under a key given by a position, and returns it | + +**Binding semantics.** How the role's positions attach: which position is the +input, which is the output, and — for `store-write` / `store-read` — which +store identity the pair shares. Written throughout as `in: `, +`out: `, and `store: `. + +`propagator` and `summary` are the same mechanism with different obligations. +A `propagator` model is a *permission* to skip a body the engine may also +choose to read. A `summary` model is an *instruction*: the body is present in +the fixture (fixtures are self-contained and stdlib-only), and the contract says +the analysis must produce the summarized semantics whether or not it read it. +Category O's negatives are what make the difference observable, because there the +body and the summary disagree. + +## The twelve templates + +Six categories of two. Each template gives its semantic intent, its model +declaration, its positive and negative shapes with the negative mechanism, its +`expected_analysis_capability.kind`, and sketches for Java, JavaScript, and +Python. + +Every negative mechanism used below is drawn from the enum the case schema +already carries. No new mechanism is introduced; see +[metadata groundwork](#metadata-groundwork) for why the `sanitizer-kill` value +the design sketch proposed was **not** added. + +--- + +### Category S — declared sources and sinks + +The floor of the whole matrix. If a tool cannot be told "this method is a +source", nothing else in this document can be asked of it. Both templates are +one-hop and involve no interesting propagation at all: whatever an engine scores +here is a statement about model binding, not about analysis. + +#### 1. `dfb-template-model-declared-source` + +**Semantic intent.** A value enters the flow from a benchmark-declared source +API that is *not* `dfb_source`. The fixture contains no other indication that the +value is tainted; the declaration is the only reason it is. + +**Model declaration.** + +- Entity identity: type `Config`, member `fetchRemote`, position `return`. +- Role: `source`. +- Binding: `out: return`. + +**Positive.** `Config.fetchRemote()` returns a value that reaches `dfb_sink` +directly. + +**Negative.** The identical flow reads from `Config.fetchLocal()`, a sibling +method on the same type with the same signature and an equally opaque-looking +body, which is **not** declared. `negative_mechanism: unrelated-value`. + +Both methods return a constant string in the fixture, so an engine that reads +their bodies learns nothing that distinguishes them. Only the declaration does. + +**Capability kind.** `declared-source-activation`. + +**Sketches.** + +- Java — `class Config { static String fetchRemote() { return "r"; } static + String fetchLocal() { return "l"; } }`, then `dfb_sink(Config.fetchRemote());`. +- JavaScript — a module-level `const Config = { fetchRemote() { return "r"; }, + fetchLocal() { return "l"; } };`, then `dfb_sink(Config.fetchRemote());`. +- Python — a module `config.py` with `def fetch_remote(): return "r"` and + `def fetch_local(): return "l"`. + +#### 2. `dfb-template-model-declared-sink` + +**Semantic intent.** The mirror of template 1. Taint from `dfb_source()` reaches +a benchmark-declared sink API that is not `dfb_sink`. + +**Model declaration.** + +- Entity identity: type `Audit`, member `record`, position `0`. +- Role: `sink`. +- Binding: `in: 0`. + +**Positive.** `Audit.record(dfb_source())`. + +**Negative.** `Audit.discard(dfb_source())` — an undeclared sibling with the +same signature. `negative_mechanism: unrelated-value`. + +**Capability kind.** `declared-sink-activation`. + +**Sketches.** Structurally identical in the three languages: a two-method +`Audit` type (class, object literal, module) whose methods both accept one +string and both drop it. + +--- + +### Category P — declared propagators + +The category the whole matrix turns on, because it is where "the engine +activated the model" and "the engine would have said this anyway" are hardest to +tell apart. Both templates are constructed so that the two are distinguishable, +and the construction is stated here rather than left to the fixtures. + +#### 3. `dfb-template-model-opaque-propagator` + +**Semantic intent.** Taint passes through a helper whose body the analyzer must +**not** need to read, because it demonstrably cannot. The declaration is the +only route from the helper's argument to its result. + +**The opaque body shape, and the evidence for choosing it.** The helper's body +routes its argument through a **reflective self-dispatch resolved from a +run-time string** — the construct the challenge tier calls +`dfb-template-chal-reflective-invocation`. That construct is chosen because the +v0.4.0 freeze already establishes, across four engines and three languages, that +none of them follows it. + +In the v0.4.0 bound evidence — freeze manifest `reports/freeze.json`, benchmark +revision `306211a` (tag `v0.4.0`), documented in +[`releases/v0.4.0.md`](releases/v0.4.0.md) — the twelve positive cells of +`dfb-template-chal-reflective-invocation` across Java, JavaScript, and Python +contain **zero `reached` outcomes**: + +| Analyzer | Java | JavaScript | Python | +| --- | --- | --- | --- | +| Bifrost v0.10.6 | `inconclusive` | `inconclusive` | `inconclusive` | +| CodeQL 2.26.3 | `not-reached` | `not-reached` | `not-reached` | +| Joern 4.0.610 | `not-reached` | `not-reached` | `not-reached` | +| Semgrep CE 1.174.0 | `unsupported` | `unsupported` | `unsupported` | + +Bound reports: `reports/{bifrost,codeql,joern,semgrep}-{java,javascript,python}-kernel.json`. +Stated precisely, because the four cells mean four different things: CodeQL and +Joern **definitively answer `not-reached`** in all six of their cells; Bifrost +reports **incomplete analysis** in all three of its; Semgrep **declines by +declared capability** in all three of its, decided from case metadata before the +scan. No engine's `witness_checkpoints` array is non-empty for any of the twelve. +The property this template needs is the weaker and better-supported one: *no +engine reaches the sink through this body on its own*. That is true in twelve of +twelve cells, and — as [`releases/v0.4.0.md`](releases/v0.4.0.md) records +independently for CodeQL — it holds across all eleven languages that have a +reflective-invocation fixture, with not one `reached` anywhere in the freeze. + +This is the entire reason the template is assertable. Its positive cell can only +be `reached` if the model was activated. + +**Model declaration.** + +- Entity identity: type `Opaque`, member `carry`, positions `0` and `return`. +- Role: `propagator`. +- Binding: `in: 0`, `out: return`. + +**Positive.** `dfb_sink(Opaque.carry(dfb_source()))`. + +**Negative.** `Opaque.block(dfb_source())` — a sibling on the same type, with an +identical reflective body, which is declared as **not** propagating (an explicit +no-flow declaration where the tool has one; otherwise simply undeclared, which +the partition records per tool). +`negative_mechanism: call-context-separation`. + +The negative is what catches an engine that treats *any* declared type as +wholly modeled, or that binds a declaration to a type rather than to a member. + +**Capability kind.** `opaque-propagator-activation`. + +**Sketches.** The three languages express the same opacity through their own +reflective facility, and the divergence from the core kernel's JavaScript +fixture is deliberate and recorded here in advance: + +- Java — `static String carry(String v) { return (String) + Opaque.class.getMethod(name, String.class).invoke(null, v); }` with `name` + bound from a local string constant to a private identity method. +- Python — `def carry(v): return getattr(_impl, name)(v)`, `name` a local + string constant. +- JavaScript — `Reflect.get(_impl, name).apply(null, [v])`. The core kernel's + JavaScript `reflective-invocation` fixture uses a computed-key call + (`handlers[name](...)`), which is structurally closer to a dispatch table. + This matrix uses `Reflect` so that the opacity is the same shape in all three + languages. That is a modeling-matrix fixture decision, it changes nothing about + the core fixture, and it is stated here so it is not later mistaken for drift. + +#### 4. `dfb-template-model-propagator-position` + +**Semantic intent.** Positional fidelity of model application. The declaration +names **parameter 1 only** (the second declared parameter); an engine that +applies the model to any tainted argument, rather than to the declared position, +fails the negative. + +**Model declaration.** + +- Entity identity: type `Opaque`, member `select`, positions `1` and `return`. +- Role: `propagator`. +- Binding: `in: 1`, `out: return`. + +**Positive.** `dfb_sink(Opaque.select("clean", dfb_source()))` — taint at the +declared position 1. + +**Negative.** `dfb_sink(Opaque.select(dfb_source(), "clean"))` — the identical +call with taint at the undeclared position 0. +`negative_mechanism: call-context-separation`, following the precedent the core +kernel's `dfb-template-argument-position-separation` already sets for +position-distinguished negatives. + +`select` carries the same reflective body as `carry`, for the same reason. + +**Capability kind.** `positional-propagator-activation`. + +**Sketches.** A two-parameter static method / module function / object method in +each language, with the reflective body of template 3. + +--- + +### Category Z — declared sanitizers + +The only category whose *negative* is the modeled one. Everywhere else the model +creates a flow; here it removes one. That inversion is the point: an engine can +fake source and propagator activation by being optimistic, but it cannot fake +sanitizer activation by being optimistic. + +#### 5. `dfb-template-model-sanitizer-kill` + +**Semantic intent.** A benchmark-declared sanitizer suppresses a flow that +otherwise exists. + +**Model declaration.** + +- Entity identity: type `Clean`, member `scrub`, position `0`. +- Role: `sanitizer`. +- Binding: `in: 0`. + +**Positive.** `dfb_sink(dfb_source())` — the flow, direct, with no sanitizer +anywhere on the path. The positive cell of this pair deliberately asks nothing +of the model; it establishes that the flow exists at all, so that the negative's +absence means something. + +**Negative.** The **same** flow routed through `Clean.scrub`: +`dfb_sink(Clean.scrub(dfb_source()))`. The declared sanitizer must suppress the +finding. `negative_mechanism: sanitizer`. + +`scrub`'s body is the identity function. That is deliberate. A sanitizer whose +body actually sanitizes would let an engine reach the right answer by reading +the body, and the assertion would stop being about the model. + +**Capability kind.** `declared-sanitizer-activation`. + +**Sketches.** `class Clean { static String scrub(String v) { return v; } }`, and +its object-literal and module equivalents. + +#### 6. `dfb-template-model-sanitizer-selectivity` + +**Semantic intent.** Sanitizer models bind by entity identity, not by name +shape. Two sanitizer-*looking* calls exist; only one is declared. + +**Model declaration.** + +- Entity identity: type `Clean`, member `scrub`, position `0`. +- Role: `sanitizer`. +- Binding: `in: 0`. + +The sibling `Clean.sanitize` — same type, same signature, same identity body, a +name at least as sanitizer-shaped — is **not** declared. + +**Positive.** `dfb_sink(Clean.sanitize(dfb_source()))`. The flow passes through +the *undeclared* sanitizer-looking call and must still be reported. + +**Negative.** `dfb_sink(Clean.scrub(dfb_source()))`, through the declared one, +suppressed. `negative_mechanism: sanitizer`. + +This is the pair that catches heuristic name matching — an engine that treats +anything called `sanitize`, `escape`, or `clean` as a barrier fails the +positive, and it fails it for a reason worth publishing. + +**Capability kind.** `sanitizer-identity-binding`. + +**Sketches.** One `Clean` type with two identity methods in each language. + +--- + +### Category O — opaque procedure summaries + +Where category P declares "you may skip this body", category O declares "ignore +this body; these are the semantics". The distinction is only observable when the +two disagree, and template 8 is built so they do. + +This category generalizes the existing Java calibration case +**`dfb-taint-java-modeled-external`** +(`cases/taint/java/modeled-external-unsupported/case.json`, template +`dfb-template-modeled-external-summary`), whose `ThirdPartyBridge.passThrough` +is exactly an `in: 0, out: return` summary and whose retained Bifrost outcome is +`unsupported` with the reason *"Bifrost's standalone policy CLI has no ambient +external semantic-model catalog; this requires an embedding with explicit +activation."* + +**That calibration case stays calibration and is not selected into this +matrix.** It is `score_tier: "calibration"`, it is bound into published freezes +at that tier, and re-tiering it would silently change what those freezes assert. +The modeling matrix authors its own cases; the calibration case remains what it +has always been — the adapter-plumbing precedent that showed this category +needed a tier of its own. + +#### 7. `dfb-template-model-summary-through` + +**Semantic intent.** An **external-shaped** procedure carries flow per a supplied +summary. External-shaped means: declared in a separate fixture file, named as a +boundary, and covered by a contract clause saying its body must be ignored. + +**Model declaration.** + +- Entity identity: type `Bridge`, member `pass`, positions `0` and `return`. +- Role: `summary`. +- Binding: `in: 0`, `out: return`. + +**Positive.** `dfb_sink(Bridge.pass(dfb_source()))`, with `Bridge` in its own +fixture file. + +**Negative.** `dfb_sink(Bridge.hold(dfb_source()))`, where the sibling `hold` +carries an explicit **no-flow** summary. `negative_mechanism: +call-context-separation`. + +Both bodies are the identity function. So the *bodies* say flow in both cells and +the *summaries* disagree with each other: an engine that reads bodies reports +both, an engine that activates summaries reports one, and an engine that does +neither reports neither. The three are distinguishable, which is the property a +summary template needs and the reason the bodies are identical rather than +convenient. + +**Capability kind.** `procedure-summary-activation`. + +**Sketches.** A second fixture file per case — `Bridge.java`, `bridge.js`, +`bridge.py` — containing two one-line identity methods. + +#### 8. `dfb-template-model-summary-field` + +**Semantic intent.** A **store-through** summary: the declaration says the +procedure writes its first argument into a named field of its second, and the +sink reads that field. The summary's output position is a heap location, not a +return value. + +**Model declaration.** + +- Entity identity: type `Bridge`, member `deposit`, positions `0` and `1`. +- Role: `summary`. +- Binding: `in: 0`, `out: 1.payload`. + +**Positive.** `Bridge.deposit(dfb_source(), box); dfb_sink(box.payload);`. + +**Negative.** The identical call, with the sink reading a **sibling field** of +the same object: `dfb_sink(box.spare);`. `negative_mechanism: field-separation`. + +`deposit`'s body writes nothing at all, so the field's contents come from the +summary or from nowhere. + +**Capability kind.** `store-through-summary-activation`. + +**Sketches.** + +- Java — `class Box { String payload; String spare; }` and + `static void deposit(String v, Box b) { }`. +- JavaScript — `const box = { payload: "", spare: "" };`. +- Python — a two-attribute class, or a module-level object with two attributes. + +--- + +### Category E — framework entry points + +The category with the sharpest three-way distinction, and the one most likely to +be misread as a failure. A handler that nothing calls is dead code to an engine +without entry-point synthesis. Declining it is correct behavior. + +**Stated before any run:** an analyzer with no entry-point synthesis must report +`unsupported` here, **not** `not-reached`. `not-reached` on this category is a +claim that the analysis ran with the declared root and found nothing, which is a +different and much stronger claim than "I cannot make a root out of a +declaration". The per-tool partition below decides which of the two a tool is +entitled to say, and it decides it before the tool runs. + +#### 9. `dfb-template-model-entrypoint-parameter` + +**Semantic intent.** A handler method that is **never called from anywhere in +the fixture** is declared an entry point with its parameter tainted on entry. +The engine must synthesize a root it was not given by the call graph. + +**Model declaration.** + +- Entity identity: type `Handler`, member `onRequest`, position `0`. +- Role: `entry-point`. +- Binding: `in: 0` tainted on entry. + +**Positive.** `onRequest(input)`'s body is `dfb_sink(input);`. Nothing in the +fixture calls `onRequest`. + +**Negative.** A sibling handler `onIgnored(input)` with a byte-identical body, +also never called, and **not** declared. +`negative_mechanism: call-context-separation`. + +**Capability kind.** `entry-point-root-activation`. + +**Sketches.** In all three languages: one type (class / object literal / module) +with two uncalled one-parameter methods whose bodies each sink the parameter, +and no top-level code that invokes either. + +#### 10. `dfb-template-model-entrypoint-selectivity` + +**Semantic intent.** Entry-point declarations bind by member identity. Template 9 +proves a root can be synthesized; this one proves the synthesis is *selective* +rather than "every uncalled method is a root", which is a common and defensible +whole-program default and one this matrix must be able to see. + +**Model declaration.** Identical to template 9, applied to a fixture where +**both** handlers are plausible roots. + +- Entity identity: type `Handler`, member `onDeclared`, position `0`. +- Role: `entry-point`. +- Binding: `in: 0` tainted on entry. + +**Positive.** `onDeclared(input)` sinks its parameter; declared. + +**Negative.** `onUndeclared(input)` sinks its parameter; **not** declared, and +in the same class, with the same signature and the same body. +`negative_mechanism: call-context-separation`. + +The pair is the entry-point analogue of template 6: an engine that treats every +public uncalled method as an entry root passes the positive and false-positives +the negative, and the pair reports that as approximation character rather than +as a ranking. + +**Capability kind.** `entry-point-identity-binding`. + +**Sketches.** As template 9, with both methods in one type. + +--- + +### Category B — persistence boundaries + +A write in one procedure and a read in another, linked only by a model that says +they are two ends of the same store. This is the category with the least prior +art in the corpus — nothing in the schema, no policy section, no query +construct, and no fixture addresses it today — so its declaration vocabulary is +defined here from scratch. + +#### 11. `dfb-template-model-store-roundtrip` + +**Semantic intent.** A tainted value is written into a fixture-local store type +under a key, and read back from a **separate procedure** under a key. The model +links the write and the read as the two roles of one persistence boundary; the +key decides whether the roundtrip closes. + +**Model declaration.** Two declarations sharing one store identity: + +- Entity identity: type `Store`, member `put`, positions `0` (key) and `1` + (value). Role: `store-write`. Binding: `in: 1`, `key: 0`, `store: primary`. +- Entity identity: type `Store`, member `get`, positions `0` (key) and `return`. + Role: `store-read`. Binding: `out: return`, `key: 0`, `store: primary`. + +**Positive.** `writeSide()` calls `Store.put("k", dfb_source())`; a separate +`readSide()` calls `dfb_sink(Store.get("k"))`. Same key constant. + +**Negative.** The identical pair of procedures with **distinct constant keys** — +`put("a", …)` and `get("b")`. `negative_mechanism: field-separation`, following +the corpus precedent that constant-key separation inside a container is recorded +as field separation. + +`Store`'s `put` and `get` have empty bodies. The roundtrip exists only in the +model. + +**Capability kind.** `persistence-boundary-activation`. + +**Sketches.** A `Store` type with two static no-op methods per language, plus two +top-level procedures. No standard-library map is used: an engine that models +`HashMap.get` would otherwise pass this without reading the declaration, which is +the same trap the fairness constraint exists to avoid. + +#### 12. `dfb-template-model-store-separation` + +**Semantic intent.** Persistence declarations are **per store instance**. Two +`Store` instances exist; the model links each instance's own write and read, and +does not link across them. + +**Model declaration.** As template 11, with the store identity bound to the +receiver instance rather than to the type: `store: `. + +**Positive.** `alpha.put("k", dfb_source())` in one procedure; +`dfb_sink(alpha.get("k"))` in another. Same instance, same key. + +**Negative.** `alpha.put("k", dfb_source())` and `dfb_sink(beta.get("k"))` — +same key, **different instance**. `negative_mechanism: object-separation`. + +**Capability kind.** `persistence-instance-binding`. + +**Sketches.** Two module-level or field-held `Store` instances per language, +constructed once and never reassigned. + +--- + +### Summary table + +| # | `template_id` | Neg. mechanism | `expected_analysis_capability.kind` | +| --- | --- | --- | --- | +| 1 | `dfb-template-model-declared-source` | `unrelated-value` | `declared-source-activation` | +| 2 | `dfb-template-model-declared-sink` | `unrelated-value` | `declared-sink-activation` | +| 3 | `dfb-template-model-opaque-propagator` | `call-context-separation` | `opaque-propagator-activation` | +| 4 | `dfb-template-model-propagator-position` | `call-context-separation` | `positional-propagator-activation` | +| 5 | `dfb-template-model-sanitizer-kill` | `sanitizer` | `declared-sanitizer-activation` | +| 6 | `dfb-template-model-sanitizer-selectivity` | `sanitizer` | `sanitizer-identity-binding` | +| 7 | `dfb-template-model-summary-through` | `call-context-separation` | `procedure-summary-activation` | +| 8 | `dfb-template-model-summary-field` | `field-separation` | `store-through-summary-activation` | +| 9 | `dfb-template-model-entrypoint-parameter` | `call-context-separation` | `entry-point-root-activation` | +| 10 | `dfb-template-model-entrypoint-selectivity` | `call-context-separation` | `entry-point-identity-binding` | +| 11 | `dfb-template-model-store-roundtrip` | `field-separation` | `persistence-boundary-activation` | +| 12 | `dfb-template-model-store-separation` | `object-separation` | `persistence-instance-binding` | + +## The equivalence contract + +This is the section that makes the matrix a benchmark rather than four separate +experiments. + +**The claim.** *What* is declared is identical across tools — the entity +identity, the role, and the binding semantics of +[the model declaration language](#the-model-declaration-language). *How* it is +declared is each tool's own native mechanism. A tool that cannot express a +category does not get a translated approximation of it; it takes +`unsupported` for that category, recorded before any run. + +**Encoding.** Each adapter encodes the declaration in the surface its own +documentation gives it, in a per-language modeling artifact committed to the +repository and hash-bound into the report's `configuration_hash` the same way +every existing adapter artifact is: + +| Adapter | Modeling artifact | Declaration surface | +| --- | --- | --- | +| Bifrost | `adapters/bifrost/policies/model-.rqlp` | RQLP `:analysis` endpoint sets — verified in the committed policies for `:sources` (`:bind return-value`) and `:sinks` (`:dangerous-operand (argument :index N)`); other sections per the partition below | +| CodeQL | `adapters/codeql/queries/Modeling.ql` (+ any `ext/*.model.yml`) | `DataFlow::ConfigSig` predicates `isSource` / `isSink` / `isBarrier` / `isAdditionalFlowStep`, optionally models-as-data rows | +| Joern | `adapters/joern/queries/modeling.sc` plus a flow-semantics file | query roots over `cpg.method…parameter` and `FlowSemantic` / `FlowMapping` entries | +| Semgrep | `adapters/semgrep/rules/model-.yaml` | `mode: taint` with `pattern-sources` / `pattern-sinks` / `pattern-propagators` / `pattern-sanitizers` | + +Bifrost and CodeQL cases name their artifact through the `tool_model_references` +keys the case schema already carries — `policy` and `query` respectively. Joern +and Semgrep have no case-level model reference today (both pin their invocation +in the runner, as their READMEs record), and the modeling matrix does not change +that. **No new `tool_model_references` key is required**, because each adapter's +modeling declarations live inside the single per-language artifact its existing +key already names. + +### The load-bearing-model requirement + +A modeling assertion is only evidence of activation if the tool's behavior +*without* the model would differ. Two of the four adapters have an +unmodeled-call default that would otherwise decide category P and category O +cells on their own: + +- **Bifrost.** Every committed kernel policy sets + `:call-modeling (call-modeling :unmodeled optimistic)`. Under that setting an + unmodeled call may pass taint through, which would decide template 3's positive + without reading the propagator declaration. +- **Semgrep CE.** Verified against the pinned CE 1.174.0: with no propagator + declared at all, a taint-mode rule reports `dfb_sink(prop("clean", t))` — the + engine's default is to carry taint from any tainted argument to a call's + result. Setting `options: taint_assume_safe_functions: true` removes that + default (verified: the same finding disappears). + +The contract is therefore: **for a category to be scored for a tool, that tool's +modeling artifact must configure the unmodeled-call default so that the model is +load-bearing** — `require-model`-style behavior where the tool has such a switch, +`taint_assume_safe_functions: true` for Semgrep. Where a tool has no such switch +for a category, the category is `unsupported` for that tool rather than scored, +because a cell the default already decides is not a measurement. + +This requirement is why several partition cells below say `unsupported` for a +tool whose declaration *syntax* exists. Syntax that the engine does not lower, or +that a permissive default overrides, is not activation. + +## Per-tool capability partition + +Preregistered here, in this document, before any modeling fixture or model file +exists — the same discipline `CHALLENGE_SEMGREP_PARTITION` in `src/main.rs` +already applies to the challenge tier, and for the same reason: a partition +decided from a result is not a capability classification. + +**Reading the tables.** `supported` means the tool's declaration surface can +express the category and the model can be made load-bearing. `unsupported` means +it cannot, today, on the pinned version — those cells are `unsupported` outcomes +with a retained reason, decided from case metadata before the tool is invoked. +Cells marked **to be verified** could not be checked against the pinned tool +while writing this document; per the rule stated at the head of each table, +**they are treated as unsupported until shown otherwise**, and promoting one is +a dated amendment. + +An `unsupported` cell is coverage, never a negative, and never a false negative. +It does not reduce any other tool's denominator, and it does not reduce the +benchmark's — a tool that declines a category simply has no assertions in it. + +### Bifrost — v0.10.6 (build `18d09c57`) + +Verified surface: the seventeen committed `.rqlp` policies use exactly +`:sources` (with `:bind return-value` and `:labels`) and `:sinks` (with +`:dangerous-operand (argument :index N)` and `:accepts`), under +`(analysis :type taint :mode may :call-modeling (call-modeling :unmodeled +optimistic))`. No committed policy contains a sanitizer, transform, or +external-model section. The pinned v0.10.6 build was not available while writing +this document; a locally installed **v0.9.5** binary was inspected and exposes +policy-schema pointers for `/analysis/sanitizers/entries/`, +`/analysis/transforms/entries/` and `/analysis/external_models/entries/`, plus +`call-modeling` values `paranoid | optimistic | require-model`. **A schema that +accepts a section is not proof that the CLI lowers it into the engine**, which is +precisely what the adapter README says is missing, so none of that is treated as +verification. + +| Cat. | Decision | Rationale | +| --- | --- | --- | +| S | **supported** | Source and sink endpoint sets are the surface every committed policy already uses, in thirteen languages, with frozen v0.4.0 evidence. Binding is by RQLP selector, which addresses a callee by name and can be language-qualified — enough for the type+member identity the declaration language requires. | +| P | **to be verified — unsupported until shown** | No committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build. | +| Z | **unsupported** | The adapter README states it directly: *"Sanitizer lowering is a future Bifrost CLI capability."* (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do. | +| O | **unsupported** | The adapter README: *"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result."* The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report. | +| E | **to be verified — unsupported until shown** | Nothing in the repository or the README describes an entry-root declaration for the policy CLI. | +| B | **to be verified — unsupported until shown** | No persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included. | + +Bifrost therefore enters this matrix with **one of six categories scored**. That +is the honest starting position for a standalone policy CLI whose modeling +surface lives in an embedding, and stating it in the preregistration — rather +than after a run — is the point. + +### CodeQL — CLI 2.26.3 + +Verified surface: the shared `codeql/dataflow` library at the pinned resolution +defines `DataFlow::ConfigSig` with `isSource`, `isSink`, and the defaulted +`isBarrier`, `isBarrierIn`, `isBarrierOut`, and `isAdditionalFlowStep`. The +pinned language packs each ship models-as-data extensible predicates — +`sourceModel`, `sinkModel`, `summaryModel`, `barrierModel`, `neutralModel` — in +`codeql/java-all@9.2.3` +(`semmle/code/java/dataflow/internal/ExternalFlowExtensions.qll`), +`codeql/javascript-all@2.9.0` and `codeql/python-all@7.2.3` +(`semmle/…/frameworks/data/internal/ApiGraphModelsExtensions.qll`). The adapter +uses **no** data extensions today; the query owns the model, which +`adapters/codeql/README.md` states as the design (*"The query owns the CodeQL +model; the case metadata remains analyzer neutral."*). + +| Cat. | Decision | Rationale | +| --- | --- | --- | +| S | **supported** | `isSource` / `isSink` over a named callee is what all eleven committed kernel queries already do. | +| P | **supported** | `isAdditionalFlowStep(node1, node2)` expresses arg-position → return-value directly, and positional fidelity is native: the step is written against `call.getArgument(1)` specifically. | +| Z | **supported** | `isBarrier` is a defaulted member of the same `ConfigSig` the adapter already instantiates. | +| O | **supported** | Same `isAdditionalFlowStep` mechanism; the store-through form of template 8 is a step into a field content node. The alternative encoding — `summaryModel` MaD rows — is available in all three packs but is API-graph-keyed and its binding to *fixture-local* types is **to be verified at implementation**; the pack-predicate encoding is the primary and the MaD one is optional, so this cell does not depend on that verification. | +| E | **supported** | `isSource` can name a parameter node of an uncalled method, and CodeQL's data flow does not require a source to be reachable from a call graph root. Selectivity is by the method's identity in the predicate body. | +| B | **supported** | Two `isAdditionalFlowStep` clauses — one from `put`'s value argument to a synthetic store node, one from that node to `get`'s result — conditioned on equal constant key arguments and, for template 12, on the receiver. Expressible in QL without leaving the checked-in pack. | + +CodeQL enters with **six of six**, which is unsurprising: a query language whose +data-flow configuration *is* a model declaration surface has no category to +decline. The interesting question for CodeQL is not whether it can be told, but +whether the resulting semantics match — which is what the assertions measure. + +### Joern — 4.0.610 + +Verified surface: the OSS data-flow engine ships a flow-semantics loader — +`io.joern.dataflowengineoss.semanticsloader` with `FlowSemantic`, `FlowMapping`, +`FlowPath`, `ParamOrRetNode`, `NilSemantics`, `NoCrossTaintSemantics`, and +`FullNameSemanticsParser`, plus a `SemanticsParser`/`SemanticsLexer` grammar for +the textual semantics format. Verified by inspecting +`io.joern.dataflowengineoss-.jar` in a locally installed distribution, +which is **4.0.432, not the pinned 4.0.610** — the class surface is expected to +be identical and is **to be confirmed against the pinned distribution at +implementation**, on the same terms as the challenge tier's verified +`maxCallDepth` bound. The committed `adapters/joern/queries/kernel.sc` supplies +no semantics today, which the README states: *"No custom semantics, no +additional propagation or sanitizer models, and no engine configuration are +supplied."* Supplying them for the modeling matrix is a new adapter capability, +scoped to a separate `modeling.sc` so the kernel script is untouched. + +| Cat. | Decision | Rationale | +| --- | --- | --- | +| S | **supported** | The kernel script already selects sources and sinks by callee name through CLI parameters; a modeling script selects the declared identities the same way. | +| P | **supported** | `FlowMapping` over `ParamOrRetNode` expresses argument-index → return propagation, and the index is the mapping's own key, so positional fidelity is native rather than emulated. | +| Z | **supported** | `NilSemantics` — a method declared with no flow mappings — is precisely "taint does not leave this entity", which is the `sanitizer` role. | +| O | **supported** | The same semantics mechanism, with an access path on the destination for template 8's `out: 1.payload`. `FlowPath` is the surface; its access-path expressiveness for a field destination is **to be verified at implementation**, and template 8 alone is unsupported for Joern if it cannot be expressed. | +| E | **supported** | `reachableByFlows` takes arbitrary CPG nodes as sources; `cpg.method.fullNameExact(…).parameter.index(1)` is a valid root regardless of whether any call site reaches the method. Selectivity is the query's own predicate. | +| B | **supported** | Two `FlowSemantic` entries — `put` mapping its value parameter into its store parameter, `get` mapping its receiver to its return — leave the key and instance discrimination to the engine, which is the correct division: the model declares the boundary, the analysis decides whether the roundtrip closes. | + +### Semgrep CE — 1.174.0 (`--oss-only`) + +This partition is **verified by execution** against the pinned CE binary +(`semgrep 1.174.0`, `--oss-only`), on small Python probes, before any fixture +exists. Each cell below states what was run and what came back. + +The existing `CHALLENGE_SEMGREP_PARTITION` precedent applies: cells are decided +from case metadata and the pinned distribution's documented behavior, before +Semgrep is invoked, and no result can talk the runner into or out of the +partition. + +| Cat. | Decision | Rationale | +| --- | --- | --- | +| S | **supported** | `pattern-sources` / `pattern-sinks` are what all eleven committed rules already use. Both category-S templates are single-statement and intraprocedural, so they sit inside the CE profile. | +| P | **unsupported** | Verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the [load-bearing-model requirement](#the-load-bearing-model-requirement) is violated either way. Arg→return propagation is outside CE's propagator vocabulary. | +| Z | **supported** | Verified: `pattern-sanitizers` on `scrub(...)` suppresses a finding that the same rule reports without it, and leaves an unrelated direct flow reported. Both category-Z templates are intraprocedural. The rule must set `options: taint_assume_safe_functions: true` so the sanitizer, not the default, is what the cells turn on. | +| O | **unsupported** | Template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only *"Experimental support for basic field-sensitive taint tracking"* — so the field-separation negative would be decided by CE's heap approximation rather than by the summary. | +| E | **supported** | Verified, and this is the surprising cell: a source written as `patterns: [pattern: "def on_request($P): ...", focus-metavariable: $P]` produced a finding inside the declared handler's body and **no** finding inside a byte-identical undeclared sibling. Both templates in this category are intraprocedural — the handler's body contains the sink — so the absence of a caller is not a problem for an intraprocedural engine, it is the normal case. | +| B | **unsupported** | The write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (*"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine"*), so the step from `put` to `get` is outside the engine regardless of what is declared. | + +Semgrep CE enters with **three of six**, and — worth saying plainly, because the +expectation from the kernels would be the opposite — it enters with a *larger* +share of this matrix than Bifrost does. Modeling capability and propagation +capability are not the same axis, which is the whole reason this tier exists. + +### Partition summary + +Preregistered, before any modeling fixture exists. `TBV` = to be verified at +implementation, treated as unsupported until shown otherwise. + +| Category | Bifrost v0.10.6 | CodeQL 2.26.3 | Joern 4.0.610 | Semgrep CE 1.174.0 | +| --- | --- | --- | --- | --- | +| S — sources and sinks | supported | supported | supported | supported | +| P — propagators | TBV | supported | supported | unsupported | +| Z — sanitizers | unsupported | supported | supported | supported | +| O — summaries | unsupported | supported | supported (T8 TBV) | unsupported | +| E — entry points | TBV | supported | supported | supported | +| B — persistence | TBV | supported | supported | unsupported | +| **Scored today** | **1 / 6** | **6 / 6** | **6 / 6** | **3 / 6** | + +These counts are categories, not scores. A tool with six of six has six +categories' worth of assertions it can get wrong, and a tool with one of six has +declined five categories rather than failed them. Any future summary that reads +this table as a ranking is a misreading of this document. + +## The three-way distinction + +Issue #15 requires that missing models, unsupported activation, and incomplete +analysis remain distinguishable. Defined precisely, and mapped onto outcomes the +[scoring contract](scoring.md#outcome-interpretation) already carries. They are +never conflated, and none of them is ever a negative. + +**Missing model — a benchmark error, impossible by construction.** A modeling +case whose declaration does not exist for an adapter that is supposed to cover it +is a defect in DataFlowBench, not evidence about the analyzer. The +modeling-population validator makes it unrepresentable: for every modeling case +and every adapter, *either* the adapter's modeling artifact contains the +declaration for that case's template, *or* that template's category is +`unsupported` for that adapter **by the partition table above**. There is no +third state, and in particular there is no silent one. Validation fails the +build; it does not produce a result. + +**Unsupported activation — the tool cannot accept or activate this category of +model.** Outcome `unsupported`, with the partition's rationale retained verbatim +as the reason, decided from case metadata **before the tool is invoked**. This +is capability coverage. It is never a false negative and never a true negative, +and no aggregate converts it into either. + +**Incomplete analysis — the model was activated but the analysis did not +complete.** Outcome `inconclusive`. The tool accepted the declaration and then +failed to produce a decisive answer: it ran out of budget, hit an internal +invariant, or emitted a candidate without a complete witness. This is execution +coverage. It is emphatically *not* `not-reached`: normalizing it would count +incomplete analysis as a negative, which is the one conversion the scoring +contract forbids most explicitly. + +Runner failures — a missing binary, a crashed process, a malformed artifact — +remain `runner-error` and are never any of the three. + +The distinction between the second and third is the one this matrix is most +likely to blur, so it has a rule: **`unsupported` is decided before the run and +`inconclusive` is decided after it.** If the partition says a tool cannot +activate a category, no execution of that tool can produce anything but +`unsupported` for it. If the partition says it can, no failure to produce an +answer may be reported as `unsupported` — it is `inconclusive`, and the reason is +retained. + +## Reporting + +Modeling results are their own population, end to end. + +- **Reports.** Per language, per adapter: + `reports/--modeling.json`, in the existing result schema, bound + into the freeze manifest like every other report. +- **Scorecards.** Separate, per language and per adapter, at the `modeling` tier. + Generated results order the tier alongside the existing four. +- **Never on a kernel card.** A modeling assertion never appears on a + propagation-kernel scorecard, never enters a core denominator, and is never + macro-averaged with one. +- **Per category.** Every report breaks results down by the six categories, so + that "activates sources but not summaries" is readable off the card rather than + reconstructed from case IDs. +- **The site.** The published site treats modeling as a new population, with its + own section. That is a later site pass and is out of scope for this document + beyond stating that the population must not be folded into an existing view. + +## Metadata groundwork + +Additive schema changes only, made in the same change as this document so that +fixture authoring is unblocked. Every addition was checked against the existing +enum first; nothing already expressible was duplicated. + +### New score tier + +`score_tier` gains `"modeling"` in both `schemas/case.schema.json` and +`schemas/freeze.schema.json`. Existing freezes are unaffected: freeze validation +is manifest-scoped, and an added enum value changes nothing that a +previously-validated manifest asserts. + +The result-generation tier ordering in `src/main.rs` (`SCORE_TIER_ORDER`) is +extended in the same change. That constant decides which tiers get a section on a +generated scorecard, and a tier absent from it would be **silently dropped** from +every generated result rather than reported as an error — so it is registered +here, with the schemas, ahead of the first modeling case. + +### No new negative mechanism + +The design sketch for this document proposed adding `sanitizer-kill`. It was +checked against the enum and **not added**: `schemas/case.schema.json` already +carries `sanitizer` in `negative_mechanism`, and it has been there since the v2 +case contract without ever being used by a case. It means exactly what +`sanitizer-kill` would have meant. Adding a second spelling of an existing value +would have been duplication, and templates 5 and 6 use `sanitizer`. + +The twelve negatives use `unrelated-value` (1, 2), `call-context-separation` +(3, 4, 7, 9, 10), `sanitizer` (5, 6), `field-separation` (8, 11), and +`object-separation` (12). `infeasible-path` and `overwrite-kill` are unused by +this matrix. + +### No new semantic dimensions + +Checked and **not** added. The enum already carries `external-summary` +(categories O and E), `sanitizer` (Z), `interprocedural-flow` (P, O, B), +`heap-field-sensitivity` (templates 8 and 11), and `object-sensitivity` +(template 12). Every category maps onto an existing dimension, so adding one +would have been duplication. + +### No new feature tags + +Checked and **not** added. `modeled-external` marks every case in this matrix — +the value exists for exactly this purpose and is currently carried by one +calibration case. `summary-required` covers categories P, O, and E; +`sanitized` covers Z; `heap-access-path` covers templates 8, 11, and 12; +`interprocedural-one-hop` covers the rest. + +### No new `tool_model_references` key + +`tool_model_references` per-tool objects are `additionalProperties: false` with +`policy`, `query`, and `unsupported_reason`. That is sufficient: Bifrost +modeling cases name their `.rqlp` through `policy`, CodeQL cases name their query +through `query`, unsupported cells carry `unsupported_reason`, and Joern and +Semgrep pin their invocation in the runner as they already do. No schema change. + +### `expected_analysis_capability.kind` + +Not enum-constrained — a free-form string with an optional `notes` sibling — so +no schema change is required and none was made. The twelve kind strings are fixed +in [the summary table](#summary-table) so that fixtures cannot drift. They follow +the corpus convention the existing `external-summary-activation` establishes: +this matrix measures *activation* and *binding*, so its kinds end in +`-activation` (the category can be turned on) or `-binding` (the category binds +to the right entity), rather than the kernels' `-taint` suffix. + +### Validator scope, stated now, implemented later + +A modeling-population validator is specified here and implemented alongside the +first language's fixtures, because a required-set check that runs before the +fixtures exist would fail against the current corpus. It must enforce: + +1. **Balance.** Each language's modeling population contains exactly one + positive and one minimally different negative case for each applicable + template — 24 assertions for a full twelve-template language. +2. **Completeness.** The population contains the exact twelve `template_id` + values above, so an omitted template cannot hide inside a balanced but smaller + subset. This mirrors the existing Python-parity required-set check. +3. **Tier isolation.** No `modeling` case appears in any core, calibration, + `language-extension`, or `real-project` selection, and no core selection + admits a `modeling` case. +4. **Declaration coverage.** For every modeling case and every covering adapter, + either the adapter's modeling artifact declares that case's model, or the + case's category is `unsupported` for that adapter by the partition table — + never neither. This is what makes *missing model* unrepresentable. +5. **Profile.** Every modeling case is `model_profile: "benchmark-controlled"`. + +## Rollout plan + +**Wave M1 — Java, JavaScript, Python.** One language per pull request, after +this document merges. Each PR adds that language's twenty-four fixtures and +cases, the per-adapter model encodings its partition entitles it to, the runs, +and the language's row in the modeling validator. A wave never edits a template +definition in this document. + +**Later — the remaining ten languages,** via the applicability pass described +under [initial languages](#initial-languages). Those languages have no modeling +denominator until that pass merges. + +**Adjacent issues.** #16 (tool-native profiles) builds on this matrix's category +taxonomy so the two profiles can be read side by side, and supplies **no +models**. #17 (OpenTaint) and #18 (Semgrep CE) join per their own issues; a new +adapter joining this matrix arrives with its own preregistered partition row, +added by amendment before its first modeling run. + +Nothing in this plan makes a language's fixtures conditional on the results any +analyzer produces for it, and no partition cell is revised because a run was +disappointing. + +## Invariants + +Restating the obligations this tier is most at risk of eroding: + +- Modeling cases are `score_tier: "modeling"` and never enter a core + denominator, in any language, in any release. +- Modeling and propagation-kernel scores are never pooled, never averaged, and + never presented as one number. +- Benchmark-controlled and tool-native model profiles are never pooled. +- `unsupported`, `inconclusive`, and `runner-error` are capability or execution + coverage and are never converted into clean negatives. +- A missing model is a benchmark defect that fails validation, never a result. +- Capability partitions are decided before runs and revised only by dated + amendment. +- Published numbers come only from validated freeze manifests. +- The category partition table counts categories, not correctness, and is not a + ranking. + +## Amendments + +None yet. This document has not been amended since it merged. diff --git a/docs/scoring.md b/docs/scoring.md index 2ca626e..9645200 100644 --- a/docs/scoring.md +++ b/docs/scoring.md @@ -66,6 +66,17 @@ calibration cases exercise capabilities such as one-hop helpers or activated external summaries without changing a core denominator. Results from one population are not evidence that another population completed successfully. +The [benchmark-controlled taint-modeling matrix](modeling-matrix.md) joins that +list as a further separate population, on its own `modeling` score tier. It asks +a different question from every kernel — not whether an engine can follow flow it +can see, but whether it activates a model it was given — so its assertions never +enter a core denominator and are never pooled or averaged with a propagation +score. Its pairs are balanced for the same reason the kernels' are: an engine +that ignores a supplied model answers "no flow" on both cells of every category +it did not activate and banks half the assertions, so modeling results are read +against the same 50% blind baseline, with per-category true-positive and +false-positive rates carrying the evidence rather than the raw correct count. + An analyzer may report a candidate finding with incomplete discovery or an incomplete witness. That evidence remains `inconclusive` until the tool proves the required path. It must not be normalized to `not-reached` merely because diff --git a/schemas/case.schema.json b/schemas/case.schema.json index ca2d876..f82e70a 100644 --- a/schemas/case.schema.json +++ b/schemas/case.schema.json @@ -46,8 +46,8 @@ ] }, "score_tier": { - "enum": ["calibration", "core", "language-extension", "real-project"], - "description": "Calibration cases validate adapters but never contribute to correctness scores." + "enum": ["calibration", "core", "language-extension", "modeling", "real-project"], + "description": "Calibration cases validate adapters but never contribute to correctness scores. Modeling cases score the benchmark-controlled taint-modeling matrix on their own tier and never enter a core denominator." }, "track": { "enum": ["value-flow", "taint", "typestate", "witness", "performance"] }, "language": { "type": "string", "minLength": 1 }, diff --git a/schemas/freeze.schema.json b/schemas/freeze.schema.json index 7b2e397..9f7451a 100644 --- a/schemas/freeze.schema.json +++ b/schemas/freeze.schema.json @@ -49,7 +49,7 @@ "enum": ["benchmark-controlled", "tool-native"] }, "score_tier": { - "enum": ["calibration", "core", "language-extension", "real-project"] + "enum": ["calibration", "core", "language-extension", "modeling", "real-project"] }, "outcome": { "enum": ["reached", "not-reached", "inconclusive", "unsupported", "runner-error"] diff --git a/src/main.rs b/src/main.rs index 6d0fff6..96220dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2206,7 +2206,17 @@ const RESULT_OUTCOME_ORDER: [&str; 5] = [ "unsupported", "runner-error", ]; -const SCORE_TIER_ORDER: [&str; 4] = ["calibration", "core", "language-extension", "real-project"]; +/// Result-page tier ordering. A tier absent from this list would be silently +/// dropped from every generated scorecard, so `modeling` is registered here +/// with the schema enums, ahead of the first modeling case, rather than left +/// to be discovered by an empty section later. +const SCORE_TIER_ORDER: [&str; 5] = [ + "calibration", + "core", + "language-extension", + "modeling", + "real-project", +]; /// Case metadata a result view needs beyond what the freeze manifest binds. /// Language and semantic dimensions live in the case file, whose bytes the From 535eb8e060f0c981524587ccd3b05ffca92ec4d6 Mon Sep 17 00:00:00 2001 From: David Baker Effendi Date: Wed, 26 Aug 2026 11:36:27 +0200 Subject: [PATCH 2/3] Build the taint-modeling-matrix runner infrastructure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The twelve preregistered modeling templates, their six categories, and the per-tool capability partition are transcribed from docs/modeling-matrix.md into src/main.rs, ahead of any fixture, model artifact, or run. No fixtures, no model files, no reports: this is the machinery a language pull request fills. MODELING_PARTITION is CHALLENGE_SEMGREP_PARTITION's mechanism generalized to four tools — twenty-four cells, one per tool per category, with the preregistration's "to be verified" cells recorded as unsupported per its own rule. Scored today: Bifrost 2 templates of 12, Semgrep CE 6, CodeQL 12, Joern 12. A declined cell is decided from the template ID before the tool is invoked, retains the document's rationale verbatim, and writes a retained capability decision beside the report; a test asserts the cell does not move when a case's feature_tags are rewritten. Tier isolation is structural rather than a filter to remember: a dfb-template-model- template and score_tier "modeling" imply each other, and smoke_population_case refuses modeling cases the way it already refuses challenge ones, so the frozen 118-case Bifrost slice cannot absorb one. The population validator enforces the balanced twenty-four over exactly the twelve for any language that has modeling cases at all; a language with none has no modeling denominator, which is different from having a zero, so no rollout table is needed — presence is the signal. Four commands, parameterized by language rather than twelve near-identical variants: the per-language kernel commands are separate because each language's kernel differs in real toolchain plumbing, and a modeling run differs from its sibling only in which artifact it loads. Each refuses, before touching the analyzer, when the language has no modeling population or when the tool's modeling artifact is missing — the preregistration's "missing model is a benchmark defect" arm, a hard error that fails the build rather than an outcome. The load-bearing-model gates are wired now so a language pull request cannot forget them: a Bifrost modeling policy must set :unmodeled require-model and may not name the kernel policies' optimistic default, and a Semgrep modeling rule must set taint_assume_safe_functions: true. Tests pin both strings. CodeQL and Joern have no such switch and are not gated. Co-Authored-By: Claude Fable 5 --- docs/adapters.md | 119 ++++ src/main.rs | 1428 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 1546 insertions(+), 1 deletion(-) diff --git a/docs/adapters.md b/docs/adapters.md index 3ee2502..254930b 100644 --- a/docs/adapters.md +++ b/docs/adapters.md @@ -199,6 +199,125 @@ core kernels carry their preregistered expanded denominators, and every remaining gap is an adapter re-run deferred to v0.4.0 by the freeze rule, not a missing fixture. +## Modeling matrix rollout mechanics + +[The modeling-matrix preregistration](modeling-matrix.md) fixes *what* the +twelve benchmark-controlled modeling templates are, which of the six categories +each analyzer can express, and what a language's modeling denominator becomes. +It deliberately leaves the runner work to the pull requests that author the +fixtures and the model artifacts. This section is the mechanics, on the same +terms as the challenge-tier section above. + +**Infrastructure now, fixtures and models per language.** The runner +infrastructure — the template constants, the population validator, the per-tool +partition, the four commands, the artifact-path conventions, and the +load-bearing-model gates — lands ahead of any fixture. Wave M1 then adds Java, +JavaScript, and Python one pull request at a time: that language's twenty-four +fixtures and cases, the per-adapter model encodings its partition entitles it +to, and the runs. A wave never edits a template definition or a partition cell. + +**Presence is the signal; there is no rollout table.** The challenge tier needed +`CHALLENGE_ROLLOUT` because its templates *expand an existing denominator*, so +something had to say whether a language's core is the classic set or the +expanded one. Modeling is its own tier with its own denominator, so the +question does not arise: `validate_modeling_cases` in `src/main.rs` checks each +language that has modeling-tier cases against the preregistered twelve, and a +language with none has no modeling denominator at all — which is different from +having a zero, and validates trivially. The first fixture a language commits +turns the check on for that language, and a partial landing fails the build +rather than silently reducing a denominator. + +**Tier isolation is structural, not a filter someone has to remember.** A +`dfb-template-model-` template and `score_tier: "modeling"` imply each other, +and the validator rejects a case where they disagree. Because every core, +calibration, `language-extension`, and `real-project` selection already filters +on the tier, a modeling case cannot leak into any of them; `smoke_population_case` +additionally refuses modeling cases outright, the same way it refuses challenge +ones, so the frozen 118-case Bifrost smoke population cannot absorb one. + +**The partition is `CHALLENGE_SEMGREP_PARTITION` generalized to four tools.** +`MODELING_PARTITION` holds one cell per tool per category — twenty-four cells, +transcribed from the preregistration's tables, with the cells it marks *to be +verified* recorded as `unsupported` per its own rule. Scored today: **Bifrost 2 +templates of 12** (category S alone), **Semgrep CE 6 of 12** (S, Z, E), +**CodeQL 12 of 12**, **Joern 12 of 12**. A declined cell is decided from the +template ID *before the tool is invoked*, retains the document's rationale +verbatim as its reason, and writes a `retained-capability-decision` evidence +document beside the report. The decision is keyed by template identity, never +by `feature_tags` and never by an observed result — a regression test asserts +the cell does not move when a case's tags are rewritten — and revising one is a +dated amendment on the preregistration, not an edit here. + +**Model artifacts are conventions the language PRs populate.** One artifact per +tool per language, hash-bound into the report's `configuration_hash`: + +| Adapter | Modeling artifact | +| --- | --- | +| Bifrost | `adapters/bifrost/policies/model-.rqlp` | +| CodeQL | `adapters/codeql//queries/Modeling.ql` | +| Joern | `adapters/joern/semantics/model-.semantics`, plus the shared `adapters/joern/queries/modeling.sc` | +| Semgrep | `adapters/semgrep/rules/model-.yaml` | + +The CodeQL path departs from the preregistration's schematic +`adapters/codeql/queries/Modeling.ql` and sits inside that language's +existing `qlpack`, because a query outside a pack cannot resolve its +`codeql/-all` dependency. That is a location, not a declaration +surface: the document's `ConfigSig` encoding is unchanged. Joern is the one +adapter with two files, and both bind the configuration hash. + +**Four commands, parameterized by language.** `run-bifrost-modeling`, +`run-codeql-modeling`, `run-joern-modeling`, and `run-semgrep-modeling`, each +taking `--language java|javascript|python` and writing +`reports/--modeling.json` with raw evidence under +`reports/raw/--modeling/`. The per-language *kernel* commands +are separate commands because each language's kernel differs in real toolchain +plumbing — a `kotlinc` trace, a `go build`, a synthesized Cargo crate, a +different extractor. A modeling run has none of that: three languages, three +already-wired toolchains, and a run that differs from its sibling only in which +artifact it loads and which population it selects. A `--language` argument says +that once instead of twelve times. + +**Fail fast, never an empty report.** A run refuses, before touching the +analyzer, when: + +- the language has no modeling population — *"no modeling population for + ``"*, because a report over zero assertions asserts nothing; +- the tool's modeling artifact for that language is missing or unreadable. This + is the preregistration's *missing model* arm: a scored cell with no + declaration behind it is a defect in DataFlowBench, not evidence about the + analyzer, so it is a **hard error** that fails the build and never an + outcome — not `unsupported`, not `not-reached`, not a result; +- a `--codeql-packs` search path is named but does not exist. + +**The load-bearing-model gates are wired now so a language PR cannot forget +them.** A modeling assertion is only evidence of activation if the tool's +behavior *without* the model would differ, and two adapters have an +unmodeled-call default that would otherwise decide category P and O cells on +their own. So the runner reads each artifact before the run and refuses it +unless the default is disabled: a Bifrost modeling policy must set +`:call-modeling (call-modeling :unmodeled require-model)` and must not name the +kernel policies' `optimistic`, and a Semgrep modeling rule must set `options: +taint_assume_safe_functions: true`. Tests pin both strings. CodeQL and Joern +have no such switch to pin — a `ConfigSig` with no `isAdditionalFlowStep` adds +no step and a Joern method with no `FlowMapping` propagates nothing — so +neither is gated. + +**The execution arm lands with the language.** Today every modeling command +stops at the population gate, because no fixture exists. The arm that invokes +an analyzer over a *scored* cell is written by the pull request that authors +that adapter's declarations for that language; until it is, a scored cell is a +hard error rather than a synthesized outcome, which the adapter contract at the +head of this document forbids. The `unsupported` arm is complete now, so a tool +that declines every category a population carries already produces a whole, +validated report of retained capability decisions without the analyzer being +invoked at all. + +**Reporting stays separate.** Modeling reports are their own population per +language and per adapter, bound into a freeze manifest like every other report, +ordered on generated scorecards by the `modeling` entry in `SCORE_TIER_ORDER`. +A modeling assertion never appears on a propagation-kernel scorecard, never +enters a core denominator, and is never macro-averaged with one. + ## CodeQL language populations The CodeQL adapter keeps Java and JavaScript as separate populations. The diff --git a/src/main.rs b/src/main.rs index 96220dc..e9c17ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -436,6 +436,609 @@ fn challenge_template_case(case: &Value) -> bool { .is_some_and(|template| template.starts_with(CHALLENGE_TEMPLATE_PREFIX)) } +// --------------------------------------------------------------------------- +// The benchmark-controlled taint-modeling matrix. +// +// Everything in this section is transcribed from docs/modeling-matrix.md, the +// preregistration artifact that merged before any modeling fixture, model +// artifact, or run existed. The twelve template identities, their six +// categories, and the per-tool capability partition are **immutable** on that +// document's terms: a cell revised after a run is a result being relabelled, +// not a capability classification. Corrections are dated amendments in the +// document, never silent edits here. +// --------------------------------------------------------------------------- + +/// Every modeling template ID carries this prefix. It is the property that +/// distinguishes the tier structurally, the same way `dfb-template-chal-` +/// distinguishes the challenge tier, so no selector has to reason about tags. +const MODELING_TEMPLATE_PREFIX: &str = "dfb-template-model-"; + +/// The twelve preregistered modeling templates, in the document's own order — +/// six categories of two. `docs/modeling-matrix.md#the-twelve-templates`. +const MODELING_TEMPLATE_IDS: [&str; 12] = [ + "dfb-template-model-declared-source", + "dfb-template-model-declared-sink", + "dfb-template-model-opaque-propagator", + "dfb-template-model-propagator-position", + "dfb-template-model-sanitizer-kill", + "dfb-template-model-sanitizer-selectivity", + "dfb-template-model-summary-through", + "dfb-template-model-summary-field", + "dfb-template-model-entrypoint-parameter", + "dfb-template-model-entrypoint-selectivity", + "dfb-template-model-store-roundtrip", + "dfb-template-model-store-separation", +]; + +/// One positive and one minimally different negative per template — 24 +/// assertions for a language whose modeling population exists at all. +const MODELING_CASE_COUNT: usize = 2 * MODELING_TEMPLATE_IDS.len(); + +/// Every modeling case is `benchmark-controlled`: the models come from +/// DataFlowBench and are supplied equally to every tool. The counterpart +/// `tool-native` profile (issue #16) supplies no models and is never pooled +/// with this one. +const MODELING_MODEL_PROFILE: &str = "benchmark-controlled"; + +/// The six preregistered categories. The partition below is stated per +/// category, exactly as the document states it, and templates inherit their +/// category's decision — a category is the unit a tool can or cannot express. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] +enum ModelingCategory { + /// S — declared sources and sinks. + SourcesAndSinks, + /// P — declared propagators. + Propagators, + /// Z — declared sanitizers. + Sanitizers, + /// O — opaque procedure summaries. + Summaries, + /// E — framework entry points. + EntryPoints, + /// B — persistence boundaries. + Persistence, +} + +impl ModelingCategory { + const ALL: [Self; 6] = [ + Self::SourcesAndSinks, + Self::Propagators, + Self::Sanitizers, + Self::Summaries, + Self::EntryPoints, + Self::Persistence, + ]; + + /// The one-letter key the document's tables use. + fn key(self) -> &'static str { + match self { + Self::SourcesAndSinks => "S", + Self::Propagators => "P", + Self::Sanitizers => "Z", + Self::Summaries => "O", + Self::EntryPoints => "E", + Self::Persistence => "B", + } + } + + fn label(self) -> &'static str { + match self { + Self::SourcesAndSinks => "declared sources and sinks", + Self::Propagators => "declared propagators", + Self::Sanitizers => "declared sanitizers", + Self::Summaries => "opaque procedure summaries", + Self::EntryPoints => "framework entry points", + Self::Persistence => "persistence boundaries", + } + } + + /// The two templates of this category, by the document's numbering. + fn templates(self) -> [&'static str; 2] { + match self { + Self::SourcesAndSinks => [MODELING_TEMPLATE_IDS[0], MODELING_TEMPLATE_IDS[1]], + Self::Propagators => [MODELING_TEMPLATE_IDS[2], MODELING_TEMPLATE_IDS[3]], + Self::Sanitizers => [MODELING_TEMPLATE_IDS[4], MODELING_TEMPLATE_IDS[5]], + Self::Summaries => [MODELING_TEMPLATE_IDS[6], MODELING_TEMPLATE_IDS[7]], + Self::EntryPoints => [MODELING_TEMPLATE_IDS[8], MODELING_TEMPLATE_IDS[9]], + Self::Persistence => [MODELING_TEMPLATE_IDS[10], MODELING_TEMPLATE_IDS[11]], + } + } +} + +/// The category a modeling template belongs to, decided from the template ID +/// alone. A non-modeling template has none. +fn modeling_category(template: &str) -> Option { + ModelingCategory::ALL + .into_iter() + .find(|category| category.templates().contains(&template)) +} + +/// The four adapters the preregistration partitions. A fifth adapter joins by +/// amendment with its own partition row, never by inheriting another's. +#[derive(Clone, Copy, PartialEq, Eq, Debug, clap::ValueEnum)] +enum ModelingTool { + Bifrost, + Codeql, + Joern, + Semgrep, +} + +impl ModelingTool { + const ALL: [Self; 4] = [Self::Bifrost, Self::Codeql, Self::Joern, Self::Semgrep]; + + /// The `tool` value the normalized report carries, and the first component + /// of the report and raw-evidence paths. + fn key(self) -> &'static str { + match self { + Self::Bifrost => "bifrost", + Self::Codeql => "codeql", + Self::Joern => "joern", + Self::Semgrep => "semgrep", + } + } + + /// The pinned identity the partition was decided against, quoted from the + /// document's table headings so a version drift is visible in the message. + fn pinned_identity(self) -> &'static str { + match self { + Self::Bifrost => "Bifrost v0.10.6", + Self::Codeql => "CodeQL CLI 2.26.3", + Self::Joern => "Joern 4.0.610", + Self::Semgrep => "Semgrep CE 1.174.0", + } + } +} + +/// One cell of the preregistered per-tool capability partition: a tool, a +/// category, and either a scored decision or the document's verbatim rationale +/// for declining it. +struct ModelingPartitionCell { + tool: ModelingTool, + category: ModelingCategory, + /// `None` when the category is scored for this tool. `Some(reason)` when + /// it is `unsupported`, carrying the rationale the report retains. + unsupported_reason: Option<&'static str>, +} + +/// The preregistered per-tool capability partition, transcribed cell for cell +/// from `docs/modeling-matrix.md#per-tool-capability-partition`. +/// +/// This is `CHALLENGE_SEMGREP_PARTITION`'s mechanism generalized to four +/// tools: a decision keyed by template identity, consulted **before** the tool +/// is invoked and before any tag rule, so that neither a fixture's +/// `feature_tags` nor an observed result can move a cell between the scored +/// and `unsupported` partitions after the fact. +/// +/// Cells the document marks *to be verified* are recorded here as +/// `unsupported`, per the rule stated at the head of each of its tables: +/// unverifiable is unsupported until shown otherwise, and promoting one is a +/// dated amendment. That is why Bifrost enters with one scored category rather +/// than four. +const MODELING_PARTITION: [ModelingPartitionCell; 24] = [ + // Bifrost — v0.10.6 (build `18d09c57`): 1 / 6. + ModelingPartitionCell { + tool: ModelingTool::Bifrost, + category: ModelingCategory::SourcesAndSinks, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Bifrost, + category: ModelingCategory::Propagators, + unsupported_reason: Some( + "to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build", + ), + }, + ModelingPartitionCell { + tool: ModelingTool::Bifrost, + category: ModelingCategory::Sanitizers, + unsupported_reason: Some( + "the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do", + ), + }, + ModelingPartitionCell { + tool: ModelingTool::Bifrost, + category: ModelingCategory::Summaries, + unsupported_reason: Some( + "the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report", + ), + }, + ModelingPartitionCell { + tool: ModelingTool::Bifrost, + category: ModelingCategory::EntryPoints, + unsupported_reason: Some( + "to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI", + ), + }, + ModelingPartitionCell { + tool: ModelingTool::Bifrost, + category: ModelingCategory::Persistence, + unsupported_reason: Some( + "to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included", + ), + }, + // CodeQL — CLI 2.26.3: 6 / 6. + ModelingPartitionCell { + tool: ModelingTool::Codeql, + category: ModelingCategory::SourcesAndSinks, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Codeql, + category: ModelingCategory::Propagators, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Codeql, + category: ModelingCategory::Sanitizers, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Codeql, + category: ModelingCategory::Summaries, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Codeql, + category: ModelingCategory::EntryPoints, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Codeql, + category: ModelingCategory::Persistence, + unsupported_reason: None, + }, + // Joern — 4.0.610: 6 / 6. + ModelingPartitionCell { + tool: ModelingTool::Joern, + category: ModelingCategory::SourcesAndSinks, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Joern, + category: ModelingCategory::Propagators, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Joern, + category: ModelingCategory::Sanitizers, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Joern, + category: ModelingCategory::Summaries, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Joern, + category: ModelingCategory::EntryPoints, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Joern, + category: ModelingCategory::Persistence, + unsupported_reason: None, + }, + // Semgrep CE — 1.174.0 (`--oss-only`): 3 / 6. + ModelingPartitionCell { + tool: ModelingTool::Semgrep, + category: ModelingCategory::SourcesAndSinks, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Semgrep, + category: ModelingCategory::Propagators, + unsupported_reason: Some( + "verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary", + ), + }, + ModelingPartitionCell { + tool: ModelingTool::Semgrep, + category: ModelingCategory::Sanitizers, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Semgrep, + category: ModelingCategory::Summaries, + unsupported_reason: Some( + "template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary", + ), + }, + ModelingPartitionCell { + tool: ModelingTool::Semgrep, + category: ModelingCategory::EntryPoints, + unsupported_reason: None, + }, + ModelingPartitionCell { + tool: ModelingTool::Semgrep, + category: ModelingCategory::Persistence, + unsupported_reason: Some( + "the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared", + ), + }, +]; + +/// The preregistered decision for one tool × template cell, keyed by template +/// identity alone: `None` when the category is scored, `Some(reason)` when the +/// tool declines it. Every cell is present, so an unknown template is a +/// programming error rather than a silent scored default. +fn modeling_partition_reason(tool: ModelingTool, template: &str) -> Result> { + let category = modeling_category(template).with_context(|| { + format!("{template:?} is not one of the twelve preregistered modeling templates") + })?; + MODELING_PARTITION + .iter() + .find(|cell| cell.tool == tool && cell.category == category) + .map(|cell| cell.unsupported_reason) + .with_context(|| { + format!( + "the modeling partition has no cell for {} × category {}", + tool.key(), + category.key() + ) + }) +} + +/// The retained `unsupported` reason for a declined cell, or `None` when the +/// cell is scored. The partition's rationale is carried verbatim; the prefix +/// names the category and the pinned tool identity the decision was made +/// against, so the reason is auditable without opening the document. +fn modeling_unsupported_reason(tool: ModelingTool, template: &str) -> Result> { + let Some(reason) = modeling_partition_reason(tool, template)? else { + return Ok(None); + }; + let category = modeling_category(template).expect("partition resolved the category"); + Ok(Some(format!( + "category {} — {} — is unsupported for {} by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): {reason}", + category.key(), + category.label(), + tool.pinned_identity(), + ))) +} + +/// The templates a tool is entitled to score, in preregistered order. The +/// counts are the document's partition summary: Bifrost 2, Semgrep 6, CodeQL +/// 12, Joern 12. +fn modeling_supported_templates(tool: ModelingTool) -> Vec<&'static str> { + MODELING_TEMPLATE_IDS + .into_iter() + .filter(|template| { + modeling_partition_reason(tool, template) + .expect("every preregistered template has a partition cell") + .is_none() + }) + .collect() +} + +/// The three languages wave M1 rolls the matrix out to. No other language has a +/// modeling denominator until the applicability pass the preregistration +/// describes merges — which is different from having a zero. +#[derive(Clone, Copy, PartialEq, Eq, Debug, clap::ValueEnum)] +enum ModelingLanguage { + Java, + Javascript, + Python, +} + +impl ModelingLanguage { + fn key(self) -> &'static str { + match self { + Self::Java => "java", + Self::Javascript => "javascript", + Self::Python => "python", + } + } + + fn display_name(self) -> &'static str { + match self { + Self::Java => "Java", + Self::Javascript => "JavaScript", + Self::Python => "Python", + } + } + + /// The population label validation errors are reported under. + fn label(self) -> String { + format!("{} modeling population", self.display_name()) + } + + /// The per-language modeling artifact this tool encodes its declarations + /// in. One artifact per tool per language, hash-bound into the report's + /// `configuration_hash` the way every existing adapter artifact is. + /// + /// The CodeQL path departs from the preregistration's schematic + /// `adapters/codeql/queries/Modeling.ql` and sits inside that + /// language's existing `qlpack`, because a query outside a pack cannot + /// resolve its `codeql/-all` dependency. That is a location, not a + /// declaration surface: the document's `ConfigSig` encoding is unchanged. + fn artifact(self, tool: ModelingTool) -> &'static str { + match (tool, self) { + (ModelingTool::Bifrost, Self::Java) => "adapters/bifrost/policies/model-java.rqlp", + (ModelingTool::Bifrost, Self::Javascript) => { + "adapters/bifrost/policies/model-javascript.rqlp" + } + (ModelingTool::Bifrost, Self::Python) => "adapters/bifrost/policies/model-python.rqlp", + (ModelingTool::Codeql, Self::Java) => "adapters/codeql/java/queries/JavaModeling.ql", + (ModelingTool::Codeql, Self::Javascript) => { + "adapters/codeql/javascript/queries/JavaScriptModeling.ql" + } + (ModelingTool::Codeql, Self::Python) => { + "adapters/codeql/python/queries/PythonModeling.ql" + } + (ModelingTool::Joern, Self::Java) => "adapters/joern/semantics/model-java.semantics", + (ModelingTool::Joern, Self::Javascript) => { + "adapters/joern/semantics/model-javascript.semantics" + } + (ModelingTool::Joern, Self::Python) => { + "adapters/joern/semantics/model-python.semantics" + } + (ModelingTool::Semgrep, Self::Java) => "adapters/semgrep/rules/model-java.yaml", + (ModelingTool::Semgrep, Self::Javascript) => { + "adapters/semgrep/rules/model-javascript.yaml" + } + (ModelingTool::Semgrep, Self::Python) => "adapters/semgrep/rules/model-python.yaml", + } + } + + fn report(self, tool: ModelingTool) -> PathBuf { + PathBuf::from(format!( + "reports/{}-{}-modeling.json", + tool.key(), + self.key() + )) + } + + fn raw_dir(self, tool: ModelingTool) -> PathBuf { + PathBuf::from(format!( + "reports/raw/{}-{}-modeling", + tool.key(), + self.key() + )) + } +} + +/// Joern's modeling query script. Unlike the other three adapters, Joern's +/// declarations live in two files — one shared script and one per-language +/// flow-semantics file — so both are hash-bound into the report. +const JOERN_MODELING_SCRIPT: &str = "adapters/joern/queries/modeling.sc"; + +/// The `call-modeling` setting a Bifrost modeling policy must carry. Every +/// committed kernel policy sets `:unmodeled optimistic`, under which an +/// unmodeled call may pass taint through and would decide template 3's +/// positive without the propagator declaration ever being read. A modeling +/// policy that kept that default would not be measuring activation. +const BIFROST_MODELING_CALL_MODELING: &str = "require-model"; + +/// The Semgrep rule option that makes a modeling declaration load-bearing. +/// Verified against the pinned CE 1.174.0: with no propagator declared, a +/// taint-mode rule still reports `dfb_sink(prop("clean", t))`; setting this +/// option removes that default and the finding disappears. +const SEMGREP_MODELING_ASSUME_SAFE_OPTION: &str = "taint_assume_safe_functions: true"; + +/// Enforce the load-bearing-model requirement on a Bifrost modeling policy. +/// +/// The requirement is the document's, not this runner's: a cell the engine's +/// unmodeled-call default already decides is not a measurement. Wiring the +/// check here means a language PR cannot author a modeling policy that +/// silently inherits the kernel policies' optimistic default. +fn require_bifrost_modeling_load_bearing(policy: &str, path: &str) -> Result<()> { + if !policy.contains(BIFROST_MODELING_CALL_MODELING) { + bail!( + "{path} does not set `:call-modeling (call-modeling :unmodeled {BIFROST_MODELING_CALL_MODELING})`; docs/modeling-matrix.md#the-load-bearing-model-requirement requires the unmodeled-call default to be configured so that the model is load-bearing" + ); + } + if policy.contains("optimistic") { + bail!( + "{path} still names the kernel policies' `:unmodeled optimistic` default; under it an unmodeled call may pass taint through and would decide a category P or O cell without the declaration being read" + ); + } + Ok(()) +} + +/// Enforce the load-bearing-model requirement on a Semgrep modeling rule. +fn require_semgrep_modeling_load_bearing(rule: &str, path: &str) -> Result<()> { + if !rule.contains(SEMGREP_MODELING_ASSUME_SAFE_OPTION) { + bail!( + "{path} does not set `options: {SEMGREP_MODELING_ASSUME_SAFE_OPTION}`; without it the pinned CE engine carries taint from any tainted argument to a call's result and the declared model is not what decides the cell (docs/modeling-matrix.md#the-load-bearing-model-requirement)" + ); + } + Ok(()) +} + +/// Whether a case is a modeling-tier assertion of this language. +fn modeling_case(case: &Value, language: ModelingLanguage) -> bool { + case["language"] == language.key() + && case["track"] == "taint" + && case["score_tier"] == "modeling" +} + +/// Corpus-wide modeling checks, run by `validate` over every committed case. +/// +/// **Tier isolation is structural.** A modeling `template_id` and the +/// `modeling` score tier imply each other, so a modeling case can never be +/// selected by a core, calibration, `language-extension`, or `real-project` +/// population — every one of those selectors filters on the tier — and a +/// modeling-tier case can never carry a kernel template. +/// +/// **A language with no modeling cases has no modeling denominator**, and +/// validates trivially. Presence of modeling-tier cases is the signal; there is +/// no rollout table to flip, because unlike the challenge tier this population +/// is not a subset of an existing denominator that a flag has to switch +/// between. +fn validate_modeling_cases(cases: &[(PathBuf, Value)]) -> Result<()> { + for (path, case) in cases { + let template = required_string(case, "template_id", &path.display().to_string())?; + let tier = required_string(case, "score_tier", &path.display().to_string())?; + let modeling_template = template.starts_with(MODELING_TEMPLATE_PREFIX); + let modeling_tier = tier == "modeling"; + if modeling_template != modeling_tier { + bail!( + "{}: template {template:?} and score_tier {tier:?} disagree; every `{MODELING_TEMPLATE_PREFIX}` template is `modeling`-tier and every `modeling`-tier case carries one", + path.display() + ); + } + if !modeling_tier { + continue; + } + if !MODELING_TEMPLATE_IDS.contains(&template) { + bail!( + "{}: {template:?} is not one of the twelve preregistered modeling templates (docs/modeling-matrix.md#the-twelve-templates)", + path.display() + ); + } + if case["model_profile"] != MODELING_MODEL_PROFILE { + bail!( + "{}: modeling cases are `model_profile: {MODELING_MODEL_PROFILE:?}`; the tool-native profile supplies no models and is never pooled with this matrix", + path.display() + ); + } + // Half of "a missing model is a benchmark defect, never a result": no + // modeling case may exist whose template has no preregistered decision + // for some adapter. The other half — that a scored cell's declaration + // is actually present in that adapter's artifact — is enforced by the + // runner, which refuses to run without the artifact. + for tool in ModelingTool::ALL { + modeling_partition_reason(tool, template).with_context(|| { + format!( + "{}: no preregistered {} partition decision", + path.display(), + tool.key() + ) + })?; + } + } + let languages: BTreeSet<&str> = cases + .iter() + .filter(|(_, case)| case["score_tier"] == "modeling") + .filter_map(|(_, case)| case["language"].as_str()) + .collect(); + for language in languages { + let population: Vec<(PathBuf, Value)> = cases + .iter() + .filter(|(_, case)| { + case["score_tier"] == "modeling" && case["language"].as_str() == Some(language) + }) + .cloned() + .collect(); + validate_modeling_population(&population, &format!("{language} modeling population"))?; + } + Ok(()) +} + +/// Balance and completeness for one language's modeling population: exactly one +/// positive and one minimally different negative for each of the twelve +/// templates — 24 assertions — under one model profile. +/// +/// An empty population is not a population: the language has no modeling +/// denominator and there is nothing to balance. Everything else must be whole, +/// so a partial fixture landing fails the build rather than silently reducing a +/// denominator. +fn validate_modeling_population(cases: &[(PathBuf, Value)], label: &str) -> Result<()> { + if cases.is_empty() { + return Ok(()); + } + validate_kernel_population_with(cases, label, &MODELING_TEMPLATE_IDS) +} + #[derive(Parser)] #[command(name = "dataflowbench")] struct Cli { @@ -785,6 +1388,44 @@ enum Commands { #[arg(long, default_value = "semgrep")] semgrep: PathBuf, }, + /// Run one language's benchmark-controlled taint-modeling matrix through + /// Bifrost's policy CLI. The preregistered partition scores category S + /// only, so the other five categories are `unsupported` with a retained + /// rationale, decided before the binary is invoked. + RunBifrostModeling { + #[arg(long, value_enum)] + language: ModelingLanguage, + #[arg(long, default_value = "bifrost")] + bifrost: PathBuf, + }, + /// Run one language's modeling matrix through CodeQL. All six categories + /// are scored: a data-flow configuration *is* a model declaration surface. + RunCodeqlModeling { + #[arg(long, value_enum)] + language: ModelingLanguage, + #[arg(long, default_value = "codeql")] + codeql: PathBuf, + #[arg(long)] + codeql_packs: Option, + }, + /// Run one language's modeling matrix through Joern's flow-semantics + /// surface and a dedicated `modeling.sc`, leaving the kernel script + /// untouched. All six categories are scored. + RunJoernModeling { + #[arg(long, value_enum)] + language: ModelingLanguage, + #[arg(long, default_value = "joern")] + joern: PathBuf, + }, + /// Run one language's modeling matrix through Semgrep CE. The + /// preregistered partition scores categories S, Z, and E; P, O, and B are + /// `unsupported` with a retained rationale, decided before the scan. + RunSemgrepModeling { + #[arg(long, value_enum)] + language: ModelingLanguage, + #[arg(long, default_value = "semgrep")] + semgrep: PathBuf, + }, } fn main() -> Result<()> { @@ -907,6 +1548,25 @@ fn main() -> Result<()> { Commands::RunSemgrepCppKernel { semgrep } => { run_semgrep_kernel(&semgrep, SemgrepKernel::Cpp) } + Commands::RunBifrostModeling { language, bifrost } => { + run_modeling(ModelingTool::Bifrost, &bifrost, language, None) + } + Commands::RunCodeqlModeling { + language, + codeql, + codeql_packs, + } => run_modeling( + ModelingTool::Codeql, + &codeql, + language, + codeql_packs.as_deref(), + ), + Commands::RunJoernModeling { language, joern } => { + run_modeling(ModelingTool::Joern, &joern, language, None) + } + Commands::RunSemgrepModeling { language, semgrep } => { + run_modeling(ModelingTool::Semgrep, &semgrep, language, None) + } } } @@ -970,6 +1630,10 @@ fn validate_cases() -> Result<()> { &row.expected_templates(), )?; } + // The modeling matrix is its own tier and its own denominator. Today the + // corpus carries no modeling case, so this is a no-op that turns into a + // required-set check the moment a language PR authors the first fixture. + validate_modeling_cases(&cases)?; println!("validated {} cases", paths.len()); Ok(()) } @@ -3299,6 +3963,13 @@ fn smoke_population_case(case: &Value) -> bool { if challenge_template_case(case) { return false; } + // Same reasoning, one tier later: a Java, JavaScript, or Python modeling + // case will name that language's Bifrost artifact, and the frozen 118 must + // not absorb it. Modeling is a separate tier with a separate scorecard and + // is never pooled with a kernel or calibration population. + if case["score_tier"] == "modeling" { + return false; + } let model = &case["tool_model_references"]["bifrost"]; if model["unsupported_reason"].is_string() { return true; @@ -4526,7 +5197,7 @@ fn validate_kernel_population_with( let expected_case_count = 2 * expected_templates.len(); if cases.len() != expected_case_count { bail!( - "{label} must select exactly {expected_case_count} core assertions; found {}", + "{label} must select exactly {expected_case_count} assertions; found {}", cases.len() ); } @@ -7672,6 +8343,250 @@ fn now_seconds() -> Result { Ok(SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs()) } +// --------------------------------------------------------------------------- +// Modeling-matrix runners. +// +// One command per adapter, parameterized by language, rather than twelve +// near-identical commands. The existing per-language kernel commands are +// separate because each language's kernel differs in real toolchain plumbing — +// a `kotlinc` trace, a `go build`, a synthesized Cargo crate, a different +// extractor. The modeling matrix has none of that: it is fixed at three +// languages on three already-wired toolchains, and a modeling run differs from +// its sibling only in which artifact it loads and which population it selects. +// A `--language` argument states that honestly; twelve enum variants would +// state it twelve times. +// --------------------------------------------------------------------------- + +/// Everything a modeling run needs, assembled before the tool is touched. +/// Building the plan is the fail-fast gate: no population, a missing artifact, +/// or an artifact that leaves the model non-load-bearing all fail here, and an +/// empty report is never written. +struct ModelingRunPlan { + tool: ModelingTool, + language: ModelingLanguage, + cases: Vec<(PathBuf, Value)>, + /// The artifacts hash-bound into the report's `configuration_hash`. + configuration_paths: BTreeSet, + report: PathBuf, + raw_dir: PathBuf, +} + +/// Select and validate one language's modeling population. +/// +/// The selection is by language, track, and score tier — the same three +/// properties every kernel selection uses — and the tier filter is what keeps +/// the population disjoint from every core, calibration, `language-extension`, +/// and `real-project` denominator. +fn select_modeling_cases(language: ModelingLanguage) -> Result> { + let mut selected = Vec::new(); + for path in case_paths() { + let case: Value = serde_json::from_str(&fs::read_to_string(&path)?)?; + if modeling_case(&case, language) { + selected.push((path, case)); + } + } + validate_modeling_population(&selected, &language.label())?; + Ok(selected) +} + +/// Assemble a modeling run, failing fast on every condition that would +/// otherwise produce a report that means nothing. +fn plan_modeling_run(tool: ModelingTool, language: ModelingLanguage) -> Result { + validate_cases()?; + let cases = select_modeling_cases(language)?; + if cases.is_empty() { + bail!( + "no modeling population for {}: the {} selection admits no `score_tier: \"modeling\"` case, so there is nothing for {} to be told. A language's {MODELING_CASE_COUNT} modeling assertions land with its own pull request (docs/modeling-matrix.md#rollout-plan); refusing to write an empty report", + language.key(), + language.display_name(), + tool.pinned_identity() + ); + } + + // A scored cell with no declaration behind it is a benchmark defect, not + // evidence about the analyzer. It is a hard error, never an outcome. + let artifact = language.artifact(tool); + let contents = fs::read_to_string(artifact).map_err(|error| { + anyhow::anyhow!( + "{} has a {} modeling population but its modeling artifact {artifact} cannot be read: {error}. docs/modeling-matrix.md makes a missing model a benchmark defect that fails the build; it is never `unsupported`, never `not-reached`, and never a result", + tool.pinned_identity(), + language.display_name() + ) + })?; + match tool { + ModelingTool::Bifrost => require_bifrost_modeling_load_bearing(&contents, artifact)?, + ModelingTool::Semgrep => require_semgrep_modeling_load_bearing(&contents, artifact)?, + // Neither the CodeQL nor the Joern surface has an unmodeled-call + // default that would decide a cell on its own: a `ConfigSig` with no + // `isAdditionalFlowStep` adds no step, and a Joern method with no + // `FlowMapping` propagates nothing. There is no switch to pin. + ModelingTool::Codeql | ModelingTool::Joern => {} + } + + let mut configuration_paths = BTreeSet::from([PathBuf::from(artifact)]); + if tool == ModelingTool::Joern { + // Joern's declarations live in two files, so both bind the hash. + configuration_paths.insert(PathBuf::from(JOERN_MODELING_SCRIPT)); + } + for path in &configuration_paths { + if !path.is_file() { + bail!( + "{} modeling run needs {}, which does not exist", + tool.pinned_identity(), + path.display() + ); + } + } + + Ok(ModelingRunPlan { + tool, + language, + cases, + configuration_paths, + report: language.report(tool), + raw_dir: language.raw_dir(tool), + }) +} + +/// Retain the preregistered `unsupported` decision for one declined cell, +/// **without invoking the tool**, and return the result-schema outcome. +/// +/// This is `CHALLENGE_SEMGREP_PARTITION`'s mechanism, per tool: the decision +/// is read from the partition by template identity, so no fixture's tags and no +/// observed result can move a cell. An excluded case is never handed to the +/// analyzer, so it cannot produce an empty finding list that later reads as a +/// negative. +fn modeling_partition_outcome( + tool: ModelingTool, + case: &Value, + raw_dir: &Path, +) -> Result> { + let id = required_string(case, "id", "modeling case")?; + let template = required_string(case, "template_id", id)?; + let Some(reason) = modeling_unsupported_reason(tool, template)? else { + return Ok(None); + }; + let category = modeling_category(template).expect("partition resolved the category"); + let raw_path = raw_dir.join(format!("{id}-unsupported.json")); + if raw_path.exists() { + fs::remove_file(&raw_path).with_context(|| format!("clear {}", raw_path.display()))?; + } + fs::write( + &raw_path, + serde_json::to_string_pretty(&json!({ + "adapter": tool.key(), + "case_id": id, + "state": "unsupported", + "stage": "preregistered-modeling-partition", + "reason": reason, + "template_id": template, + "modeling_category": category.key(), + "modeling_category_label": category.label(), + "pinned_tool_identity": tool.pinned_identity(), + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "evidence_kind": "retained-capability-decision" + }))? + "\n", + )?; + Ok(Some(("unsupported", reason, raw_path))) +} + +/// Run one adapter's modeling matrix for one language. +/// +/// The staged shape of this command is deliberate and is recorded in +/// docs/adapters.md: the population gate, the artifact gate, the load-bearing +/// gate, and the partition's `unsupported` arm are infrastructure and land +/// here; the arm that actually invokes the analyzer over a scored cell lands +/// with the language pull request that authors that adapter's declarations, +/// because there is nothing to invoke it against until then. A scored cell +/// with no execution arm is a hard error — this adapter will not synthesize a +/// tool result, and `docs/adapters.md` forbids it. +fn run_modeling( + tool: ModelingTool, + binary: &Path, + language: ModelingLanguage, + codeql_packs: Option<&Path>, +) -> Result<()> { + if let Some(packs) = codeql_packs + && !packs.is_dir() + { + bail!("CodeQL pack search path {} does not exist", packs.display()); + } + let plan = plan_modeling_run(tool, language)?; + + let scored = modeling_supported_templates(plan.tool); + let scored_cases: Vec<&str> = plan + .cases + .iter() + .filter_map(|(_, case)| case["template_id"].as_str()) + .filter(|template| scored.contains(template)) + .collect(); + if !scored_cases.is_empty() { + bail!( + "{} has {} scored {} modeling assertion(s) ({scored_cases:?}) but this adapter's modeling execution arm is not wired yet; it lands with the language pull request that authors {} (docs/modeling-matrix.md#rollout-plan). Refusing to write a report rather than synthesizing an outcome", + plan.tool.pinned_identity(), + scored_cases.len(), + plan.language.display_name(), + plan.language.artifact(plan.tool) + ); + } + + // Reached only by a tool that declines every category this population + // carries: a complete report of retained capability decisions, with the + // analyzer never invoked. + fs::create_dir_all(&plan.raw_dir)?; + let started = now_seconds()?; + let (version, build_identity) = modeling_version_identity(plan.tool, binary)?; + let revision = fixture_revision()?; + let mut results = Vec::with_capacity(plan.cases.len()); + for (_, case) in &plan.cases { + let id = required_string(case, "id", "modeling case")?; + let start = Instant::now(); + let (outcome, reason, raw_path) = + modeling_partition_outcome(plan.tool, case, &plan.raw_dir)? + .expect("every remaining cell is an unsupported one"); + results.push(normalized_result( + case, + id, + outcome, + vec![reason], + start.elapsed(), + &raw_path, + )); + } + let report = json!({ + "schema_version": 1, + "tool": plan.tool.key(), + "tool_version": version, + "tool_build_identity": build_identity, + "adapter_version": ADAPTER_VERSION, + "configuration_hash": hash_paths(&plan.configuration_paths)?, + "fixture_revision": revision, + "started_at_unix_seconds": started, + "ended_at_unix_seconds": now_seconds()?, + "cold_or_warm": "cold", + "results": results + }); + write_and_validate_report(&plan.report, &report)?; + println!("wrote {}", plan.report.display()); + Ok(()) +} + +/// The pinned version identity a modeling report records, read from the same +/// surface each adapter's kernel reports already read it from. +fn modeling_version_identity(tool: ModelingTool, binary: &Path) -> Result<(String, String)> { + match tool { + ModelingTool::Bifrost => Ok(( + command_output(Command::new(binary).arg("--version")) + .unwrap_or_else(|_| "unknown".into()), + command_output(Command::new(binary).arg("--build-identity")) + .unwrap_or_else(|_| "unknown".into()), + )), + ModelingTool::Codeql => codeql_version_identity(binary), + ModelingTool::Joern => joern_version_identity(binary), + ModelingTool::Semgrep => semgrep_version_identity(binary), + } +} + #[cfg(test)] mod tests { use super::*; @@ -11647,4 +12562,515 @@ mod tests { assert_eq!(outcome, "inconclusive"); assert_eq!(raw_special_outcome(&inconclusive), Some("inconclusive")); } + + // ----------------------------------------------------------------------- + // The benchmark-controlled taint-modeling matrix. + // ----------------------------------------------------------------------- + + /// One synthetic modeling case, carrying every field the modeling + /// validators read. + fn modeling_case_value(template: &str, polarity: &str, language: &str) -> Value { + let short = template + .strip_prefix(MODELING_TEMPLATE_PREFIX) + .expect("a modeling template"); + json!({ + "id": format!("dfb-taint-{language}-model-{short}-{polarity}"), + "template_id": template, + "polarity": polarity, + "score_tier": "modeling", + "track": "taint", + "language": language, + "model_profile": MODELING_MODEL_PROFILE, + "feature_tags": ["modeled-external", "intraprocedural"], + "expected_analysis_capability": {"kind": "declared-source-activation"} + }) + } + + /// A whole balanced modeling population for one language: 24 assertions + /// over the preregistered twelve. + fn modeling_population(language: &str) -> Vec<(PathBuf, Value)> { + let mut cases = Vec::new(); + for template in MODELING_TEMPLATE_IDS { + for polarity in ["positive", "negative"] { + cases.push(( + PathBuf::from(format!( + "cases/taint/{language}/{template}-{polarity}/case.json" + )), + modeling_case_value(template, polarity, language), + )); + } + } + cases + } + + /// The twelve template IDs are the document's, unique, and all carry the + /// tier's structural prefix. + #[test] + fn modeling_templates_are_the_preregistered_twelve() { + assert_eq!(MODELING_TEMPLATE_IDS.len(), 12); + assert_eq!(MODELING_CASE_COUNT, 24); + let unique: BTreeSet<&str> = MODELING_TEMPLATE_IDS.into_iter().collect(); + assert_eq!(unique.len(), 12); + for template in MODELING_TEMPLATE_IDS { + assert!( + template.starts_with(MODELING_TEMPLATE_PREFIX), + "{template} lacks the modeling prefix" + ); + } + assert_eq!( + MODELING_TEMPLATE_IDS[0], + "dfb-template-model-declared-source" + ); + assert_eq!( + MODELING_TEMPLATE_IDS[11], + "dfb-template-model-store-separation" + ); + } + + /// Six categories of two, partitioning the twelve exactly. + #[test] + fn every_modeling_template_belongs_to_exactly_one_category() { + let mut seen: BTreeSet<&str> = BTreeSet::new(); + for category in ModelingCategory::ALL { + for template in category.templates() { + assert!(seen.insert(template), "{template} is in two categories"); + assert_eq!(modeling_category(template), Some(category)); + } + } + assert_eq!(seen, MODELING_TEMPLATE_IDS.into_iter().collect()); + assert_eq!(modeling_category("dfb-template-direct-propagation"), None); + assert_eq!( + ModelingCategory::ALL.map(ModelingCategory::key), + ["S", "P", "Z", "O", "E", "B"] + ); + } + + /// Every tool × template cell is decided. There is no scored default: an + /// undecided cell is an error, not a silent `supported`. + #[test] + fn the_modeling_partition_decides_every_tool_and_template() { + for tool in ModelingTool::ALL { + for template in MODELING_TEMPLATE_IDS { + modeling_partition_reason(tool, template) + .unwrap_or_else(|_| panic!("{} × {template} is undecided", tool.key())); + } + } + assert_eq!(MODELING_PARTITION.len(), 24); + assert!( + modeling_partition_reason(ModelingTool::Codeql, "dfb-template-chal-dispatch-table") + .is_err() + ); + } + + /// The scored-template counts are the document's partition summary, + /// expressed in templates rather than categories: Bifrost 2 of 12, Semgrep + /// 6 of 12, CodeQL and Joern 12 of 12. + #[test] + fn modeling_partition_scored_counts_match_the_preregistration() { + assert_eq!(modeling_supported_templates(ModelingTool::Bifrost).len(), 2); + assert_eq!(modeling_supported_templates(ModelingTool::Semgrep).len(), 6); + assert_eq!(modeling_supported_templates(ModelingTool::Codeql).len(), 12); + assert_eq!(modeling_supported_templates(ModelingTool::Joern).len(), 12); + } + + /// Bifrost enters with category S alone — the honest starting position the + /// preregistration states for a standalone policy CLI whose modeling + /// surface lives in an embedding. + #[test] + fn bifrost_modeling_partition_scores_category_s_only() { + assert_eq!( + modeling_supported_templates(ModelingTool::Bifrost), + ModelingCategory::SourcesAndSinks.templates().to_vec() + ); + for category in [ + ModelingCategory::Propagators, + ModelingCategory::Sanitizers, + ModelingCategory::Summaries, + ModelingCategory::EntryPoints, + ModelingCategory::Persistence, + ] { + for template in category.templates() { + assert!( + modeling_partition_reason(ModelingTool::Bifrost, template) + .unwrap() + .is_some(), + "{template} must be unsupported for Bifrost" + ); + } + } + } + + /// Semgrep CE enters with S, Z, and E — three of six, and a larger share + /// of this matrix than Bifrost, which is the whole reason the tier exists. + #[test] + fn semgrep_modeling_partition_scores_sources_sanitizers_and_entry_points() { + let mut expected = Vec::new(); + for category in [ + ModelingCategory::SourcesAndSinks, + ModelingCategory::Sanitizers, + ModelingCategory::EntryPoints, + ] { + expected.extend(category.templates()); + } + expected.sort_unstable(); + let mut scored = modeling_supported_templates(ModelingTool::Semgrep); + scored.sort_unstable(); + assert_eq!(scored, expected); + } + + /// The partition is keyed by template identity alone. No `feature_tags` + /// choice a fixture makes — and no observed result — can move a cell + /// between the scored and `unsupported` partitions. + #[test] + fn the_modeling_partition_is_tag_proof() { + let template = "dfb-template-model-opaque-propagator"; + let baseline = modeling_unsupported_reason(ModelingTool::Semgrep, template).unwrap(); + assert!(baseline.is_some()); + for tags in [ + json!(["intraprocedural"]), + json!(["interprocedural-deep", "heap-access-path"]), + json!([]), + ] { + let mut case = modeling_case_value(template, "positive", "java"); + case["feature_tags"] = tags; + case["expected_analysis_capability"]["kind"] = json!("local-taint"); + assert_eq!( + modeling_unsupported_reason( + ModelingTool::Semgrep, + case["template_id"].as_str().unwrap() + ) + .unwrap(), + baseline, + "a fixture's tags must not move a partition cell" + ); + } + // And the converse: a scored cell stays scored whatever it is tagged. + let scored = "dfb-template-model-declared-source"; + assert!( + modeling_unsupported_reason(ModelingTool::Semgrep, scored) + .unwrap() + .is_none() + ); + } + + /// Every declined cell retains a reason that names the category and the + /// pinned tool identity and carries the document's rationale verbatim. + #[test] + fn modeling_unsupported_reasons_are_retained_and_attributed() { + let reason = + modeling_unsupported_reason(ModelingTool::Bifrost, "dfb-template-model-sanitizer-kill") + .unwrap() + .expect("category Z is unsupported for Bifrost"); + assert!(reason.starts_with("category Z — declared sanitizers —")); + assert!(reason.contains("Bifrost v0.10.6")); + assert!(reason.contains("Sanitizer lowering is a future Bifrost CLI capability.")); + assert!(reason.contains("docs/modeling-matrix.md")); + for tool in ModelingTool::ALL { + for template in MODELING_TEMPLATE_IDS { + if let Some(reason) = modeling_unsupported_reason(tool, template).unwrap() { + assert!(reason.len() > 80, "a retained reason must say why"); + } + } + } + } + + /// A declined cell writes its retained capability decision and returns + /// `unsupported` without the analyzer ever being invoked. + #[test] + fn a_declined_modeling_cell_retains_evidence_without_invoking_the_tool() { + let root = unique_test_dir("dataflowbench-modeling-partition-test"); + let case = modeling_case_value("dfb-template-model-store-roundtrip", "positive", "python"); + let (outcome, reason, raw_path) = + modeling_partition_outcome(ModelingTool::Semgrep, &case, &root) + .unwrap() + .expect("category B is unsupported for Semgrep CE"); + assert_eq!(outcome, "unsupported"); + let retained: Value = serde_json::from_slice(&fs::read(&raw_path).unwrap()).unwrap(); + assert_eq!(retained["state"], "unsupported"); + assert_eq!(retained["stage"], "preregistered-modeling-partition"); + assert_eq!(retained["modeling_category"], "B"); + assert_eq!(retained["adapter"], "semgrep"); + assert_eq!(retained["reason"], json!(reason)); + assert_eq!(retained["evidence_kind"], "retained-capability-decision"); + + // A scored cell produces no decision and no evidence at all. + let scored = modeling_case_value("dfb-template-model-declared-sink", "positive", "python"); + assert!( + modeling_partition_outcome(ModelingTool::Semgrep, &scored, &root) + .unwrap() + .is_none() + ); + fs::remove_dir_all(&root).unwrap(); + } + + /// A language with no modeling cases has no modeling denominator, which is + /// different from having a zero. It validates trivially. + #[test] + fn an_absent_modeling_population_validates_trivially() { + validate_modeling_population(&[], "Java modeling population").unwrap(); + validate_modeling_cases(&[]).unwrap(); + } + + /// A whole balanced population over the preregistered twelve validates. + #[test] + fn a_balanced_modeling_population_validates() { + let cases = modeling_population("java"); + assert_eq!(cases.len(), MODELING_CASE_COUNT); + validate_modeling_population(&cases, "Java modeling population").unwrap(); + validate_modeling_cases(&cases).unwrap(); + } + + /// A partial fixture landing fails the build rather than silently reducing + /// a denominator, and an unbalanced pair fails too. + #[test] + fn an_incomplete_modeling_population_fails_validation() { + let mut short = modeling_population("javascript"); + short.truncate(22); + let error = validate_modeling_population(&short, "JavaScript modeling population") + .unwrap_err() + .to_string(); + assert!( + error.contains("must select exactly 24 assertions"), + "{error}" + ); + + let mut unbalanced = modeling_population("javascript"); + unbalanced[1].1["polarity"] = json!("positive"); + let error = validate_modeling_population(&unbalanced, "JavaScript modeling population") + .unwrap_err() + .to_string(); + assert!( + error.contains("one positive and one negative per template"), + "{error}" + ); + + let mut renamed = modeling_population("javascript"); + renamed[0].1["template_id"] = json!("dfb-template-model-invented"); + renamed[1].1["template_id"] = json!("dfb-template-model-invented"); + let error = validate_modeling_population(&renamed, "JavaScript modeling population") + .unwrap_err() + .to_string(); + assert!(error.contains("template set mismatch"), "{error}"); + } + + /// Tier isolation is structural: the modeling template prefix and the + /// `modeling` score tier imply each other, so a modeling case can never be + /// selected into a core, calibration, extension, or real-project + /// population, and a kernel template can never claim the modeling tier. + #[test] + fn the_modeling_tier_and_the_modeling_prefix_imply_each_other() { + let mut retiered = modeling_population("python"); + retiered[0].1["score_tier"] = json!("core"); + let error = validate_modeling_cases(&retiered).unwrap_err().to_string(); + assert!(error.contains("disagree"), "{error}"); + + let smuggled = vec![( + PathBuf::from("cases/taint/python/smuggled/case.json"), + json!({ + "id": "dfb-taint-python-smuggled", + "template_id": "dfb-template-direct-propagation", + "score_tier": "modeling", + "polarity": "positive", + "track": "taint", + "language": "python", + "model_profile": MODELING_MODEL_PROFILE + }), + )]; + let error = validate_modeling_cases(&smuggled).unwrap_err().to_string(); + assert!(error.contains("disagree"), "{error}"); + + let invented = vec![( + PathBuf::from("cases/taint/python/invented/case.json"), + json!({ + "id": "dfb-taint-python-invented", + "template_id": "dfb-template-model-invented", + "score_tier": "modeling", + "polarity": "positive", + "track": "taint", + "language": "python", + "model_profile": MODELING_MODEL_PROFILE + }), + )]; + let error = validate_modeling_cases(&invented).unwrap_err().to_string(); + assert!( + error.contains("not one of the twelve preregistered modeling templates"), + "{error}" + ); + } + + /// Every modeling case is `benchmark-controlled`. The tool-native profile + /// supplies no models and is never pooled with this matrix. + #[test] + fn modeling_cases_must_be_benchmark_controlled() { + let mut cases = modeling_population("java"); + cases[0].1["model_profile"] = json!("tool-native"); + let error = validate_modeling_cases(&cases).unwrap_err().to_string(); + assert!(error.contains("benchmark-controlled"), "{error}"); + } + + /// A modeling case is never swept into the frozen 118-case Bifrost smoke + /// population, whatever policy it names. + #[test] + fn a_modeling_case_is_never_smoke_selected() { + let mut case = + modeling_case_value("dfb-template-model-declared-source", "positive", "java"); + case["tool_model_references"] = json!({"bifrost": {"policy": BIFROST_JAVA_POLICY}}); + assert!(!smoke_population_case(&case)); + case["tool_model_references"] = + json!({"bifrost": {"unsupported_reason": "no external catalog"}}); + assert!(!smoke_population_case(&case)); + } + + /// The generated scorecards order `modeling` alongside the existing tiers. + /// A tier absent from this list would be silently dropped. + #[test] + fn the_result_tier_order_carries_modeling() { + assert!(SCORE_TIER_ORDER.contains(&"modeling")); + } + + /// This pull request is infrastructure only: the corpus carries no + /// modeling case, and every modeling run therefore fails fast rather than + /// writing an empty report. + #[test] + fn the_checked_in_corpus_carries_no_modeling_case() { + for path in case_paths() { + let case: Value = serde_json::from_str(&fs::read_to_string(&path).unwrap()).unwrap(); + assert_ne!( + case["score_tier"], + "modeling", + "{} is a modeling case; this PR is infrastructure only", + path.display() + ); + } + for language in [ + ModelingLanguage::Java, + ModelingLanguage::Javascript, + ModelingLanguage::Python, + ] { + assert!(select_modeling_cases(language).unwrap().is_empty()); + } + } + + /// With no population, a run fails with a clear error naming the language + /// and never writes a report. + #[test] + fn a_modeling_run_without_a_population_fails_fast() { + for (tool, binary) in [ + (ModelingTool::Bifrost, "bifrost"), + (ModelingTool::Codeql, "codeql"), + (ModelingTool::Joern, "joern"), + (ModelingTool::Semgrep, "semgrep"), + ] { + let error = run_modeling(tool, Path::new(binary), ModelingLanguage::Java, None) + .unwrap_err() + .to_string(); + assert!( + error.starts_with("no modeling population for java"), + "{error}" + ); + assert!(!ModelingLanguage::Java.report(tool).exists()); + } + } + + /// A Bifrost modeling policy must make the model load-bearing: the kernel + /// policies' optimistic unmodeled-call default would decide a category P + /// or O cell without the declaration ever being read. + #[test] + fn a_bifrost_modeling_policy_must_require_the_model() { + let optimistic = + "(analysis :type taint :mode may :call-modeling (call-modeling :unmodeled optimistic))"; + let error = + require_bifrost_modeling_load_bearing(optimistic, "adapters/bifrost/policies/x.rqlp") + .unwrap_err() + .to_string(); + assert!(error.contains("require-model"), "{error}"); + + let silent = "(analysis :type taint :mode may)"; + assert!( + require_bifrost_modeling_load_bearing(silent, "adapters/bifrost/policies/x.rqlp") + .is_err() + ); + + let load_bearing = "(analysis :type taint :mode may :call-modeling (call-modeling :unmodeled require-model))"; + require_bifrost_modeling_load_bearing(load_bearing, "adapters/bifrost/policies/x.rqlp") + .unwrap(); + assert_eq!(BIFROST_MODELING_CALL_MODELING, "require-model"); + } + + /// A Semgrep modeling rule must disable the engine's default pass-through, + /// which the preregistration verified against the pinned CE binary. + #[test] + fn a_semgrep_modeling_rule_must_assume_safe_functions() { + let permissive = "rules:\n - id: dfb-model\n mode: taint\n"; + let error = + require_semgrep_modeling_load_bearing(permissive, "adapters/semgrep/rules/x.yaml") + .unwrap_err() + .to_string(); + assert!( + error.contains("taint_assume_safe_functions: true"), + "{error}" + ); + + let load_bearing = "rules:\n - id: dfb-model\n mode: taint\n options:\n taint_assume_safe_functions: true\n"; + require_semgrep_modeling_load_bearing(load_bearing, "adapters/semgrep/rules/x.yaml") + .unwrap(); + assert_eq!( + SEMGREP_MODELING_ASSUME_SAFE_OPTION, + "taint_assume_safe_functions: true" + ); + } + + /// The model-artifact, report, and raw-evidence paths the language pull + /// requests populate. Twelve distinct artifacts, one per tool per language. + #[test] + fn modeling_artifact_and_report_paths_follow_the_convention() { + let mut artifacts = BTreeSet::new(); + for tool in ModelingTool::ALL { + for language in [ + ModelingLanguage::Java, + ModelingLanguage::Javascript, + ModelingLanguage::Python, + ] { + assert!(artifacts.insert(language.artifact(tool))); + assert_eq!( + language.report(tool), + PathBuf::from(format!( + "reports/{}-{}-modeling.json", + tool.key(), + language.key() + )) + ); + assert_eq!( + language.raw_dir(tool), + PathBuf::from(format!( + "reports/raw/{}-{}-modeling", + tool.key(), + language.key() + )) + ); + } + } + assert_eq!(artifacts.len(), 12); + assert_eq!( + ModelingLanguage::Java.artifact(ModelingTool::Bifrost), + "adapters/bifrost/policies/model-java.rqlp" + ); + assert_eq!( + ModelingLanguage::Python.artifact(ModelingTool::Semgrep), + "adapters/semgrep/rules/model-python.yaml" + ); + assert_eq!( + ModelingLanguage::Javascript.artifact(ModelingTool::Joern), + "adapters/joern/semantics/model-javascript.semantics" + ); + assert_eq!( + ModelingLanguage::Javascript.artifact(ModelingTool::Codeql), + "adapters/codeql/javascript/queries/JavaScriptModeling.ql" + ); + // No modeling artifact is committed yet; every one arrives with the + // language pull request that authors its declarations. + for artifact in artifacts { + assert!(!Path::new(artifact).exists(), "{artifact} exists already"); + } + } } From be31dde59706fd3a69d1c07f97c5ba518e734593 Mon Sep 17 00:00:00 2001 From: David Baker Effendi Date: Wed, 26 Aug 2026 14:58:48 +0200 Subject: [PATCH 3/3] Populate the Java taint-modeling matrix on four analyzers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wave M1's first language. Twenty-four assertions — the twelve preregistered templates x positive/negative — under cases/taint/java/model-*, four per-adapter artifacts encoding the same analyzer-neutral declarations natively, the scored execution arm for all four modeling runners, and the four runs. No template proved unimplementable as preregistered and no partition cell moved. Where a run disagreed with what docs/modeling-matrix.md expected, the disagreement is published as observed and carried in docs/java-modeling.md as a *proposed* amendment for a separate, dated change: a cell revised from a result is a result being relabelled. Outcomes, on four different denominators that are not comparable to one another and are never pooled with the propagation kernel: Bifrost 4/4 on the one category its partition scores and 20 preregistered `unsupported`; CodeQL 24/24; Joern 20/24; Semgrep CE 11/12 scored and 12 `unsupported`. No `inconclusive` and no `runner-error` anywhere. Load-bearing verification is part of the run contract, and every scored tool has a demonstrated counterfactual: removing one declaration from the committed artifact removes the finding, with a control cell that depends on a different declaration left unchanged. One of them came back negative and is reported that way — Semgrep CE's required `taint_assume_safe_functions: true` also suppresses the flow through the *declared* sanitizer, so on a category-Z fixture the option rather than the declaration decides the cell. A crossed four-run probe is the evidence. Category Z is still scored with the option on, because that is what the preregistration and the runner gate require, and template 6's positive is published as the false negative it is rather than recovered by declaring a propagator this partition does not award CE. Joern's two false positives are separated from "the model was ignored" by their own probes: the `Opaque.select` mapping is acted on but its index is not enforced, and a `FlowPath` access-path destination can be written but does not discriminate the declared field from its sibling. Reconciliation on this tier is source-anchored as well as sink-anchored, because a modeling fixture carries both halves of its pair in one type by construction and category E's handlers need no caller — so the declared handler's flow is present in the negative's fixture. A finding counts only when it lies in the region its case's own source anchor governs and on a callsite of its anchored sink function; an unmatched finding is the pair's other entity, fully attributable, and normalizes to `not-reached` with the count retained rather than to the kernels' `inconclusive`. Two adapter-hygiene points that the freeze depends on. The Semgrep modeling rules share the rules directory but are excluded from the kernel configuration hash, so a modeling wave landing for a new language does not move a hash that describes nothing about the kernel a retained report is evidence for. And Java's CodeQL modeling query joins the adapter's root pack, which is the Java pack; the infra's schematic `adapters/codeql/java/queries/` has no qlpack to resolve `codeql/java-all` from. The eight new report and raw-evidence paths collide with nothing the v0.4.0 freeze binds, no pre-existing case or report is touched, and the smoke population stays 118. Co-Authored-By: Claude Fable 5 --- adapters/bifrost/README.md | 44 + adapters/bifrost/policies/model-java.rqlp | 14 + adapters/codeql/README.md | 69 + adapters/codeql/queries/JavaModeling.ql | 177 ++ adapters/joern/README.md | 102 +- adapters/joern/queries/modeling.sc | 154 ++ adapters/joern/semantics/model-java.semantics | 9 + adapters/semgrep/README.md | 84 +- adapters/semgrep/rules/model-java.yaml | 58 + .../ModelDeclaredSinkNegative.java | 17 + .../model-declared-sink-negative/case.json | 64 + .../ModelDeclaredSinkPositive.java | 17 + .../model-declared-sink-positive/case.json | 63 + .../ModelDeclaredSourceNegative.java | 19 + .../model-declared-source-negative/case.json | 64 + .../ModelDeclaredSourcePositive.java | 19 + .../model-declared-source-positive/case.json | 63 + .../Handler.java | 13 + .../case.json | 64 + .../Handler.java | 13 + .../case.json | 63 + .../Handler.java | 13 + .../case.json | 64 + .../Handler.java | 13 + .../case.json | 63 + .../ModelOpaquePropagatorNegative.java | 39 + .../case.json | 64 + .../ModelOpaquePropagatorPositive.java | 39 + .../case.json | 63 + .../ModelPropagatorPositionNegative.java | 29 + .../case.json | 64 + .../ModelPropagatorPositionPositive.java | 29 + .../case.json | 63 + .../ModelSanitizerKillNegative.java | 19 + .../model-sanitizer-kill-negative/case.json | 64 + .../ModelSanitizerKillPositive.java | 19 + .../model-sanitizer-kill-positive/case.json | 63 + .../ModelSanitizerSelectivityNegative.java | 23 + .../case.json | 64 + .../ModelSanitizerSelectivityPositive.java | 23 + .../case.json | 63 + .../ModelStoreRoundtripNegative.java | 25 + .../model-store-roundtrip-negative/case.json | 65 + .../ModelStoreRoundtripPositive.java | 25 + .../model-store-roundtrip-positive/case.json | 64 + .../ModelStoreSeparationNegative.java | 29 + .../model-store-separation-negative/case.json | 65 + .../ModelStoreSeparationPositive.java | 29 + .../model-store-separation-positive/case.json | 64 + .../ModelSummaryFieldNegative.java | 24 + .../model-summary-field-negative/case.json | 67 + .../ModelSummaryFieldPositive.java | 24 + .../model-summary-field-positive/case.json | 66 + .../Bridge.java | 11 + .../ModelSummaryThroughNegative.java | 13 + .../model-summary-through-negative/case.json | 66 + .../Bridge.java | 11 + .../ModelSummaryThroughPositive.java | 13 + .../model-summary-through-positive/case.json | 65 + docs/adapters.md | 43 +- docs/java-kernel.md | 5 + docs/java-modeling.md | 383 +++++ docs/milestones.md | 12 + reports/bifrost-java-modeling.json | 418 +++++ reports/codeql-java-modeling.json | 404 +++++ reports/joern-java-modeling.json | 424 +++++ ...int-java-model-declared-sink-negative.json | 1 + ...int-java-model-declared-sink-positive.json | 1 + ...t-java-model-declared-source-negative.json | 1 + ...t-java-model-declared-source-positive.json | 1 + ...ypoint-parameter-negative-unsupported.json | 13 + ...ypoint-parameter-positive-unsupported.json | 13 + ...oint-selectivity-negative-unsupported.json | 13 + ...oint-selectivity-positive-unsupported.json | 13 + ...paque-propagator-negative-unsupported.json | 13 + ...paque-propagator-positive-unsupported.json | 13 + ...pagator-position-negative-unsupported.json | 13 + ...pagator-position-positive-unsupported.json | 13 + ...l-sanitizer-kill-negative-unsupported.json | 13 + ...l-sanitizer-kill-positive-unsupported.json | 13 + ...izer-selectivity-negative-unsupported.json | 13 + ...izer-selectivity-positive-unsupported.json | 13 + ...-store-roundtrip-negative-unsupported.json | 13 + ...-store-roundtrip-positive-unsupported.json | 13 + ...store-separation-negative-unsupported.json | 13 + ...store-separation-positive-unsupported.json | 13 + ...el-summary-field-negative-unsupported.json | 13 + ...el-summary-field-positive-unsupported.json | 13 + ...-summary-through-negative-unsupported.json | 13 + ...-summary-through-positive-unsupported.json | 13 + ...va-model-declared-sink-negative.sarif.json | 1 + ...va-model-declared-sink-positive.sarif.json | 1 + ...-model-declared-source-negative.sarif.json | 1 + ...-model-declared-source-positive.sarif.json | 1 + ...l-entrypoint-parameter-negative.sarif.json | 1 + ...l-entrypoint-parameter-positive.sarif.json | 1 + ...entrypoint-selectivity-negative.sarif.json | 1 + ...entrypoint-selectivity-positive.sarif.json | 1 + ...odel-opaque-propagator-negative.sarif.json | 1 + ...odel-opaque-propagator-positive.sarif.json | 1 + ...el-propagator-position-negative.sarif.json | 1 + ...el-propagator-position-positive.sarif.json | 1 + ...a-model-sanitizer-kill-negative.sarif.json | 1 + ...a-model-sanitizer-kill-positive.sarif.json | 1 + ...-sanitizer-selectivity-negative.sarif.json | 1 + ...-sanitizer-selectivity-positive.sarif.json | 1 + ...-model-store-roundtrip-negative.sarif.json | 1 + ...-model-store-roundtrip-positive.sarif.json | 1 + ...model-store-separation-negative.sarif.json | 1 + ...model-store-separation-positive.sarif.json | 1 + ...va-model-summary-field-negative.sarif.json | 1 + ...va-model-summary-field-positive.sarif.json | 1 + ...-model-summary-through-negative.sarif.json | 1 + ...-model-summary-through-positive.sarif.json | 1 + ...int-java-model-declared-sink-negative.json | 1 + ...int-java-model-declared-sink-positive.json | 1 + ...t-java-model-declared-source-negative.json | 1 + ...t-java-model-declared-source-positive.json | 1 + ...a-model-entrypoint-parameter-negative.json | 1 + ...a-model-entrypoint-parameter-positive.json | 1 + ...model-entrypoint-selectivity-negative.json | 1 + ...model-entrypoint-selectivity-positive.json | 1 + ...java-model-opaque-propagator-negative.json | 1 + ...java-model-opaque-propagator-positive.json | 1 + ...va-model-propagator-position-negative.json | 1 + ...va-model-propagator-position-positive.json | 1 + ...nt-java-model-sanitizer-kill-negative.json | 1 + ...nt-java-model-sanitizer-kill-positive.json | 1 + ...-model-sanitizer-selectivity-negative.json | 1 + ...-model-sanitizer-selectivity-positive.json | 1 + ...t-java-model-store-roundtrip-negative.json | 1 + ...t-java-model-store-roundtrip-positive.json | 1 + ...-java-model-store-separation-negative.json | 1 + ...-java-model-store-separation-positive.json | 1 + ...int-java-model-summary-field-negative.json | 1 + ...int-java-model-summary-field-positive.json | 1 + ...t-java-model-summary-through-negative.json | 1 + ...t-java-model-summary-through-positive.json | 1 + ...int-java-model-declared-sink-negative.json | 1 + ...int-java-model-declared-sink-positive.json | 1 + ...t-java-model-declared-source-negative.json | 1 + ...t-java-model-declared-source-positive.json | 1 + ...a-model-entrypoint-parameter-negative.json | 1 + ...a-model-entrypoint-parameter-positive.json | 1 + ...model-entrypoint-selectivity-negative.json | 1 + ...model-entrypoint-selectivity-positive.json | 1 + ...paque-propagator-negative-unsupported.json | 13 + ...paque-propagator-positive-unsupported.json | 13 + ...pagator-position-negative-unsupported.json | 13 + ...pagator-position-positive-unsupported.json | 13 + ...nt-java-model-sanitizer-kill-negative.json | 1 + ...nt-java-model-sanitizer-kill-positive.json | 1 + ...-model-sanitizer-selectivity-negative.json | 1 + ...-model-sanitizer-selectivity-positive.json | 1 + ...-store-roundtrip-negative-unsupported.json | 13 + ...-store-roundtrip-positive-unsupported.json | 13 + ...store-separation-negative-unsupported.json | 13 + ...store-separation-positive-unsupported.json | 13 + ...el-summary-field-negative-unsupported.json | 13 + ...el-summary-field-positive-unsupported.json | 13 + ...-summary-through-negative-unsupported.json | 13 + ...-summary-through-positive-unsupported.json | 13 + reports/semgrep-java-modeling.json | 402 +++++ src/main.rs | 1492 +++++++++++++++-- 164 files changed, 6660 insertions(+), 200 deletions(-) create mode 100644 adapters/bifrost/policies/model-java.rqlp create mode 100644 adapters/codeql/queries/JavaModeling.ql create mode 100644 adapters/joern/queries/modeling.sc create mode 100644 adapters/joern/semantics/model-java.semantics create mode 100644 adapters/semgrep/rules/model-java.yaml create mode 100644 cases/taint/java/model-declared-sink-negative/ModelDeclaredSinkNegative.java create mode 100644 cases/taint/java/model-declared-sink-negative/case.json create mode 100644 cases/taint/java/model-declared-sink-positive/ModelDeclaredSinkPositive.java create mode 100644 cases/taint/java/model-declared-sink-positive/case.json create mode 100644 cases/taint/java/model-declared-source-negative/ModelDeclaredSourceNegative.java create mode 100644 cases/taint/java/model-declared-source-negative/case.json create mode 100644 cases/taint/java/model-declared-source-positive/ModelDeclaredSourcePositive.java create mode 100644 cases/taint/java/model-declared-source-positive/case.json create mode 100644 cases/taint/java/model-entrypoint-parameter-negative/Handler.java create mode 100644 cases/taint/java/model-entrypoint-parameter-negative/case.json create mode 100644 cases/taint/java/model-entrypoint-parameter-positive/Handler.java create mode 100644 cases/taint/java/model-entrypoint-parameter-positive/case.json create mode 100644 cases/taint/java/model-entrypoint-selectivity-negative/Handler.java create mode 100644 cases/taint/java/model-entrypoint-selectivity-negative/case.json create mode 100644 cases/taint/java/model-entrypoint-selectivity-positive/Handler.java create mode 100644 cases/taint/java/model-entrypoint-selectivity-positive/case.json create mode 100644 cases/taint/java/model-opaque-propagator-negative/ModelOpaquePropagatorNegative.java create mode 100644 cases/taint/java/model-opaque-propagator-negative/case.json create mode 100644 cases/taint/java/model-opaque-propagator-positive/ModelOpaquePropagatorPositive.java create mode 100644 cases/taint/java/model-opaque-propagator-positive/case.json create mode 100644 cases/taint/java/model-propagator-position-negative/ModelPropagatorPositionNegative.java create mode 100644 cases/taint/java/model-propagator-position-negative/case.json create mode 100644 cases/taint/java/model-propagator-position-positive/ModelPropagatorPositionPositive.java create mode 100644 cases/taint/java/model-propagator-position-positive/case.json create mode 100644 cases/taint/java/model-sanitizer-kill-negative/ModelSanitizerKillNegative.java create mode 100644 cases/taint/java/model-sanitizer-kill-negative/case.json create mode 100644 cases/taint/java/model-sanitizer-kill-positive/ModelSanitizerKillPositive.java create mode 100644 cases/taint/java/model-sanitizer-kill-positive/case.json create mode 100644 cases/taint/java/model-sanitizer-selectivity-negative/ModelSanitizerSelectivityNegative.java create mode 100644 cases/taint/java/model-sanitizer-selectivity-negative/case.json create mode 100644 cases/taint/java/model-sanitizer-selectivity-positive/ModelSanitizerSelectivityPositive.java create mode 100644 cases/taint/java/model-sanitizer-selectivity-positive/case.json create mode 100644 cases/taint/java/model-store-roundtrip-negative/ModelStoreRoundtripNegative.java create mode 100644 cases/taint/java/model-store-roundtrip-negative/case.json create mode 100644 cases/taint/java/model-store-roundtrip-positive/ModelStoreRoundtripPositive.java create mode 100644 cases/taint/java/model-store-roundtrip-positive/case.json create mode 100644 cases/taint/java/model-store-separation-negative/ModelStoreSeparationNegative.java create mode 100644 cases/taint/java/model-store-separation-negative/case.json create mode 100644 cases/taint/java/model-store-separation-positive/ModelStoreSeparationPositive.java create mode 100644 cases/taint/java/model-store-separation-positive/case.json create mode 100644 cases/taint/java/model-summary-field-negative/ModelSummaryFieldNegative.java create mode 100644 cases/taint/java/model-summary-field-negative/case.json create mode 100644 cases/taint/java/model-summary-field-positive/ModelSummaryFieldPositive.java create mode 100644 cases/taint/java/model-summary-field-positive/case.json create mode 100644 cases/taint/java/model-summary-through-negative/Bridge.java create mode 100644 cases/taint/java/model-summary-through-negative/ModelSummaryThroughNegative.java create mode 100644 cases/taint/java/model-summary-through-negative/case.json create mode 100644 cases/taint/java/model-summary-through-positive/Bridge.java create mode 100644 cases/taint/java/model-summary-through-positive/ModelSummaryThroughPositive.java create mode 100644 cases/taint/java/model-summary-through-positive/case.json create mode 100644 docs/java-modeling.md create mode 100644 reports/bifrost-java-modeling.json create mode 100644 reports/codeql-java-modeling.json create mode 100644 reports/joern-java-modeling.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-negative.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-positive.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-negative.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-positive.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json create mode 100644 reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-positive.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-negative.sarif.json create mode 100644 reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-positive.sarif.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-positive.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-negative.json create mode 100644 reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-negative.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-negative.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json create mode 100644 reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json create mode 100644 reports/semgrep-java-modeling.json diff --git a/adapters/bifrost/README.md b/adapters/bifrost/README.md index 4ce5b48..1ff0012 100644 --- a/adapters/bifrost/README.md +++ b/adapters/bifrost/README.md @@ -529,3 +529,47 @@ tracks the final cross-language production-taint acceptance work; the defects and coverage gaps this population exposes are tracked as bifrost-dev #2637 (Ruby), #2638 (Rust `gap_contract`), #2639 (`element-object`), and #2640 (nested-callable roots). + +## Java taint-modeling matrix + +`run-bifrost-modeling --language java` runs the twenty-four assertions of the +[benchmark-controlled taint-modeling matrix](../../docs/modeling-matrix.md) +against `policies/model-java.rqlp`, writing `reports/bifrost-java-modeling.json` +with retained evidence under `reports/raw/bifrost-java-modeling/`. It is its own +population on its own `modeling` score tier: never in a core denominator, never +pooled with the Java propagation kernel, never added to a kernel number. + +The preregistered partition awards Bifrost **one of six categories** — declared +sources and sinks — and that is what the policy declares, and all it declares. +The other five categories are `unsupported` with the document's rationale +retained verbatim, decided from the template ID *before* the binary is invoked, +so twenty of the twenty-four assertions never reach the CLI at all. Two of those +five are the README's own long-standing statements — sanitizer lowering is a +future CLI capability, and external semantic-model activation requires an +embedding with an explicit catalog — and three are cells the preregistration +could not verify against the pinned build and therefore recorded as unsupported +until shown otherwise. Declining a category is coverage, never a negative, and +never a false negative. + +The modeling policy differs from every committed kernel policy in one +load-bearing way: it sets `:call-modeling (call-modeling :unmodeled +require-model)` where the kernels set `optimistic`. Under the optimistic default +an unmodeled call may pass taint through, which would decide a propagator cell +without the declaration ever being read. The runner refuses a modeling policy +that does not set `require-model`, and refuses one that still names +`optimistic`. **v0.10.6 accepts `require-model`** — the first thing this wave +established, since the preregistration could not. + +The policy's own configuration hash is over `model-java.rqlp` alone. No kernel +policy, and no kernel report's hash, is touched by it. + +The v0.4.0-era run of this slice produces 2 `reached`, 2 `not-reached`, and 20 +`unsupported` results: **category S is 4/4**, with two true positives, two true +negatives, and neither undeclared sibling (`Config.fetchLocal`, `Audit.discard`) +picked up. The load-bearing counterfactual is retained as a documented probe — +removing the `Config.fetchRemote` source entry turns template 1's positive from +one finding to none while template 2's positive is unchanged. + +See [the Java modeling report](../../docs/java-modeling.md) for the per-template +realizations, the full observed outcomes, and the proposed amendments this run +supports. diff --git a/adapters/bifrost/policies/model-java.rqlp b/adapters/bifrost/policies/model-java.rqlp new file mode 100644 index 0000000..54524e3 --- /dev/null +++ b/adapters/bifrost/policies/model-java.rqlp @@ -0,0 +1,14 @@ +(policy + :schema-version 1 + :id "dataflowbench.taint.model-java" + :name "DataFlowBench Java taint-modeling matrix" + :message "A benchmark-declared model carried input to the declared sink" + :severity warning + :analysis (analysis :type taint :mode may + :call-modeling (call-modeling :unmodeled require-model) + :sources (endpoint-set :entries [ + (source :id input :display-name "benchmark input" :categories [input.user-controlled] :selector (rql :schema-version 1 (language java (call :callee (name "dfb_source")))) :bind return-value :labels [attacker-controlled]) + (source :id declared-source :display-name "Config.fetchRemote" :categories [input.user-controlled] :selector (rql :schema-version 1 (language java (call :callee (name "fetchRemote")))) :bind return-value :labels [attacker-controlled])]) + :sinks (endpoint-set :entries [ + (sink :id sink :display-name "benchmark sink" :categories [data.sensitive] :selector (rql :schema-version 1 (language java (call :callee (name "dfb_sink")))) :dangerous-operand (argument :index 0) :accepts [attacker-controlled]) + (sink :id declared-sink :display-name "Audit.record" :categories [data.sensitive] :selector (rql :schema-version 1 (language java (call :callee (name "record")))) :dangerous-operand (argument :index 0) :accepts [attacker-controlled])])) ) diff --git a/adapters/codeql/README.md b/adapters/codeql/README.md index 484bfc1..bc72bb8 100644 --- a/adapters/codeql/README.md +++ b/adapters/codeql/README.md @@ -799,3 +799,72 @@ array-element positive, and exception-catch positive; the loop-carried negative is a false positive. No special or error outcomes occurred. Every Python case uses an isolated cold database, with no database or compiled fixture reused across the pair. + +## Taint-modeling matrix + +`run-codeql-modeling --language ` runs that language's twenty-four +assertions of the +[benchmark-controlled taint-modeling matrix](../../docs/modeling-matrix.md), +writing `reports/codeql--modeling.json` with retained evidence under +`reports/raw/codeql--modeling/`. Java is wave M1's first language; see +[the Java modeling report](../../docs/java-modeling.md). + +CodeQL enters this matrix with **six of six categories scored**, which is +unsurprising and is not a ranking: a query language whose data-flow +configuration *is* a model declaration surface has no category to decline. The +interesting question here is not whether it can be told, but whether activation +produces the modeled semantics rather than something adjacent to them. + +The design the adapter already states — *the query owns the CodeQL model; the +case metadata remains analyzer neutral* — holds unchanged. One +`Modeling.ql` per language carries all six categories in one +`DataFlow::ConfigSig`: + +| Category | `ConfigSig` member | +| --- | --- | +| S — sources and sinks | `isSource` / `isSink` over the declared type-plus-member | +| P — propagators | `isAdditionalFlowStep` from the declared argument position to the call | +| Z — sanitizers | `isBarrier` on the declared input position | +| O — summaries | `isAdditionalFlowStep`, with template 8's step landing on reads of the declared field of the declared argument, and the explicit no-flow summaries encoded as barriers | +| E — entry points | `isSource` on the parameter node of an uncalled declared method | +| B — persistence | paired `isAdditionalFlowStep` clauses conditioned on equal constant keys and on the store identity | + +No data extension is used. The models-as-data alternative for category O is +available in the pinned packs but is API-graph-keyed, and its binding to +fixture-local types stays unverified; the pack-predicate encoding is the +primary one and does not depend on it. + +Java's modeling query is `queries/JavaModeling.ql`, beside `JavaKernel.ql`, +because Java's CodeQL pack *is* the adapter root: `qlpack.yml` declares +`dataflowbench/codeql-java`. A query under a `java/` subdirectory would resolve +no `codeql/java-all` dependency, since there is no pack there. Every other +language's modeling query sits inside that language's own pack directory. This +is a location, not a declaration surface. + +The per-case machinery is the kernel's, unchanged: one cold database per case +from the same traced extraction, `database analyze` to SARIF, and the same +execution-error check. Only the normalization differs, because a modeling +fixture carries both halves of its pair by construction — see +[anchor reconciliation on this tier](../../docs/java-modeling.md#anchor-reconciliation-on-this-tier). + +No modeling query enters a kernel report's `configuration_hash`: a kernel hash +is built from the queries the selected *cases* name, and no core case names a +modeling query. + +### Observed: Java + +`reports/codeql-java-modeling.json`, CLI 2.26.3, 24 results: 12 `reached` and +12 `not-reached`, **24/24 correct** — twelve true positives, twelve true +negatives, no false positive, no false negative, no `inconclusive`, and no +`runner-error`. Both cells the preregistration flagged as needing +implementation-time verification are answered: template 8's store-through +summary and category B's keyed and instance-bound roundtrip. + +The load-bearing counterfactual is a documented probe: removing only the +`Opaque.carry` `isAdditionalFlowStep` clause turns template 3's positive from +one result to none, while template 4's positive — which takes the separate +`Opaque.select` step — is unchanged. That is also the check that template 3 is +doing its job, since the reflective body it routes through is the construct the +v0.4.0 freeze establishes no engine follows unaided. + +See [the Java modeling report](../../docs/java-modeling.md). diff --git a/adapters/codeql/queries/JavaModeling.ql b/adapters/codeql/queries/JavaModeling.ql new file mode 100644 index 0000000..33b1b3b --- /dev/null +++ b/adapters/codeql/queries/JavaModeling.ql @@ -0,0 +1,177 @@ +/** + * @name DataFlowBench Java taint-modeling matrix + * @description Encodes the twelve benchmark-supplied model declarations of + * docs/modeling-matrix.md natively in CodeQL's data-flow + * configuration surface, for the Java modeling population. + * @kind path-problem + * @problem.severity warning + * @precision high + * @id dataflowbench/java-taint-modeling + * @tags security + */ + +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.TaintTracking + +/** + * Entity identity, as the model declaration language defines it: a declaring + * type plus a member name. Binding is never by name shape and never by a + * substring, so `Audit.record` says nothing about `Audit.discard`. + */ +predicate modelCall(MethodCall call, string type, string member) { + call.getMethod().getDeclaringType().getName() = type and + call.getMethod().getName() = member +} + +/** The string constant a store call is keyed by. */ +predicate storeKey(MethodCall call, string key) { + call.getArgument(0).(CompileTimeConstantExpr).getStringValue() = key +} + +/** + * Whether two store calls address the same store identity. + * + * Template 11 binds the store to the type: `Store.put` and `Store.get` are + * static, so neither call carries an instance receiver — a static call's + * qualifier is the `TypeAccess`, never a variable. Template 12 binds it to the + * receiver instance, so the two calls must name the same variable. + */ +predicate sameStore(MethodCall put, MethodCall get) { + put.getQualifier().(VarAccess).getVariable() = get.getQualifier().(VarAccess).getVariable() + or + not put.getQualifier() instanceof VarAccess and not get.getQualifier() instanceof VarAccess +} + +module DataFlowBenchModelingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + // The benchmark's own canonical source. Every fixture that is not itself a + // declared-source assertion starts here. + exists(MethodCall call | + call.getMethod().getName() = "dfb_source" and + source.asExpr() = call + ) + or + // Template 1 — role `source`, entity `Config.fetchRemote`, out: return. + // The undeclared sibling `Config.fetchLocal` is deliberately absent. + exists(MethodCall call | + modelCall(call, "Config", "fetchRemote") and + source.asExpr() = call + ) + or + // Templates 9 and 10 — role `entry-point`, entities `Handler.onRequest` + // and `Handler.onDeclared`, in: 0 tainted on entry. Neither method is + // called from anywhere in its fixture; CodeQL's data flow does not require + // a source to be reachable from a call-graph root. The undeclared siblings + // `onIgnored` and `onUndeclared` are deliberately absent. + exists(Method handler | + handler.getDeclaringType().getName() = "Handler" and + handler.getName() = ["onRequest", "onDeclared"] and + source.asParameter() = handler.getParameter(0) + ) + } + + predicate isSink(DataFlow::Node sink) { + // The benchmark's own canonical sink. + exists(MethodCall call | + call.getMethod().getName() = "dfb_sink" and + sink.asExpr() = call.getArgument(0) + ) + or + // Template 2 — role `sink`, entity `Audit.record`, in: 0. The undeclared + // sibling `Audit.discard` is deliberately absent. + exists(MethodCall call | + modelCall(call, "Audit", "record") and + sink.asExpr() = call.getArgument(0) + ) + } + + predicate isBarrier(DataFlow::Node node) { + // Templates 5 and 6 — role `sanitizer`, entity `Clean.scrub`, in: 0. + // `Clean.sanitize` is a sibling with the same identity body and a name at + // least as sanitizer-shaped, and it is not declared. + exists(MethodCall call | + modelCall(call, "Clean", "scrub") and + node.asExpr() = call.getArgument(0) + ) + or + // The explicit no-flow declarations the model language allows where a tool + // has one: template 3's `Opaque.block` and template 7's `Bridge.hold`. + // Both bodies say flow — `hold`'s is the identity function — so without + // these clauses the query would report the body's semantics rather than + // the summary's, which is exactly the distinction category O exists to + // make observable. + exists(MethodCall call | + modelCall(call, "Opaque", "block") and + node.asExpr() = call.getArgument(0) + ) + or + exists(MethodCall call | + modelCall(call, "Bridge", "hold") and + node.asExpr() = call.getArgument(0) + ) + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + // Template 3 — role `propagator`, entity `Opaque.carry`, in: 0, out: return. + exists(MethodCall call | + modelCall(call, "Opaque", "carry") and + node1.asExpr() = call.getArgument(0) and + node2.asExpr() = call + ) + or + // Template 4 — role `propagator`, entity `Opaque.select`, in: 1, out: return. + // Positional fidelity is native: the step names argument 1 specifically, so + // taint at the undeclared position 0 never takes it. + exists(MethodCall call | + modelCall(call, "Opaque", "select") and + node1.asExpr() = call.getArgument(1) and + node2.asExpr() = call + ) + or + // Template 7 — role `summary`, entity `Bridge.pass`, in: 0, out: return. + exists(MethodCall call | + modelCall(call, "Bridge", "pass") and + node1.asExpr() = call.getArgument(0) and + node2.asExpr() = call + ) + or + // Template 8 — role `summary`, entity `Bridge.deposit`, in: 0, + // out: `1.payload`. The output position is a heap location, so the step + // lands on the reads of that field of that object rather than on a return + // value. `deposit`'s body writes nothing, so the field's contents come + // from this declaration or from nowhere, and the sibling field `spare` + // takes no step. + exists(MethodCall call, FieldRead read | + modelCall(call, "Bridge", "deposit") and + read.getField().getName() = "payload" and + read.getQualifier().(VarAccess).getVariable() = + call.getArgument(1).(VarAccess).getVariable() and + node1.asExpr() = call.getArgument(0) and + node2.asExpr() = read + ) + or + // Templates 11 and 12 — roles `store-write` and `store-read` sharing one + // store identity. `Store.put` binds in: 1 under key: 0; `Store.get` binds + // out: return under key: 0. The two close a roundtrip only when the key + // constants agree and the store identities agree, which is what the + // field-separation and object-separation negatives test. + exists(MethodCall put, MethodCall get, string key | + modelCall(put, "Store", "put") and + modelCall(get, "Store", "get") and + storeKey(put, key) and + storeKey(get, key) and + sameStore(put, get) and + node1.asExpr() = put.getArgument(1) and + node2.asExpr() = get + ) + } +} + +module DataFlowBenchModelingFlow = TaintTracking::Global; + +import DataFlowBenchModelingFlow::PathGraph + +from DataFlowBenchModelingFlow::PathNode source, DataFlowBenchModelingFlow::PathNode sink +where DataFlowBenchModelingFlow::flowPath(source, sink) +select sink.getNode(), source, sink, "A benchmark-declared model carried input to the declared sink." diff --git a/adapters/joern/README.md b/adapters/joern/README.md index 15aa943..6f44910 100644 --- a/adapters/joern/README.md +++ b/adapters/joern/README.md @@ -673,9 +673,12 @@ denominator either. Absence of a slice is not a Joern result about C. - The `benchmark-controlled` profile applies: the query is given the same source and sink identities the Bifrost and CodeQL kernels are given, and nothing from Joern's own default source/sink models is used. -- Only the OSS data-flow engine's default semantics are used. No custom - semantics, no additional propagation or sanitizer models, and no engine - configuration are supplied. +- Only the OSS data-flow engine's default semantics are used **by the + kernels**. No custom semantics, no additional propagation or sanitizer + models, and no engine configuration are supplied to `kernel.sc`. The + taint-modeling matrix is the one population that supplies semantics, through + its own `modeling.sc` and its own per-language semantics file; it never + touches the kernel script and is never pooled with a kernel population. - The source is the source call's return value; the sink is the sink call's positional arguments. Receiver arguments are excluded. - One CPG per case, always built cold from source; no CPG is reused between @@ -689,3 +692,96 @@ denominator either. Absence of a slice is not a Joern result about C. Joern results are not a proxy for any other adapter's population, and no Joern population is evidence for another Joern language. + +## Taint-modeling matrix + +`run-joern-modeling --language ` runs that language's twenty-four +assertions of the +[benchmark-controlled taint-modeling matrix](../../docs/modeling-matrix.md), +writing `reports/joern--modeling.json` with retained evidence under +`reports/raw/joern--modeling/`. Java is wave M1's first language; see +[the Java modeling report](../../docs/java-modeling.md). + +This is the one place where the "no custom semantics" statement above does not +apply, and it is scoped so that it still applies everywhere else. The kernels +supply no semantics and no engine configuration, and `queries/kernel.sc` is +untouched by this population. The modeling matrix supplies both, through two +files that are hash-bound together into the modeling report and into nothing +else: + +| File | Carries | +| --- | --- | +| `queries/modeling.sc` | the roles whose native Joern surface is a query root — `source`, `sink`, and `entry-point` | +| `semantics/model-.semantics` | the roles whose surface is a `FlowSemantic` — `propagator`, `sanitizer`, `summary`, `store-write`, `store-read` | + +The script loads the semantics file with `FullNameSemanticsParser` and installs +it as the engine's whole `Semantics` via `FullNameSemantics.fromList`. No +default catalog is layered underneath, so an entity with no entry is one the +benchmark did not declare — which is exactly what the undeclared siblings of +this matrix's negatives need. + +Index convention in the semantics files: 0 is the receiver, 1..n the declared +parameters counted from one, and -1 the return value. The +[model declaration language](../../docs/modeling-matrix.md#the-model-declaration-language) +counts parameters from **0**, so its `in: 0` is index 1 here. A method named with +no mapping at all is `NilSemantics` — taint that arrives does not leave — which +is both the `sanitizer` role and the explicit no-flow declaration the `summary` +role's negatives need. + +**The semantics files carry no comments.** The pinned 4.0.610 +`FullNameSemanticsParser` returns an empty declaration list for a file whose +first line is a `//` comment; that was verified against the pinned distribution +rather than assumed, so the files are declarations only and their commentary +lives in the language's modeling document. + +The modeling normalization is not the kernel's. A kernel run that bound zero +source or zero sink nodes is `inconclusive`, because on a kernel an unobserved +endpoint means the run never saw the assertion. On the modeling tier an +unobserved endpoint is frequently the measurement itself — a declared-source +negative's sibling is undeclared *on purpose* — so zero bound nodes is a correct +and informative answer there, retained in the diagnostics rather than converted +into incomplete evidence. A run that produced no CPG at all is still +`runner-error`. + +Invocation, one non-interactive process per case, in a per-case scratch root: + +```bash +joern --script adapters/joern/queries/modeling.sc \ + --param inputPath= \ + --param language= \ + --param semanticsPath=adapters/joern/semantics/model-.semantics \ + --param outputPath=reports/raw/joern--modeling/.json +``` + +### Observed: Java + +`reports/joern-java-modeling.json`, 4.0.610, 24 results: 12 `reached` and 12 +`not-reached`, **20/24 correct** — ten true positives, ten true negatives, two +false positives, two false negatives, no `inconclusive` and no `runner-error`. +Categories S, Z, and E are 4/4; P and O are 3/4 and B is 2/4. + +The load-bearing counterfactual is a documented probe: removing only the +`Clean.scrub` line from the nine-entry semantics file turns both category-Z +negatives from no flows to one flow each, while template 7's negative — which +depends on the still-declared `Bridge.hold` — is unchanged. + +Three engine facts account for the four misses, and each is published as +observed rather than tuned around: + +- **Positional fidelity is not enforced.** `Opaque.select` is declared index + 2 → return and taint at the undeclared index 1 reaches the sink. A separate + three-way probe separates this from "the model was ignored": replacing the + mapping with `NilSemantics` removes both cells' findings, and removing the + entry entirely lets the engine walk the reflective body instead. The mapping + is applied; its index is not what selects the argument. +- **A `FlowPath` access-path destination does not discriminate.** + `Bridge.deposit` declared `1 -> 2 "payload"` also taints the sibling field + `box.spare`. The preregistration named exactly this cell as unverified. +- **The persistence roundtrip does not close.** Both category-B declarations + load and both negatives are correct, but no flow crosses from `Store.put`'s + value parameter to `Store.get`'s return in either the type-bound or the + instance-bound spelling. + +All three are recorded as *proposed* amendments on the preregistration, not +applied: a partition cell revised from a result is a result being relabelled. +See [the Java modeling report](../../docs/java-modeling.md). diff --git a/adapters/joern/queries/modeling.sc b/adapters/joern/queries/modeling.sc new file mode 100644 index 0000000..bbcde16 --- /dev/null +++ b/adapters/joern/queries/modeling.sc @@ -0,0 +1,154 @@ +// DataFlowBench Joern taint-modeling query. +// +// One script serves every language's modeling matrix, the way `kernel.sc` +// serves every language's propagation kernel. It is a *separate* script on +// purpose: the kernel script supplies no semantics and no engine +// configuration, and docs/modeling-matrix.md requires that to stay true, so +// the modeling declarations land here rather than in the kernel's file. +// +// The declarations this script carries are the ones whose native Joern surface +// is a query root — the `source`, `sink`, and `entry-point` roles. The +// `propagator`, `sanitizer`, and `summary` roles, plus the two persistence +// roles, are carried by the per-language flow-semantics file passed as +// `semanticsPath`; both files are hash-bound into the report. +// +// Identity binding. The model declaration language binds by a type-plus-member +// triple. Every modeling fixture gives each declared member a name that occurs +// once in its own fixture — `fetchRemote` beside `fetchLocal`, `record` beside +// `discard`, `onRequest` beside `onIgnored` — so selecting by member name here +// resolves exactly the declared entity and never its undeclared sibling. The +// flow-semantics file, which has to discriminate between fixtures of different +// languages inside one artifact, binds by full method name instead. +// +// Invocation (see adapters/joern/README.md): +// +// joern --script adapters/joern/queries/modeling.sc \ +// --param inputPath= \ +// --param language= \ +// --param semanticsPath=.semantics> \ +// --param outputPath= + +import io.joern.dataflowengineoss.queryengine.{EngineConfig, EngineContext} +import io.joern.dataflowengineoss.semanticsloader.{FullNameSemantics, FullNameSemanticsParser} +import java.nio.file.{Files, Paths} + +def jsonString(value: String): String = { + val out = new StringBuilder("\"") + value.foreach { + case '"' => out ++= "\\\"" + case '\\' => out ++= "\\\\" + case '\n' => out ++= "\\n" + case '\r' => out ++= "\\r" + case '\t' => out ++= "\\t" + case c if c.isControl => out ++= f"\\u${c.toInt}%04x" + case c => out += c + } + out ++= "\"" + out.toString +} + +def jsonArray(items: Seq[String]): String = items.mkString("[", ",", "]") + +def jsonField(name: String, value: String): String = jsonString(name) + ":" + value + +def jsonObject(fields: Seq[String]): String = fields.mkString("{", ",", "}") + +/** One CPG node rendered as retained location evidence. */ +def nodeJson(node: io.shiftleft.codepropertygraph.generated.nodes.AstNode): String = { + val file = scala.util.Try(node.location.filename).getOrElse("") + val line = node.lineNumber.map(_.toString).getOrElse("null") + val method = scala.util.Try(node.location.methodFullName).getOrElse("") + jsonObject( + Seq( + jsonField("label", jsonString(node.label)), + jsonField("file", jsonString(file)), + jsonField("line", line), + jsonField("method", jsonString(method)), + jsonField("code", jsonString(node.code)) + ) + ) +} + +/** Members the matrix declares as sources, by the doc's own entity names. */ +val declaredSourceCalls = Seq("dfb_source", "fetchRemote") + +/** Members the matrix declares as sinks. */ +val declaredSinkCalls = Seq("dfb_sink", "record") + +/** Members the matrix declares as entry points, with parameter 0 tainted. */ +val declaredEntryPoints = Seq("onRequest", "onDeclared") + +@main def main( + inputPath: String, + language: String, + semanticsPath: String, + outputPath: String +): Unit = { + val header = Seq( + jsonField("adapter", jsonString("joern")), + jsonField("evidence_kind", jsonString("joern-reachable-by-flows")), + jsonField("input_path", jsonString(inputPath)), + jsonField("frontend_language", jsonString(language)), + jsonField("semantics_path", jsonString(semanticsPath)), + jsonField("source_function", jsonString(declaredSourceCalls.mkString("|"))), + jsonField("sink_function", jsonString(declaredSinkCalls.mkString("|"))) + ) + + val document = + try { + importCode(inputPath = inputPath, projectName = "dataflowbench", language = language) + + // The benchmark-supplied propagator, sanitizer, summary, and persistence + // declarations, loaded into the engine as flow semantics. Nothing else + // is configured: no default catalog is added on top, so an entity with + // no entry here is one the benchmark did not declare. + val declared = new FullNameSemanticsParser().parseFile(semanticsPath) + implicit val context: EngineContext = + EngineContext(FullNameSemantics.fromList(declared), EngineConfig()) + + val sourceCalls = cpg.call.nameExact(declaredSourceCalls: _*).l + val entryParameters = + cpg.method.nameExact(declaredEntryPoints: _*).parameter.index(1).l + val sourceNodes = sourceCalls ++ entryParameters + // The positional arguments of a declared sink call. `argumentIndex > 0` + // drops the implicit receiver the JavaScript and Python frontends attach + // as argument 0; it is not part of any declared sink's bound position. + val sinkNodes = + cpg.call.nameExact(declaredSinkCalls: _*).argument.filter(_.argumentIndex > 0).l + val flows = sinkNodes.reachableByFlows(sourceNodes).l + val flowJson = flows.map { path => + jsonObject(Seq(jsonField("elements", jsonArray(path.elements.map(nodeJson))))) + } + jsonObject( + header ++ Seq( + jsonField("state", jsonString("analyzed")), + jsonField("method_count", cpg.method.size.toString), + jsonField("declared_semantics_count", declared.size.toString), + jsonField("source_node_count", sourceNodes.size.toString), + jsonField("sink_node_count", sinkNodes.size.toString), + jsonField("source_nodes", jsonArray(sourceNodes.map(nodeJson))), + jsonField("sink_nodes", jsonArray(sinkNodes.map(nodeJson))), + jsonField("flow_count", flows.size.toString), + jsonField("flows", jsonArray(flowJson)) + ) + ) + } catch { + case throwable: Throwable => + // A frontend, semantics-loader, or engine failure is retained as a + // runner error. It is never allowed to look like an empty (negative) + // result set. + jsonObject( + header ++ Seq( + jsonField("state", jsonString("runner-error")), + jsonField("stage", jsonString("joern-modeling-script")), + jsonField( + "diagnostic", + jsonString(s"${throwable.getClass.getName}: ${throwable.getMessage}") + ) + ) + ) + } + + Files.write(Paths.get(outputPath), (document + "\n").getBytes("UTF-8")) + println(s"dataflowbench-joern-modeling wrote $outputPath") +} diff --git a/adapters/joern/semantics/model-java.semantics b/adapters/joern/semantics/model-java.semantics new file mode 100644 index 0000000..99bcc1c --- /dev/null +++ b/adapters/joern/semantics/model-java.semantics @@ -0,0 +1,9 @@ +"dataflowbench.taint.Opaque.carry:java.lang.String(java.lang.String)" 1 -> -1 +"dataflowbench.taint.Opaque.block:java.lang.String(java.lang.String)" +"dataflowbench.taint.Opaque.select:java.lang.String(java.lang.String,java.lang.String)" 2 -> -1 +"dataflowbench.taint.Clean.scrub:java.lang.String(java.lang.String)" +"dataflowbench.taint.Bridge.pass:java.lang.String(java.lang.String)" 1 -> -1 +"dataflowbench.taint.Bridge.hold:java.lang.String(java.lang.String)" +"dataflowbench.taint.Bridge.deposit:void(java.lang.String,dataflowbench.taint.Box)" 1 -> 2 "payload" +"dataflowbench.taint.Store.put:void(java.lang.String,java.lang.String)" 2 -> 0 +"dataflowbench.taint.Store.get:java.lang.String(java.lang.String)" 0 -> -1 diff --git a/adapters/semgrep/README.md b/adapters/semgrep/README.md index fdfae95..97d3f68 100644 --- a/adapters/semgrep/README.md +++ b/adapters/semgrep/README.md @@ -557,8 +557,12 @@ claim — it resolves all 14 scored Kotlin cases through the Java arm. - The `benchmark-controlled` profile applies: the rule is given the same source and sink identities the Bifrost, CodeQL, and Joern kernels are given, and nothing from Semgrep's own registry or default models is used. -- Only the CE (OSS) engine's default taint semantics are used. No propagators, - no sanitizers, no taint labels, no `options:` block, and no Pro feature. +- Only the CE (OSS) engine's default taint semantics are used **by the + kernels**. No propagators, no sanitizers, no taint labels, no `options:` + block, and no Pro feature appear in a kernel rule. The taint-modeling matrix + is the one population with sanitizers and an `options:` block, in its own + `model-.yaml`; it is never pooled with a kernel population and is + excluded from the kernel configuration hash. - The source is the source call itself; the sink is the sink call. No receiver or argument-position refinement is applied beyond the call pattern. - One process per case, always cold; no scan observes another case's files. @@ -570,3 +574,79 @@ claim — it resolves all 14 scored Kotlin cases through the Java arm. Semgrep results are not a proxy for any other adapter's population, no Semgrep population is evidence for another Semgrep language, and the scored 14-assertion subset is never comparable to another tool's full 32- or 30-assertion kernel. + +## Taint-modeling matrix + +`run-semgrep-modeling --language ` runs that language's twenty-four +assertions of the +[benchmark-controlled taint-modeling matrix](../../docs/modeling-matrix.md), +writing `reports/semgrep--modeling.json` with retained evidence under +`reports/raw/semgrep--modeling/`. Java is wave M1's first language; +see [the Java modeling report](../../docs/java-modeling.md). + +The preregistered partition awards Semgrep CE **three of six categories** — S +(declared sources and sinks), Z (declared sanitizers), and E (framework entry +points) — and `rules/model-.yaml` declares those three and only those +three. P, O, and B are `unsupported` with the document's rationale retained +verbatim, decided from the template ID before the scan, so twelve of the +twenty-four assertions never reach the binary. Worth restating, because the +expectation from the kernels is the opposite: **CE enters this matrix with a +larger share of it than Bifrost does.** Modeling capability and propagation +capability are not the same axis. + +Two things distinguish a modeling rule from a kernel rule. + +- **No placeholder.** A kernel rule carries `__DFB_SOURCE__` and `__DFB_SINK__` + because the endpoint identifiers vary per fixture. A modeling rule carries the + benchmark's *declarations*, which are the same for the whole population by + construction, so they are written out literally once and the runner names the + committed file directly. There is still no per-case, per-template, or + per-polarity branching. +- **`options: taint_assume_safe_functions: true`,** which is the + [load-bearing-model requirement](../../docs/modeling-matrix.md#the-load-bearing-model-requirement). + Without it the pinned CE engine carries taint from any tainted argument to a + call's result, and every category-Z cell would be decided by that default + rather than by the `Clean.scrub` declaration. The runner refuses a modeling + rule that does not set it. + +That option is load-bearing in both directions, and the second direction costs a +cell: with unmodeled calls assumed safe, CE also stops carrying taint through +the *undeclared* sanitizer-shaped sibling that template 6's positive routes +through. That cell is reported as observed. It is not tuned around — adding a +propagator for the sibling would be tuning toward the expected polarity, and P +is a category this partition does not award CE in the first place. + +**The modeling rules are excluded from the kernel configuration hash.** A +kernel report's `configuration_hash` is a SHA-256 over every committed *kernel* +rule; `semgrep_rule_paths` skips `model-*.yaml`, so a modeling wave landing for +a new language does not move a hash that describes nothing about the kernel the +report is evidence for. Each modeling report's hash is over its own artifact. + +### Observed: Java + +`reports/semgrep-java-modeling.json`, CE 1.174.0 `--oss-only`, 24 results: 5 +`reached`, 7 `not-reached`, 12 `unsupported`. On the twelve scored assertions, +**11/12 correct** — five true positives, six true negatives, no false positive, +one false negative, and no `inconclusive`. + +Categories S and E are 4/4. Category E is the counter-intuitive one and the +preregistration called it in advance: an intraprocedural engine handles an +uncalled handler *well*, because the sink is inside the handler's own body and +the absence of a caller is the normal case rather than a problem. The +declaration binds selectively — the undeclared siblings `onIgnored` and +`onUndeclared` produce nothing. + +Two load-bearing counterfactuals are retained as documented probes: removing the +`Config.fetchRemote(...)` source turns template 1's positive from one finding to +none (template 2 unchanged), and removing the `onRequest` entry-point source +turns template 9's positive from one finding to none (template 10 unchanged). + +The single miss is template 6's positive, and its cause is the load-bearing +option itself. A crossed four-run probe over the two variables shows that with +`taint_assume_safe_functions: true` the `Clean.scrub` declaration is inert — the +option, not the sanitizer, is what decides every category-Z cell — while with it +off the declaration decides both negatives and template 6's positive is reported +correctly. Category Z is nonetheless scored with the option on, because that is +what the preregistration and the runner gate require, and the outcome is +published as observed. The narrow amendment this supports is stated in +[the Java modeling report](../../docs/java-modeling.md), not applied here. diff --git a/adapters/semgrep/rules/model-java.yaml b/adapters/semgrep/rules/model-java.yaml new file mode 100644 index 0000000..1b4a7cb --- /dev/null +++ b/adapters/semgrep/rules/model-java.yaml @@ -0,0 +1,58 @@ +# Benchmark-controlled Semgrep CE taint rule: the DataFlowBench Java +# taint-modeling matrix. +# +# Unlike the kernel rules this file carries no runner-substituted placeholder. +# A modeling assertion is scored on whether the engine activates the +# benchmark's *declarations*, so the declarations are written out literally, +# once, for the whole population — the single per-language artifact +# docs/modeling-matrix.md's equivalence contract requires. +# +# Only the three categories the preregistered partition awards Semgrep CE are +# declared here. Categories P (propagators), O (summaries), and B (persistence) +# are `unsupported` for this adapter by that partition, and the artifact for an +# unsupported category must not declare it — the partition decides those cells +# without the tool, so declaring them anyway would smuggle a scored cell past a +# capability decision made before the run. +# +# `taint_assume_safe_functions: true` is the load-bearing-model requirement. +# Without it the pinned CE engine carries taint from any tainted argument to a +# call's result, and every category-Z cell would be decided by that default +# rather than by the `Clean.scrub` declaration. +rules: + - id: dfb-model-java + languages: [java] + severity: WARNING + message: a benchmark-declared model carried input to the declared sink + mode: taint + options: + taint_assume_safe_functions: true + pattern-sources: + # The benchmark's own canonical source. + - pattern: dfb_source(...) + # Template 1 — role `source`, entity `Config.fetchRemote`, out: return. + # The undeclared sibling `Config.fetchLocal` is deliberately absent. + - pattern: Config.fetchRemote(...) + # Templates 9 and 10 — role `entry-point`, entities `Handler.onRequest` + # and `Handler.onDeclared`, in: 0 tainted on entry. The handler is never + # called from the fixture; the declaration is what makes its parameter a + # root. The undeclared siblings `onIgnored` and `onUndeclared` are + # deliberately absent. + - patterns: + - pattern: | + void onRequest($T $P) { ... } + - focus-metavariable: $P + - patterns: + - pattern: | + void onDeclared($T $P) { ... } + - focus-metavariable: $P + pattern-sinks: + # The benchmark's own canonical sink. + - pattern: dfb_sink(...) + # Template 2 — role `sink`, entity `Audit.record`, in: 0. The undeclared + # sibling `Audit.discard` is deliberately absent. + - pattern: Audit.record(...) + pattern-sanitizers: + # Templates 5 and 6 — role `sanitizer`, entity `Clean.scrub`, in: 0. + # `Clean.sanitize` is a sibling with the same identity body and a name at + # least as sanitizer-shaped, and it is not declared. + - pattern: Clean.scrub(...) diff --git a/cases/taint/java/model-declared-sink-negative/ModelDeclaredSinkNegative.java b/cases/taint/java/model-declared-sink-negative/ModelDeclaredSinkNegative.java new file mode 100644 index 0000000..15ca903 --- /dev/null +++ b/cases/taint/java/model-declared-sink-negative/ModelDeclaredSinkNegative.java @@ -0,0 +1,17 @@ +package dataflowbench.taint; + +final class Audit { + static void record(String value) { } + + static void discard(String value) { } // DFB-SINK: model-declared-sink-sink +} + +final class ModelDeclaredSinkNegative { + static String dfb_source() { // DFB-SOURCE: model-declared-sink-input + return "t"; + } + + static void run() { + Audit.discard(dfb_source()); + } +} diff --git a/cases/taint/java/model-declared-sink-negative/case.json b/cases/taint/java/model-declared-sink-negative/case.json new file mode 100644 index 0000000..6f59ae4 --- /dev/null +++ b/cases/taint/java/model-declared-sink-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-declared-sink-negative", + "template_id": "dfb-template-model-declared-sink", + "polarity": "negative", + "negative_mechanism": "unrelated-value", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "local-flow" + ], + "feature_tags": [ + "modeled-external", + "interprocedural-one-hop" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelDeclaredSinkNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-declared-sink-input", + "file": "ModelDeclaredSinkNegative.java", + "line_hint": 10 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-declared-sink-sink", + "file": "ModelDeclaredSinkNegative.java", + "line_hint": 6 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-declared-sink-input", + "sink": "DFB-SINK: model-declared-sink-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "declared-sink-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-declared-sink-positive/ModelDeclaredSinkPositive.java b/cases/taint/java/model-declared-sink-positive/ModelDeclaredSinkPositive.java new file mode 100644 index 0000000..925a183 --- /dev/null +++ b/cases/taint/java/model-declared-sink-positive/ModelDeclaredSinkPositive.java @@ -0,0 +1,17 @@ +package dataflowbench.taint; + +final class Audit { + static void record(String value) { } // DFB-SINK: model-declared-sink-sink + + static void discard(String value) { } +} + +final class ModelDeclaredSinkPositive { + static String dfb_source() { // DFB-SOURCE: model-declared-sink-input + return "t"; + } + + static void run() { + Audit.record(dfb_source()); + } +} diff --git a/cases/taint/java/model-declared-sink-positive/case.json b/cases/taint/java/model-declared-sink-positive/case.json new file mode 100644 index 0000000..f03d5d7 --- /dev/null +++ b/cases/taint/java/model-declared-sink-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-declared-sink-positive", + "template_id": "dfb-template-model-declared-sink", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "local-flow" + ], + "feature_tags": [ + "modeled-external", + "interprocedural-one-hop" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelDeclaredSinkPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-declared-sink-input", + "file": "ModelDeclaredSinkPositive.java", + "line_hint": 10 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-declared-sink-sink", + "file": "ModelDeclaredSinkPositive.java", + "line_hint": 4 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-declared-sink-input", + "sink": "DFB-SINK: model-declared-sink-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "declared-sink-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-declared-source-negative/ModelDeclaredSourceNegative.java b/cases/taint/java/model-declared-source-negative/ModelDeclaredSourceNegative.java new file mode 100644 index 0000000..6325f84 --- /dev/null +++ b/cases/taint/java/model-declared-source-negative/ModelDeclaredSourceNegative.java @@ -0,0 +1,19 @@ +package dataflowbench.taint; + +final class Config { + static String fetchRemote() { + return "r"; + } + + static String fetchLocal() { // DFB-SOURCE: model-declared-source-input + return "l"; + } +} + +final class ModelDeclaredSourceNegative { + static void dfb_sink(String value) { } // DFB-SINK: model-declared-source-sink + + static void run() { + dfb_sink(Config.fetchLocal()); + } +} diff --git a/cases/taint/java/model-declared-source-negative/case.json b/cases/taint/java/model-declared-source-negative/case.json new file mode 100644 index 0000000..ca734e0 --- /dev/null +++ b/cases/taint/java/model-declared-source-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-declared-source-negative", + "template_id": "dfb-template-model-declared-source", + "polarity": "negative", + "negative_mechanism": "unrelated-value", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "local-flow" + ], + "feature_tags": [ + "modeled-external", + "interprocedural-one-hop" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelDeclaredSourceNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-declared-source-input", + "file": "ModelDeclaredSourceNegative.java", + "line_hint": 8 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-declared-source-sink", + "file": "ModelDeclaredSourceNegative.java", + "line_hint": 14 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-declared-source-input", + "sink": "DFB-SINK: model-declared-source-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "declared-source-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-declared-source-positive/ModelDeclaredSourcePositive.java b/cases/taint/java/model-declared-source-positive/ModelDeclaredSourcePositive.java new file mode 100644 index 0000000..6c6e160 --- /dev/null +++ b/cases/taint/java/model-declared-source-positive/ModelDeclaredSourcePositive.java @@ -0,0 +1,19 @@ +package dataflowbench.taint; + +final class Config { + static String fetchRemote() { // DFB-SOURCE: model-declared-source-input + return "r"; + } + + static String fetchLocal() { + return "l"; + } +} + +final class ModelDeclaredSourcePositive { + static void dfb_sink(String value) { } // DFB-SINK: model-declared-source-sink + + static void run() { + dfb_sink(Config.fetchRemote()); + } +} diff --git a/cases/taint/java/model-declared-source-positive/case.json b/cases/taint/java/model-declared-source-positive/case.json new file mode 100644 index 0000000..671e4c6 --- /dev/null +++ b/cases/taint/java/model-declared-source-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-declared-source-positive", + "template_id": "dfb-template-model-declared-source", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "local-flow" + ], + "feature_tags": [ + "modeled-external", + "interprocedural-one-hop" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelDeclaredSourcePositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-declared-source-input", + "file": "ModelDeclaredSourcePositive.java", + "line_hint": 4 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-declared-source-sink", + "file": "ModelDeclaredSourcePositive.java", + "line_hint": 14 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-declared-source-input", + "sink": "DFB-SINK: model-declared-source-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "declared-source-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-entrypoint-parameter-negative/Handler.java b/cases/taint/java/model-entrypoint-parameter-negative/Handler.java new file mode 100644 index 0000000..a3a3537 --- /dev/null +++ b/cases/taint/java/model-entrypoint-parameter-negative/Handler.java @@ -0,0 +1,13 @@ +package dataflowbench.taint; + +final class Handler { + static void dfb_sink(String value) { } // DFB-SINK: model-entrypoint-parameter-sink + + void onRequest(String input) { + dfb_sink(input); + } + + void onIgnored(String input) { // DFB-SOURCE: model-entrypoint-parameter-input + dfb_sink(input); + } +} diff --git a/cases/taint/java/model-entrypoint-parameter-negative/case.json b/cases/taint/java/model-entrypoint-parameter-negative/case.json new file mode 100644 index 0000000..6fce1f7 --- /dev/null +++ b/cases/taint/java/model-entrypoint-parameter-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-entrypoint-parameter-negative", + "template_id": "dfb-template-model-entrypoint-parameter", + "polarity": "negative", + "negative_mechanism": "call-context-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "Handler.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-entrypoint-parameter-input", + "file": "Handler.java", + "line_hint": 10 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-entrypoint-parameter-sink", + "file": "Handler.java", + "line_hint": 4 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-entrypoint-parameter-input", + "sink": "DFB-SINK: model-entrypoint-parameter-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "entry-point-root-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-entrypoint-parameter-positive/Handler.java b/cases/taint/java/model-entrypoint-parameter-positive/Handler.java new file mode 100644 index 0000000..c4e8af8 --- /dev/null +++ b/cases/taint/java/model-entrypoint-parameter-positive/Handler.java @@ -0,0 +1,13 @@ +package dataflowbench.taint; + +final class Handler { + static void dfb_sink(String value) { } // DFB-SINK: model-entrypoint-parameter-sink + + void onRequest(String input) { // DFB-SOURCE: model-entrypoint-parameter-input + dfb_sink(input); + } + + void onIgnored(String input) { + dfb_sink(input); + } +} diff --git a/cases/taint/java/model-entrypoint-parameter-positive/case.json b/cases/taint/java/model-entrypoint-parameter-positive/case.json new file mode 100644 index 0000000..e0072cf --- /dev/null +++ b/cases/taint/java/model-entrypoint-parameter-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-entrypoint-parameter-positive", + "template_id": "dfb-template-model-entrypoint-parameter", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "Handler.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-entrypoint-parameter-input", + "file": "Handler.java", + "line_hint": 6 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-entrypoint-parameter-sink", + "file": "Handler.java", + "line_hint": 4 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-entrypoint-parameter-input", + "sink": "DFB-SINK: model-entrypoint-parameter-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "entry-point-root-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-entrypoint-selectivity-negative/Handler.java b/cases/taint/java/model-entrypoint-selectivity-negative/Handler.java new file mode 100644 index 0000000..d9c5f9b --- /dev/null +++ b/cases/taint/java/model-entrypoint-selectivity-negative/Handler.java @@ -0,0 +1,13 @@ +package dataflowbench.taint; + +final class Handler { + static void dfb_sink(String value) { } // DFB-SINK: model-entrypoint-selectivity-sink + + void onDeclared(String input) { + dfb_sink(input); + } + + void onUndeclared(String input) { // DFB-SOURCE: model-entrypoint-selectivity-input + dfb_sink(input); + } +} diff --git a/cases/taint/java/model-entrypoint-selectivity-negative/case.json b/cases/taint/java/model-entrypoint-selectivity-negative/case.json new file mode 100644 index 0000000..e1b78f8 --- /dev/null +++ b/cases/taint/java/model-entrypoint-selectivity-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-entrypoint-selectivity-negative", + "template_id": "dfb-template-model-entrypoint-selectivity", + "polarity": "negative", + "negative_mechanism": "call-context-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "Handler.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-entrypoint-selectivity-input", + "file": "Handler.java", + "line_hint": 10 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-entrypoint-selectivity-sink", + "file": "Handler.java", + "line_hint": 4 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-entrypoint-selectivity-input", + "sink": "DFB-SINK: model-entrypoint-selectivity-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "entry-point-identity-binding" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-entrypoint-selectivity-positive/Handler.java b/cases/taint/java/model-entrypoint-selectivity-positive/Handler.java new file mode 100644 index 0000000..d16ea9f --- /dev/null +++ b/cases/taint/java/model-entrypoint-selectivity-positive/Handler.java @@ -0,0 +1,13 @@ +package dataflowbench.taint; + +final class Handler { + static void dfb_sink(String value) { } // DFB-SINK: model-entrypoint-selectivity-sink + + void onDeclared(String input) { // DFB-SOURCE: model-entrypoint-selectivity-input + dfb_sink(input); + } + + void onUndeclared(String input) { + dfb_sink(input); + } +} diff --git a/cases/taint/java/model-entrypoint-selectivity-positive/case.json b/cases/taint/java/model-entrypoint-selectivity-positive/case.json new file mode 100644 index 0000000..017bd8d --- /dev/null +++ b/cases/taint/java/model-entrypoint-selectivity-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-entrypoint-selectivity-positive", + "template_id": "dfb-template-model-entrypoint-selectivity", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "Handler.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-entrypoint-selectivity-input", + "file": "Handler.java", + "line_hint": 6 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-entrypoint-selectivity-sink", + "file": "Handler.java", + "line_hint": 4 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-entrypoint-selectivity-input", + "sink": "DFB-SINK: model-entrypoint-selectivity-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "entry-point-identity-binding" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-opaque-propagator-negative/ModelOpaquePropagatorNegative.java b/cases/taint/java/model-opaque-propagator-negative/ModelOpaquePropagatorNegative.java new file mode 100644 index 0000000..d3e374f --- /dev/null +++ b/cases/taint/java/model-opaque-propagator-negative/ModelOpaquePropagatorNegative.java @@ -0,0 +1,39 @@ +package dataflowbench.taint; + +final class Opaque { + public static String identity(String value) { + return value; + } + + static String carry(String value) { + String target = "identity"; + try { + return (String) Opaque.class.getMethod(target, String.class) + .invoke(null, value); + } catch (ReflectiveOperationException error) { + return ""; + } + } + + static String block(String value) { + String target = "identity"; + try { + return (String) Opaque.class.getMethod(target, String.class) + .invoke(null, value); + } catch (ReflectiveOperationException error) { + return ""; + } + } +} + +final class ModelOpaquePropagatorNegative { + static String dfb_source() { // DFB-SOURCE: model-opaque-propagator-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-opaque-propagator-sink + + static void run() { + dfb_sink(Opaque.block(dfb_source())); + } +} diff --git a/cases/taint/java/model-opaque-propagator-negative/case.json b/cases/taint/java/model-opaque-propagator-negative/case.json new file mode 100644 index 0000000..5f96628 --- /dev/null +++ b/cases/taint/java/model-opaque-propagator-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-opaque-propagator-negative", + "template_id": "dfb-template-model-opaque-propagator", + "polarity": "negative", + "negative_mechanism": "call-context-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelOpaquePropagatorNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-opaque-propagator-input", + "file": "ModelOpaquePropagatorNegative.java", + "line_hint": 30 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-opaque-propagator-sink", + "file": "ModelOpaquePropagatorNegative.java", + "line_hint": 34 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-opaque-propagator-input", + "sink": "DFB-SINK: model-opaque-propagator-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "opaque-propagator-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-opaque-propagator-positive/ModelOpaquePropagatorPositive.java b/cases/taint/java/model-opaque-propagator-positive/ModelOpaquePropagatorPositive.java new file mode 100644 index 0000000..8691407 --- /dev/null +++ b/cases/taint/java/model-opaque-propagator-positive/ModelOpaquePropagatorPositive.java @@ -0,0 +1,39 @@ +package dataflowbench.taint; + +final class Opaque { + public static String identity(String value) { + return value; + } + + static String carry(String value) { + String target = "identity"; + try { + return (String) Opaque.class.getMethod(target, String.class) + .invoke(null, value); + } catch (ReflectiveOperationException error) { + return ""; + } + } + + static String block(String value) { + String target = "identity"; + try { + return (String) Opaque.class.getMethod(target, String.class) + .invoke(null, value); + } catch (ReflectiveOperationException error) { + return ""; + } + } +} + +final class ModelOpaquePropagatorPositive { + static String dfb_source() { // DFB-SOURCE: model-opaque-propagator-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-opaque-propagator-sink + + static void run() { + dfb_sink(Opaque.carry(dfb_source())); + } +} diff --git a/cases/taint/java/model-opaque-propagator-positive/case.json b/cases/taint/java/model-opaque-propagator-positive/case.json new file mode 100644 index 0000000..b667524 --- /dev/null +++ b/cases/taint/java/model-opaque-propagator-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-opaque-propagator-positive", + "template_id": "dfb-template-model-opaque-propagator", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelOpaquePropagatorPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-opaque-propagator-input", + "file": "ModelOpaquePropagatorPositive.java", + "line_hint": 30 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-opaque-propagator-sink", + "file": "ModelOpaquePropagatorPositive.java", + "line_hint": 34 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-opaque-propagator-input", + "sink": "DFB-SINK: model-opaque-propagator-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "opaque-propagator-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-propagator-position-negative/ModelPropagatorPositionNegative.java b/cases/taint/java/model-propagator-position-negative/ModelPropagatorPositionNegative.java new file mode 100644 index 0000000..26764c5 --- /dev/null +++ b/cases/taint/java/model-propagator-position-negative/ModelPropagatorPositionNegative.java @@ -0,0 +1,29 @@ +package dataflowbench.taint; + +final class Opaque { + public static String identity(String value) { + return value; + } + + static String select(String first, String second) { + String target = "identity"; + try { + return (String) Opaque.class.getMethod(target, String.class) + .invoke(null, second); + } catch (ReflectiveOperationException error) { + return ""; + } + } +} + +final class ModelPropagatorPositionNegative { + static String dfb_source() { // DFB-SOURCE: model-propagator-position-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-propagator-position-sink + + static void run() { + dfb_sink(Opaque.select(dfb_source(), "clean")); + } +} diff --git a/cases/taint/java/model-propagator-position-negative/case.json b/cases/taint/java/model-propagator-position-negative/case.json new file mode 100644 index 0000000..1026b10 --- /dev/null +++ b/cases/taint/java/model-propagator-position-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-propagator-position-negative", + "template_id": "dfb-template-model-propagator-position", + "polarity": "negative", + "negative_mechanism": "call-context-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelPropagatorPositionNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-propagator-position-input", + "file": "ModelPropagatorPositionNegative.java", + "line_hint": 20 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-propagator-position-sink", + "file": "ModelPropagatorPositionNegative.java", + "line_hint": 24 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-propagator-position-input", + "sink": "DFB-SINK: model-propagator-position-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "positional-propagator-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-propagator-position-positive/ModelPropagatorPositionPositive.java b/cases/taint/java/model-propagator-position-positive/ModelPropagatorPositionPositive.java new file mode 100644 index 0000000..fbfe2dc --- /dev/null +++ b/cases/taint/java/model-propagator-position-positive/ModelPropagatorPositionPositive.java @@ -0,0 +1,29 @@ +package dataflowbench.taint; + +final class Opaque { + public static String identity(String value) { + return value; + } + + static String select(String first, String second) { + String target = "identity"; + try { + return (String) Opaque.class.getMethod(target, String.class) + .invoke(null, second); + } catch (ReflectiveOperationException error) { + return ""; + } + } +} + +final class ModelPropagatorPositionPositive { + static String dfb_source() { // DFB-SOURCE: model-propagator-position-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-propagator-position-sink + + static void run() { + dfb_sink(Opaque.select("clean", dfb_source())); + } +} diff --git a/cases/taint/java/model-propagator-position-positive/case.json b/cases/taint/java/model-propagator-position-positive/case.json new file mode 100644 index 0000000..48a4215 --- /dev/null +++ b/cases/taint/java/model-propagator-position-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-propagator-position-positive", + "template_id": "dfb-template-model-propagator-position", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelPropagatorPositionPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-propagator-position-input", + "file": "ModelPropagatorPositionPositive.java", + "line_hint": 20 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-propagator-position-sink", + "file": "ModelPropagatorPositionPositive.java", + "line_hint": 24 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-propagator-position-input", + "sink": "DFB-SINK: model-propagator-position-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "positional-propagator-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-sanitizer-kill-negative/ModelSanitizerKillNegative.java b/cases/taint/java/model-sanitizer-kill-negative/ModelSanitizerKillNegative.java new file mode 100644 index 0000000..5ed6793 --- /dev/null +++ b/cases/taint/java/model-sanitizer-kill-negative/ModelSanitizerKillNegative.java @@ -0,0 +1,19 @@ +package dataflowbench.taint; + +final class Clean { + static String scrub(String value) { + return value; + } +} + +final class ModelSanitizerKillNegative { + static String dfb_source() { // DFB-SOURCE: model-sanitizer-kill-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-sanitizer-kill-sink + + static void run() { + dfb_sink(Clean.scrub(dfb_source())); + } +} diff --git a/cases/taint/java/model-sanitizer-kill-negative/case.json b/cases/taint/java/model-sanitizer-kill-negative/case.json new file mode 100644 index 0000000..2154404 --- /dev/null +++ b/cases/taint/java/model-sanitizer-kill-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-sanitizer-kill-negative", + "template_id": "dfb-template-model-sanitizer-kill", + "polarity": "negative", + "negative_mechanism": "sanitizer", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "sanitizer" + ], + "feature_tags": [ + "modeled-external", + "sanitized" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelSanitizerKillNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-sanitizer-kill-input", + "file": "ModelSanitizerKillNegative.java", + "line_hint": 10 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-sanitizer-kill-sink", + "file": "ModelSanitizerKillNegative.java", + "line_hint": 14 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-sanitizer-kill-input", + "sink": "DFB-SINK: model-sanitizer-kill-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "declared-sanitizer-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-sanitizer-kill-positive/ModelSanitizerKillPositive.java b/cases/taint/java/model-sanitizer-kill-positive/ModelSanitizerKillPositive.java new file mode 100644 index 0000000..f677538 --- /dev/null +++ b/cases/taint/java/model-sanitizer-kill-positive/ModelSanitizerKillPositive.java @@ -0,0 +1,19 @@ +package dataflowbench.taint; + +final class Clean { + static String scrub(String value) { + return value; + } +} + +final class ModelSanitizerKillPositive { + static String dfb_source() { // DFB-SOURCE: model-sanitizer-kill-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-sanitizer-kill-sink + + static void run() { + dfb_sink(dfb_source()); + } +} diff --git a/cases/taint/java/model-sanitizer-kill-positive/case.json b/cases/taint/java/model-sanitizer-kill-positive/case.json new file mode 100644 index 0000000..9484452 --- /dev/null +++ b/cases/taint/java/model-sanitizer-kill-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-sanitizer-kill-positive", + "template_id": "dfb-template-model-sanitizer-kill", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "sanitizer" + ], + "feature_tags": [ + "modeled-external", + "sanitized" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelSanitizerKillPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-sanitizer-kill-input", + "file": "ModelSanitizerKillPositive.java", + "line_hint": 10 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-sanitizer-kill-sink", + "file": "ModelSanitizerKillPositive.java", + "line_hint": 14 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-sanitizer-kill-input", + "sink": "DFB-SINK: model-sanitizer-kill-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "declared-sanitizer-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-sanitizer-selectivity-negative/ModelSanitizerSelectivityNegative.java b/cases/taint/java/model-sanitizer-selectivity-negative/ModelSanitizerSelectivityNegative.java new file mode 100644 index 0000000..742538e --- /dev/null +++ b/cases/taint/java/model-sanitizer-selectivity-negative/ModelSanitizerSelectivityNegative.java @@ -0,0 +1,23 @@ +package dataflowbench.taint; + +final class Clean { + static String scrub(String value) { + return value; + } + + static String sanitize(String value) { + return value; + } +} + +final class ModelSanitizerSelectivityNegative { + static String dfb_source() { // DFB-SOURCE: model-sanitizer-selectivity-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-sanitizer-selectivity-sink + + static void run() { + dfb_sink(Clean.scrub(dfb_source())); + } +} diff --git a/cases/taint/java/model-sanitizer-selectivity-negative/case.json b/cases/taint/java/model-sanitizer-selectivity-negative/case.json new file mode 100644 index 0000000..726c47b --- /dev/null +++ b/cases/taint/java/model-sanitizer-selectivity-negative/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-sanitizer-selectivity-negative", + "template_id": "dfb-template-model-sanitizer-selectivity", + "polarity": "negative", + "negative_mechanism": "sanitizer", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "sanitizer" + ], + "feature_tags": [ + "modeled-external", + "sanitized" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelSanitizerSelectivityNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-sanitizer-selectivity-input", + "file": "ModelSanitizerSelectivityNegative.java", + "line_hint": 14 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-sanitizer-selectivity-sink", + "file": "ModelSanitizerSelectivityNegative.java", + "line_hint": 18 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-sanitizer-selectivity-input", + "sink": "DFB-SINK: model-sanitizer-selectivity-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "sanitizer-identity-binding" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-sanitizer-selectivity-positive/ModelSanitizerSelectivityPositive.java b/cases/taint/java/model-sanitizer-selectivity-positive/ModelSanitizerSelectivityPositive.java new file mode 100644 index 0000000..a9bf0bb --- /dev/null +++ b/cases/taint/java/model-sanitizer-selectivity-positive/ModelSanitizerSelectivityPositive.java @@ -0,0 +1,23 @@ +package dataflowbench.taint; + +final class Clean { + static String scrub(String value) { + return value; + } + + static String sanitize(String value) { + return value; + } +} + +final class ModelSanitizerSelectivityPositive { + static String dfb_source() { // DFB-SOURCE: model-sanitizer-selectivity-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-sanitizer-selectivity-sink + + static void run() { + dfb_sink(Clean.sanitize(dfb_source())); + } +} diff --git a/cases/taint/java/model-sanitizer-selectivity-positive/case.json b/cases/taint/java/model-sanitizer-selectivity-positive/case.json new file mode 100644 index 0000000..7f71ced --- /dev/null +++ b/cases/taint/java/model-sanitizer-selectivity-positive/case.json @@ -0,0 +1,63 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-sanitizer-selectivity-positive", + "template_id": "dfb-template-model-sanitizer-selectivity", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "sanitizer" + ], + "feature_tags": [ + "modeled-external", + "sanitized" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelSanitizerSelectivityPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-sanitizer-selectivity-input", + "file": "ModelSanitizerSelectivityPositive.java", + "line_hint": 14 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-sanitizer-selectivity-sink", + "file": "ModelSanitizerSelectivityPositive.java", + "line_hint": 18 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-sanitizer-selectivity-input", + "sink": "DFB-SINK: model-sanitizer-selectivity-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "sanitizer-identity-binding" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-store-roundtrip-negative/ModelStoreRoundtripNegative.java b/cases/taint/java/model-store-roundtrip-negative/ModelStoreRoundtripNegative.java new file mode 100644 index 0000000..3bbdd78 --- /dev/null +++ b/cases/taint/java/model-store-roundtrip-negative/ModelStoreRoundtripNegative.java @@ -0,0 +1,25 @@ +package dataflowbench.taint; + +final class Store { + static void put(String key, String value) { } + + static String get(String key) { + return ""; + } +} + +final class ModelStoreRoundtripNegative { + static String dfb_source() { // DFB-SOURCE: model-store-roundtrip-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-store-roundtrip-sink + + static void writeSide() { + Store.put("a", dfb_source()); + } + + static void readSide() { + dfb_sink(Store.get("b")); + } +} diff --git a/cases/taint/java/model-store-roundtrip-negative/case.json b/cases/taint/java/model-store-roundtrip-negative/case.json new file mode 100644 index 0000000..6c797e4 --- /dev/null +++ b/cases/taint/java/model-store-roundtrip-negative/case.json @@ -0,0 +1,65 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-store-roundtrip-negative", + "template_id": "dfb-template-model-store-roundtrip", + "polarity": "negative", + "negative_mechanism": "field-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow", + "heap-field-sensitivity" + ], + "feature_tags": [ + "modeled-external", + "heap-access-path" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelStoreRoundtripNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-store-roundtrip-input", + "file": "ModelStoreRoundtripNegative.java", + "line_hint": 12 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-store-roundtrip-sink", + "file": "ModelStoreRoundtripNegative.java", + "line_hint": 16 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-store-roundtrip-input", + "sink": "DFB-SINK: model-store-roundtrip-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "persistence-boundary-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-store-roundtrip-positive/ModelStoreRoundtripPositive.java b/cases/taint/java/model-store-roundtrip-positive/ModelStoreRoundtripPositive.java new file mode 100644 index 0000000..1954ca9 --- /dev/null +++ b/cases/taint/java/model-store-roundtrip-positive/ModelStoreRoundtripPositive.java @@ -0,0 +1,25 @@ +package dataflowbench.taint; + +final class Store { + static void put(String key, String value) { } + + static String get(String key) { + return ""; + } +} + +final class ModelStoreRoundtripPositive { + static String dfb_source() { // DFB-SOURCE: model-store-roundtrip-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-store-roundtrip-sink + + static void writeSide() { + Store.put("k", dfb_source()); + } + + static void readSide() { + dfb_sink(Store.get("k")); + } +} diff --git a/cases/taint/java/model-store-roundtrip-positive/case.json b/cases/taint/java/model-store-roundtrip-positive/case.json new file mode 100644 index 0000000..1d151e0 --- /dev/null +++ b/cases/taint/java/model-store-roundtrip-positive/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-store-roundtrip-positive", + "template_id": "dfb-template-model-store-roundtrip", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow", + "heap-field-sensitivity" + ], + "feature_tags": [ + "modeled-external", + "heap-access-path" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelStoreRoundtripPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-store-roundtrip-input", + "file": "ModelStoreRoundtripPositive.java", + "line_hint": 12 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-store-roundtrip-sink", + "file": "ModelStoreRoundtripPositive.java", + "line_hint": 16 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-store-roundtrip-input", + "sink": "DFB-SINK: model-store-roundtrip-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "persistence-boundary-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-store-separation-negative/ModelStoreSeparationNegative.java b/cases/taint/java/model-store-separation-negative/ModelStoreSeparationNegative.java new file mode 100644 index 0000000..af05d1b --- /dev/null +++ b/cases/taint/java/model-store-separation-negative/ModelStoreSeparationNegative.java @@ -0,0 +1,29 @@ +package dataflowbench.taint; + +final class Store { + void put(String key, String value) { } + + String get(String key) { + return ""; + } +} + +final class ModelStoreSeparationNegative { + static final Store alpha = new Store(); + + static final Store beta = new Store(); + + static String dfb_source() { // DFB-SOURCE: model-store-separation-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-store-separation-sink + + static void writeSide() { + alpha.put("k", dfb_source()); + } + + static void readSide() { + dfb_sink(beta.get("k")); + } +} diff --git a/cases/taint/java/model-store-separation-negative/case.json b/cases/taint/java/model-store-separation-negative/case.json new file mode 100644 index 0000000..9661891 --- /dev/null +++ b/cases/taint/java/model-store-separation-negative/case.json @@ -0,0 +1,65 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-store-separation-negative", + "template_id": "dfb-template-model-store-separation", + "polarity": "negative", + "negative_mechanism": "object-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow", + "object-sensitivity" + ], + "feature_tags": [ + "modeled-external", + "heap-access-path" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelStoreSeparationNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-store-separation-input", + "file": "ModelStoreSeparationNegative.java", + "line_hint": 16 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-store-separation-sink", + "file": "ModelStoreSeparationNegative.java", + "line_hint": 20 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-store-separation-input", + "sink": "DFB-SINK: model-store-separation-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "persistence-instance-binding" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-store-separation-positive/ModelStoreSeparationPositive.java b/cases/taint/java/model-store-separation-positive/ModelStoreSeparationPositive.java new file mode 100644 index 0000000..73ea7ab --- /dev/null +++ b/cases/taint/java/model-store-separation-positive/ModelStoreSeparationPositive.java @@ -0,0 +1,29 @@ +package dataflowbench.taint; + +final class Store { + void put(String key, String value) { } + + String get(String key) { + return ""; + } +} + +final class ModelStoreSeparationPositive { + static final Store alpha = new Store(); + + static final Store beta = new Store(); + + static String dfb_source() { // DFB-SOURCE: model-store-separation-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-store-separation-sink + + static void writeSide() { + alpha.put("k", dfb_source()); + } + + static void readSide() { + dfb_sink(alpha.get("k")); + } +} diff --git a/cases/taint/java/model-store-separation-positive/case.json b/cases/taint/java/model-store-separation-positive/case.json new file mode 100644 index 0000000..dc1bdf2 --- /dev/null +++ b/cases/taint/java/model-store-separation-positive/case.json @@ -0,0 +1,64 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-store-separation-positive", + "template_id": "dfb-template-model-store-separation", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "interprocedural-flow", + "object-sensitivity" + ], + "feature_tags": [ + "modeled-external", + "heap-access-path" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelStoreSeparationPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-store-separation-input", + "file": "ModelStoreSeparationPositive.java", + "line_hint": 16 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-store-separation-sink", + "file": "ModelStoreSeparationPositive.java", + "line_hint": 20 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-store-separation-input", + "sink": "DFB-SINK: model-store-separation-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "persistence-instance-binding" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-summary-field-negative/ModelSummaryFieldNegative.java b/cases/taint/java/model-summary-field-negative/ModelSummaryFieldNegative.java new file mode 100644 index 0000000..2519d08 --- /dev/null +++ b/cases/taint/java/model-summary-field-negative/ModelSummaryFieldNegative.java @@ -0,0 +1,24 @@ +package dataflowbench.taint; + +final class Box { + String payload = ""; + String spare = ""; +} + +final class Bridge { + static void deposit(String value, Box box) { } +} + +final class ModelSummaryFieldNegative { + static String dfb_source() { // DFB-SOURCE: model-summary-field-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-summary-field-sink + + static void run() { + Box box = new Box(); + Bridge.deposit(dfb_source(), box); + dfb_sink(box.spare); + } +} diff --git a/cases/taint/java/model-summary-field-negative/case.json b/cases/taint/java/model-summary-field-negative/case.json new file mode 100644 index 0000000..02fa5c4 --- /dev/null +++ b/cases/taint/java/model-summary-field-negative/case.json @@ -0,0 +1,67 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-summary-field-negative", + "template_id": "dfb-template-model-summary-field", + "polarity": "negative", + "negative_mechanism": "field-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary", + "interprocedural-flow", + "heap-field-sensitivity" + ], + "feature_tags": [ + "modeled-external", + "summary-required", + "heap-access-path" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelSummaryFieldNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-summary-field-input", + "file": "ModelSummaryFieldNegative.java", + "line_hint": 13 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-summary-field-sink", + "file": "ModelSummaryFieldNegative.java", + "line_hint": 17 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-summary-field-input", + "sink": "DFB-SINK: model-summary-field-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "store-through-summary-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-summary-field-positive/ModelSummaryFieldPositive.java b/cases/taint/java/model-summary-field-positive/ModelSummaryFieldPositive.java new file mode 100644 index 0000000..036edd2 --- /dev/null +++ b/cases/taint/java/model-summary-field-positive/ModelSummaryFieldPositive.java @@ -0,0 +1,24 @@ +package dataflowbench.taint; + +final class Box { + String payload = ""; + String spare = ""; +} + +final class Bridge { + static void deposit(String value, Box box) { } +} + +final class ModelSummaryFieldPositive { + static String dfb_source() { // DFB-SOURCE: model-summary-field-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-summary-field-sink + + static void run() { + Box box = new Box(); + Bridge.deposit(dfb_source(), box); + dfb_sink(box.payload); + } +} diff --git a/cases/taint/java/model-summary-field-positive/case.json b/cases/taint/java/model-summary-field-positive/case.json new file mode 100644 index 0000000..f799919 --- /dev/null +++ b/cases/taint/java/model-summary-field-positive/case.json @@ -0,0 +1,66 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-summary-field-positive", + "template_id": "dfb-template-model-summary-field", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary", + "interprocedural-flow", + "heap-field-sensitivity" + ], + "feature_tags": [ + "modeled-external", + "summary-required", + "heap-access-path" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "ModelSummaryFieldPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-summary-field-input", + "file": "ModelSummaryFieldPositive.java", + "line_hint": 13 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-summary-field-sink", + "file": "ModelSummaryFieldPositive.java", + "line_hint": 17 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-summary-field-input", + "sink": "DFB-SINK: model-summary-field-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "store-through-summary-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-summary-through-negative/Bridge.java b/cases/taint/java/model-summary-through-negative/Bridge.java new file mode 100644 index 0000000..4934c5e --- /dev/null +++ b/cases/taint/java/model-summary-through-negative/Bridge.java @@ -0,0 +1,11 @@ +package dataflowbench.taint; + +final class Bridge { + static String pass(String value) { + return value; + } + + static String hold(String value) { + return value; + } +} diff --git a/cases/taint/java/model-summary-through-negative/ModelSummaryThroughNegative.java b/cases/taint/java/model-summary-through-negative/ModelSummaryThroughNegative.java new file mode 100644 index 0000000..03703dc --- /dev/null +++ b/cases/taint/java/model-summary-through-negative/ModelSummaryThroughNegative.java @@ -0,0 +1,13 @@ +package dataflowbench.taint; + +final class ModelSummaryThroughNegative { + static String dfb_source() { // DFB-SOURCE: model-summary-through-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-summary-through-sink + + static void run() { + dfb_sink(Bridge.hold(dfb_source())); + } +} diff --git a/cases/taint/java/model-summary-through-negative/case.json b/cases/taint/java/model-summary-through-negative/case.json new file mode 100644 index 0000000..79ad82c --- /dev/null +++ b/cases/taint/java/model-summary-through-negative/case.json @@ -0,0 +1,66 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-summary-through-negative", + "template_id": "dfb-template-model-summary-through", + "polarity": "negative", + "negative_mechanism": "call-context-separation", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary", + "interprocedural-flow" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "Bridge.java", + "ModelSummaryThroughNegative.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-summary-through-input", + "file": "ModelSummaryThroughNegative.java", + "line_hint": 4 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-summary-through-sink", + "file": "ModelSummaryThroughNegative.java", + "line_hint": 8 + } + ], + "expected_flows": [], + "expected_nonflows": [ + { + "source": "DFB-SOURCE: model-summary-through-input", + "sink": "DFB-SINK: model-summary-through-sink" + } + ], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "procedure-summary-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/cases/taint/java/model-summary-through-positive/Bridge.java b/cases/taint/java/model-summary-through-positive/Bridge.java new file mode 100644 index 0000000..4934c5e --- /dev/null +++ b/cases/taint/java/model-summary-through-positive/Bridge.java @@ -0,0 +1,11 @@ +package dataflowbench.taint; + +final class Bridge { + static String pass(String value) { + return value; + } + + static String hold(String value) { + return value; + } +} diff --git a/cases/taint/java/model-summary-through-positive/ModelSummaryThroughPositive.java b/cases/taint/java/model-summary-through-positive/ModelSummaryThroughPositive.java new file mode 100644 index 0000000..2a07f49 --- /dev/null +++ b/cases/taint/java/model-summary-through-positive/ModelSummaryThroughPositive.java @@ -0,0 +1,13 @@ +package dataflowbench.taint; + +final class ModelSummaryThroughPositive { + static String dfb_source() { // DFB-SOURCE: model-summary-through-input + return "t"; + } + + static void dfb_sink(String value) { } // DFB-SINK: model-summary-through-sink + + static void run() { + dfb_sink(Bridge.pass(dfb_source())); + } +} diff --git a/cases/taint/java/model-summary-through-positive/case.json b/cases/taint/java/model-summary-through-positive/case.json new file mode 100644 index 0000000..4193ef1 --- /dev/null +++ b/cases/taint/java/model-summary-through-positive/case.json @@ -0,0 +1,65 @@ +{ + "schema_version": 2, + "id": "dfb-taint-java-model-summary-through-positive", + "template_id": "dfb-template-model-summary-through", + "polarity": "positive", + "score_tier": "modeling", + "track": "taint", + "language": "java", + "semantic_dimensions": [ + "external-summary", + "interprocedural-flow" + ], + "feature_tags": [ + "modeled-external", + "summary-required" + ], + "model_profile": "benchmark-controlled", + "fixture_files": [ + "Bridge.java", + "ModelSummaryThroughPositive.java" + ], + "source_anchors": [ + { + "marker": "DFB-SOURCE: model-summary-through-input", + "file": "ModelSummaryThroughPositive.java", + "line_hint": 4 + } + ], + "sink_anchors": [ + { + "marker": "DFB-SINK: model-summary-through-sink", + "file": "ModelSummaryThroughPositive.java", + "line_hint": 8 + } + ], + "expected_flows": [ + { + "source": "DFB-SOURCE: model-summary-through-input", + "sink": "DFB-SINK: model-summary-through-sink" + } + ], + "expected_nonflows": [], + "witness_checkpoints": [], + "expected_analysis_capability": { + "kind": "procedure-summary-activation" + }, + "execution_budget": { + "wall_clock_seconds": 60, + "peak_memory_mb": 512 + }, + "fixture_provenance": { + "kind": "authored", + "origin": "DataFlowBench", + "revision": "m3-modeling-java", + "license": "MIT" + }, + "tool_model_references": { + "bifrost": { + "policy": "adapters/bifrost/policies/model-java.rqlp" + }, + "codeql": { + "query": "adapters/codeql/queries/JavaModeling.ql" + } + } +} diff --git a/docs/adapters.md b/docs/adapters.md index 254930b..5f61e31 100644 --- a/docs/adapters.md +++ b/docs/adapters.md @@ -254,7 +254,7 @@ tool per language, hash-bound into the report's `configuration_hash`: | Adapter | Modeling artifact | | --- | --- | | Bifrost | `adapters/bifrost/policies/model-.rqlp` | -| CodeQL | `adapters/codeql//queries/Modeling.ql` | +| CodeQL | `adapters/codeql//queries/Modeling.ql`, except Java's, which is `adapters/codeql/queries/JavaModeling.ql` | | Joern | `adapters/joern/semantics/model-.semantics`, plus the shared `adapters/joern/queries/modeling.sc` | | Semgrep | `adapters/semgrep/rules/model-.yaml` | @@ -262,8 +262,13 @@ The CodeQL path departs from the preregistration's schematic `adapters/codeql/queries/Modeling.ql` and sits inside that language's existing `qlpack`, because a query outside a pack cannot resolve its `codeql/-all` dependency. That is a location, not a declaration -surface: the document's `ConfigSig` encoding is unchanged. Joern is the one -adapter with two files, and both bind the configuration hash. +surface: the document's `ConfigSig` encoding is unchanged. Java is the one +language for which the schematic path is already correct, because Java's pack +*is* the adapter root — `adapters/codeql/qlpack.yml` declares +`dataflowbench/codeql-java` and `JavaKernel.ql` sits beside it — so there is no +`adapters/codeql/java/` to descend into and a query under one would resolve +nothing. Joern is the one adapter with two files, and both bind the +configuration hash. **Four commands, parameterized by language.** `run-bifrost-modeling`, `run-codeql-modeling`, `run-joern-modeling`, and `run-semgrep-modeling`, each @@ -302,15 +307,31 @@ have no such switch to pin — a `ConfigSig` with no `isAdditionalFlowStep` adds no step and a Joern method with no `FlowMapping` propagates nothing — so neither is gated. -**The execution arm lands with the language.** Today every modeling command -stops at the population gate, because no fixture exists. The arm that invokes -an analyzer over a *scored* cell is written by the pull request that authors -that adapter's declarations for that language; until it is, a scored cell is a -hard error rather than a synthesized outcome, which the adapter contract at the -head of this document forbids. The `unsupported` arm is complete now, so a tool -that declines every category a population carries already produces a whole, +**The execution arm lands with the language.** The arm that invokes an analyzer +over a *scored* cell is written by the pull request that authors that adapter's +declarations for that language; until it is, a scored cell is a hard error +rather than a synthesized outcome, which the adapter contract at the head of +this document forbids. The `unsupported` arm was complete from the start, so a +tool that declines every category a population carries produces a whole, validated report of retained capability decisions without the analyzer being -invoked at all. +invoked at all. **Java's arm is live for all four adapters** — see [the Java +modeling report](java-modeling.md). JavaScript and Python still stop at the +population gate, and CodeQL's ECMAScript arm additionally has to be wired +through that adapter's own per-kernel extraction path rather than through the +shared `CodeqlLanguage`, because that is where the JavaScript populations are +extracted. + +**Reconciliation on this tier is source-anchored as well as sink-anchored,** and +that is a property of the fixtures rather than of any adapter. A modeling fixture +carries both halves of its pair in one type — the declared entity and its +undeclared sibling — because that is what the templates say makes the negative a +negative, and category E's handlers need no caller, so the declared handler's +flow is present in the negative's fixture too. A finding therefore counts only +when it lies in the region its case's own source anchor governs *and* on a +callsite of its anchored sink function. An unmatched finding on this tier is the +pair's other entity, fully attributable, so it normalizes to `not-reached` with +the count retained — not to the kernels' `inconclusive`, which is reserved here +for evidence with no usable location at all. **Reporting stays separate.** Modeling reports are their own population per language and per adapter, bound into a freeze manifest like every other report, diff --git a/docs/java-kernel.md b/docs/java-kernel.md index fa6be02..d0f359c 100644 --- a/docs/java-kernel.md +++ b/docs/java-kernel.md @@ -10,6 +10,11 @@ was therefore recorded across [the adapter contract](adapters.md) and the per-adapter READMEs rather than in a file of its own. This document is that file, and its subject is the expansion. +Java also carries the first population of the +[benchmark-controlled taint-modeling matrix](java-modeling.md). That is a +separate tier with a separate denominator and it is never pooled with anything +below: no number in this document is ever added to a number in that one. + ## Classic core: 16 templates, 32 assertions Unchanged and frozen in v0.3.0. The sixteen `dfb-template-*` identities in diff --git a/docs/java-modeling.md b/docs/java-modeling.md new file mode 100644 index 0000000..8b7b7aa --- /dev/null +++ b/docs/java-modeling.md @@ -0,0 +1,383 @@ +# Java taint-modeling matrix + +Java is wave M1's first language for the +[benchmark-controlled taint-modeling matrix](modeling-matrix.md). This document +is the Java realization of that preregistration: how each of the twelve +templates is spelled in Java, how each of the four adapters encodes the same +analyzer-neutral declarations natively, and what the four runs produced. + +It is a *report*, not a contract. Every definition it cites — the templates, the +negative mechanisms, the capability kinds, the per-tool partition — is fixed by +[the preregistration](modeling-matrix.md), which merged before any of this was +authored and which this document does not amend. Where a run disagreed with what +the preregistration expected, the disagreement is published as observed and +flagged as a *proposed* amendment for a separate, dated change. + +Modeling assertions are `score_tier: "modeling"`. They are never in Java's core +denominator, never pooled with [the propagation kernel](java-kernel.md), and no +number here is ever added to a number there. The two scorecards answer different +questions: the kernel asks whether an engine can follow flow it can see, and this +matrix asks whether it can be told things. + +## The population + +Twenty-four assertions — the twelve templates × positive/negative — under +`cases/taint/java/model--{positive,negative}/`, with case IDs +`dfb-taint-java-model--`. All are `track: taint`, +`score_tier: modeling`, `model_profile: benchmark-controlled`, provenance +`authored`/`DataFlowBench`, revision `m3-modeling-java`, license MIT. + +Every fixture is stdlib-only Java in package `dataflowbench.taint` and compiles +warning-free under `javac 21.0.8 --release 21 -Xlint:all -Werror` — the same +host toolchain the CodeQL Java adapter traces with `javac -d classes`. Eleven +templates are a single `.java` file; template 7 is two, because its summarized +procedure has to be external-shaped. + +`validate_modeling_cases` in `src/main.rs` enforces the balance and the required +set: exactly one positive and one minimally different negative for each of the +preregistered twelve, one model profile across all twenty-four, and the +structural implication that a `dfb-template-model-` template and the `modeling` +tier imply each other. + +### Template realizations + +The declared entities are the preregistration's own: `Config.fetchRemote`, +`Audit.record`, `Opaque.carry` / `Opaque.select`, `Clean.scrub`, `Bridge.pass` / +`Bridge.deposit`, `Handler.onRequest` / `Handler.onDeclared`, and `Store`. Each +lives as a package-private top-level class in its fixture's file, so its +fully-qualified name is stable across fixtures — which is what lets the Joern +flow-semantics artifact bind one entry per entity rather than one per case. + +| # | Template | Java realization | +| --- | --- | --- | +| 1 | `declared-source` | `final class Config` with two constant-returning statics, `fetchRemote` and `fetchLocal`. The positive sinks `Config.fetchRemote()`, the negative `Config.fetchLocal()`. Both bodies return a string literal, so an engine that reads them learns nothing that distinguishes the two. | +| 2 | `declared-sink` | `final class Audit` with two one-parameter statics that both drop their argument, `record` and `discard`. The positive calls `Audit.record(dfb_source())`, the negative `Audit.discard(dfb_source())`. | +| 3 | `opaque-propagator` | `final class Opaque` with `carry` and `block`, whose bodies are byte-identical reflective self-dispatch: `Opaque.class.getMethod(target, String.class).invoke(null, value)` with `target` a local `String` constant naming a public `identity` method. The positive sinks `Opaque.carry(dfb_source())`, the negative `Opaque.block(dfb_source())`. | +| 4 | `propagator-position` | `Opaque.select(String first, String second)` with the same reflective body, forwarding `second`. The positive is `Opaque.select("clean", dfb_source())` — taint at declared position 1 — and the negative `Opaque.select(dfb_source(), "clean")`, the identical call with taint at the undeclared position 0. | +| 5 | `sanitizer-kill` | `final class Clean` with the identity method `scrub`. The positive is the bare flow `dfb_sink(dfb_source())`; the negative routes the same flow through `Clean.scrub`. `Clean` is present in both fixtures, so the pair differs only in the routing. | +| 6 | `sanitizer-selectivity` | `Clean` with two identity methods, `scrub` and `sanitize`. The positive flows through the *undeclared* `sanitize` and must still be reported; the negative flows through the declared `scrub`. | +| 7 | `summary-through` | `Bridge.java`, a second fixture file, holding `Bridge` with two identity methods `pass` and `hold`. Both bodies say flow; the summaries disagree, which is what makes reading-the-body and activating-the-summary distinguishable. | +| 8 | `summary-field` | `final class Box { String payload; String spare; }` and `static void deposit(String value, Box box) { }` with an empty body. Both cells call `Bridge.deposit(dfb_source(), box)`; the positive sinks `box.payload`, the negative the sibling `box.spare`. | +| 9 | `entrypoint-parameter` | `final class Handler` with two uncalled one-parameter methods `onRequest` and `onIgnored` with byte-identical bodies (`dfb_sink(input);`) and no top-level code invoking either. The positive anchors on `onRequest`, the negative on `onIgnored`. | +| 10 | `entrypoint-selectivity` | The same shape with `onDeclared` and `onUndeclared`, both plausible roots in one class. | +| 11 | `store-roundtrip` | `final class Store` with two static no-op methods `put(key, value)` and `get(key)`. `writeSide()` calls `Store.put("k", dfb_source())` and a separate `readSide()` calls `dfb_sink(Store.get("k"))`; the negative uses the distinct constant keys `"a"` and `"b"`. No standard-library map is used, so no shipped `HashMap` model can pass the cell without reading the declaration. | +| 12 | `store-separation` | The same shape with *instance* methods and two `static final Store` fields, `alpha` and `beta`, constructed once and never reassigned. The positive writes and reads `alpha`; the negative writes `alpha` and reads `beta` under the same key. | + +No template proved unimplementable as preregistered, and no template's semantics +were altered. + +### One authoring decision worth recording + +Template 8's `Box` and `Bridge` are auxiliary classes in the fixture's own file +rather than in a second one. `javac -Xlint:all` emits `auxiliaryclass` when a +class hidden in one source file is used from another, so the two-file spelling +would not have compiled warning-free. The preregistration requires a second file +only for template 7 — where external *shape* is part of the semantic intent — so +template 8 is single-file. Nothing about the declaration changes: the entity is +still `Bridge.deposit`, bound by type and member. + +## The four model artifacts + +The same three-part declaration — entity identity, role, binding semantics — in +four native surfaces. Each is hash-bound into its report's +`configuration_hash`. + +| Adapter | Artifact | Categories it declares | +| --- | --- | --- | +| Bifrost v0.10.6 | `adapters/bifrost/policies/model-java.rqlp` | S | +| CodeQL 2.26.3 | `adapters/codeql/queries/JavaModeling.ql` | S, P, Z, O, E, B | +| Joern 4.0.610 | `adapters/joern/semantics/model-java.semantics` + `adapters/joern/queries/modeling.sc` | S, P, Z, O, E, B | +| Semgrep CE 1.174.0 | `adapters/semgrep/rules/model-java.yaml` | S, Z, E | + +**An artifact never declares a category its tool's partition marks +unsupported.** The partition decides those cells before the tool is invoked, so +a declaration for one would smuggle a scored cell past a capability decision +already made. That is why the Bifrost policy carries sources and sinks only and +the Semgrep rule carries no propagator and no summary. + +The CodeQL query sits at `adapters/codeql/queries/JavaModeling.ql` rather than +under a `java/` subdirectory. Java's CodeQL pack *is* the adapter root — +`adapters/codeql/qlpack.yml` declares `dataflowbench/codeql-java`, and +`JavaKernel.ql` already lives beside it — and a query outside a pack resolves no +`codeql/java-all` dependency. That is a location, not a declaration surface. + +The Joern flow-semantics file carries no comments. The pinned distribution's +`FullNameSemanticsParser` returns an empty list for a file whose first line is a +`//` comment, verified against 4.0.610, so the file is declarations only and its +commentary lives here and in the adapter README. + +## Anchor reconciliation on this tier + +A modeling fixture carries **both** halves of its pair by construction: the +declared entity and its undeclared sibling live in one type, because that is +what the templates say makes the negative a negative. Category E makes the +consequence unavoidable — a handler needs no caller, so the *declared* handler's +flow is present in the negative fixture too, on a callsite of the same sink +function. Reconciling a finding against the sink anchor alone would read that +sibling's flow as this case's finding. + +So every modeling adapter reconciles the **source side as well**: a finding +counts only when it lies in the region the case's own source anchor governs — +the anchored declaration, its body, and the callsites of the anchored source +function — *and* on a callsite of the anchored sink function. The region is +computed by indentation rather than by block punctuation, so one rule serves a +braced body and an indented one. + +One modeling-specific reading follows from that. On a kernel, a finding that +reconciles to nothing is unusable evidence and stays `inconclusive`. Here it is +*expected* and fully attributable — it is the pair's other entity — so it is +`not-reached` with the count retained in the result's diagnostics. Evidence with +no usable location at all is still unreadable and still `inconclusive`. + +The Joern normalization additionally departs from the kernel's on one point: the +kernel reports `inconclusive` when a run bound zero source or zero sink nodes, +because on a kernel an unobserved endpoint means the run never saw the +assertion. On this tier an unobserved endpoint is frequently *the measurement* — +`Config.fetchLocal` and `Audit.discard` are undeclared on purpose, so zero bound +nodes is the correct and informative answer, and converting it to `inconclusive` +would hide the one thing category S exists to show. A run that produced no CPG +at all is still `runner-error`. + +## Observed results + +Four runs, sequential, on the pinned distributions. `unsupported` is capability +coverage, `inconclusive` is execution coverage, and neither is ever converted +into a negative. No run produced an `inconclusive` or a `runner-error` result. + +### The three-way split + +| Adapter | Scored | `unsupported` | `inconclusive` | Correct on the scored | Report | +| --- | --- | --- | --- | --- | --- | +| Bifrost v0.10.6 (`18d09c57`) | 4 | 20 | 0 | **4 / 4** | `reports/bifrost-java-modeling.json` | +| CodeQL 2.26.3 | 24 | 0 | 0 | **24 / 24** | `reports/codeql-java-modeling.json` | +| Joern 4.0.610 | 24 | 0 | 0 | **20 / 24** | `reports/joern-java-modeling.json` | +| Semgrep CE 1.174.0 | 12 | 12 | 0 | **11 / 12** | `reports/semgrep-java-modeling.json` | + +The scored column is the preregistered partition, not an outcome: Bifrost +declined five of six categories and Semgrep CE three, both decided from the +template ID before the binary ran. **These four numbers are not comparable to +one another**, because they are over different denominators, and none of them is +comparable to anything on [the Java propagation kernel](java-kernel.md). + +### Per category + +`—` is a category the partition declines for that tool. Each cell is +correct-of-4. + +| Category | Bifrost | CodeQL | Joern | Semgrep CE | +| --- | --- | --- | --- | --- | +| S — declared sources and sinks | 4/4 | 4/4 | 4/4 | 4/4 | +| P — declared propagators | — | 4/4 | 3/4 | — | +| Z — declared sanitizers | — | 4/4 | 4/4 | 3/4 | +| O — opaque summaries | — | 4/4 | 3/4 | — | +| E — framework entry points | — | 4/4 | 4/4 | 4/4 | +| B — persistence boundaries | — | 4/4 | 2/4 | — | + +### Bifrost v0.10.6 — `reports/bifrost-java-modeling.json` + +24 results: 2 `reached`, 2 `not-reached`, 20 `unsupported`. Category S is +**4/4** — 2 true positives, 2 true negatives, no false positive, no false +negative — so both declared-source and declared-sink activation bind by entity +identity, and neither undeclared sibling (`Config.fetchLocal`, `Audit.discard`) +is picked up. + +The twenty declined assertions retain the preregistration's rationale verbatim +in a `retained-capability-decision` document beside the report, keyed by +template identity. Nothing about them is a result about Bifrost's analysis; they +are five categories a standalone policy CLI does not expose today. + +One preregistration cell can now be answered, and it is the one this run existed +to answer first: **v0.10.6 accepts +`:call-modeling (call-modeling :unmodeled require-model)`.** The partition +recorded category P as *to be verified* partly because that was unknown. +Accepting the switch is necessary but not sufficient for promoting P — a +propagator or transform section still has to be shown to lower — so the cell +stays where the preregistration put it, and the observation is recorded here for +whoever writes that amendment. + +### CodeQL 2.26.3 — `reports/codeql-java-modeling.json` + +24 results: 12 `reached`, 12 `not-reached`. **24/24** — 12 true positives, 12 +true negatives, no false positive and no false negative anywhere in the matrix. +Every category the partition awarded it is answered exactly as declared, +including the two the preregistration flagged as needing implementation-time +verification: template 8's store-through summary (encoded as a step from the +declared argument onto reads of the declared field of the declared object) and +category B's roundtrip (paired steps conditioned on equal constant keys and on +the store identity). + +This is the result a query language whose data-flow configuration *is* a +declaration surface should produce, and it is not a ranking. What it does +establish is that the twelve templates are *satisfiable as preregistered* — each +one has at least one engine that gets it right — so a miss elsewhere in this +matrix is a statement about that engine and not about a badly posed cell. + +### Joern 4.0.610 — `reports/joern-java-modeling.json` + +24 results: 12 `reached`, 12 `not-reached`. **20/24** — 10 true positives, 10 +true negatives, 2 false positives, 2 false negatives. Categories S, Z, and E are +4/4. The four misses fall into three distinct engine facts, each worth +publishing on its own terms. + +**Positional fidelity did not hold (template 4's negative, a false positive).** +The semantics entry declares `Opaque.select` as index 2 → return, and taint at +the *undeclared* index 1 reached the sink anyway. The declaration is still +load-bearing — replacing the mapping with `NilSemantics` removes both cells' +findings, and removing the entry entirely lets the engine walk the reflective +body instead — so this is not "the model was ignored". It is narrower and more +interesting: the mapping is applied, and its **index is not enforced**. The +preregistration expected the opposite ("the index is the mapping's own key, so +positional fidelity is native rather than emulated"), and the disagreement is +published as observed. + +**The access-path destination did not discriminate (template 8's negative, a +false positive).** `Bridge.deposit` is declared `1 -> 2 "payload"`, and the +sibling field read `box.spare` was reported as tainted too. The preregistration +recorded exactly this as unverified — *"`FlowPath` is the surface; its +access-path expressiveness for a field destination is to be verified at +implementation, and template 8 alone is unsupported for Joern if it cannot be +expressed."* It can be *written*; it does not discriminate. Under the document's +own rule this is the shape of a proposed amendment for that cell, dated and +separate. + +**The persistence roundtrip did not close (both category-B positives, false +negatives).** The two boundary declarations load and the negatives are correct, +but no flow crosses from `Store.put`'s value parameter to `Store.get`'s return +in either the type-bound or the instance-bound spelling. The preregistration +chose to *leave the key and instance discrimination to the engine* — the model +declares the boundary, the analysis decides whether the roundtrip closes — and +on this engine it does not close at all. That is a coverage result about Joern's +handling of a store modeled through a receiver, not a defect in the +declarations, and the two correct negatives are correct for the same reason the +positives are wrong, which is exactly the case the balanced-pair design exists +to make visible. + +### Semgrep CE 1.174.0 — `reports/semgrep-java-modeling.json` + +24 results: 5 `reached`, 7 `not-reached`, 12 `unsupported`. **11/12** on the +scored partition — 5 true positives, 6 true negatives, no false positive, one +false negative. + +Categories S and E are 4/4. Category E is worth restating because it is the +counter-intuitive one and the preregistration called it in advance: an +intraprocedural engine handles an uncalled handler *well*, because the sink is +inside the handler's own body and the absence of a caller is the normal case +rather than a problem. The declaration binds selectively — the undeclared +siblings `onIgnored` and `onUndeclared` produce nothing. + +The single miss is **template 6's positive**, where the flow passes through the +*undeclared* sanitizer-shaped `Clean.sanitize` and must still be reported. It is +not reported, and the reason is the load-bearing option itself: see below. + +## Load-bearing verification + +The preregistration's rule is that the model, not the propagation, is what is +being scored — a cell the tool's default already decides is not a measurement. +Every scored tool has at least one demonstrated counterfactual here: remove the +declaration, and the finding goes away. Each probe removes **one** declaration +from the committed artifact, leaves the rest intact, and re-runs the affected +cell together with a control cell that depends on a different declaration. + +| Tool | Category | Declaration removed | Affected cell | Control cell | +| --- | --- | --- | --- | --- | +| Bifrost | S | the `Config.fetchRemote` `:sources` entry | template 1 positive: 1 finding → **0** | template 2 positive: 1 → 1 | +| CodeQL | P | the `Opaque.carry` `isAdditionalFlowStep` clause | template 3 positive: 1 result → **0** | template 4 positive: 1 → 1 | +| Joern | Z | the `Clean.scrub` semantics line (8 of 9 entries kept) | templates 5 and 6 negatives: 0 flows → **1 each** | template 7 negative: 0 → 0 | +| Semgrep CE | S | the `Config.fetchRemote(...)` `pattern-sources` entry | template 1 positive: 1 finding → **0** | template 2 positive: 1 → 1 | +| Semgrep CE | E | the `void onRequest($T $P) { ... }` source | template 9 positive: 1 finding → **0** | template 10 positive: 1 → 1 | + +CodeQL's probe is also the check that template 3 is doing what it was designed +to do. The reflective body is the construct the v0.4.0 freeze establishes no +engine follows, and with the propagator step removed CodeQL indeed reports +nothing — so the positive cell can only be `reached` because the model was +activated, which is the whole reason the template is assertable. + +### Where the requirement did not hold: Semgrep CE, category Z + +The load-bearing gate obliges a Semgrep modeling rule to set +`options: taint_assume_safe_functions: true`, because without it the pinned CE +engine carries taint from any tainted argument to a call's result. On this +population that option **also suppresses the flow through the declared +sanitizer**, so the sanitizer declaration is inert and the default is what +decides the category-Z cells. Four runs over the two selectivity cells and one +kill cell, with the two variables crossed: + +| `taint_assume_safe_functions` | `pattern-sanitizers` | T6 positive (`Clean.sanitize`) | T6 negative (`Clean.scrub`) | T5 negative (`Clean.scrub`) | +| --- | --- | --- | --- | --- | +| `true` (committed) | declared | 0 | 0 | 0 | +| `true` | removed | 0 | 0 | 0 | +| `false` | declared | 1 | 0 | 0 | +| `false` | removed | 1 | 1 | 1 | + +Rows one and two are identical: with the option on, removing the declaration +changes nothing, which is the definition of a declaration that is not +load-bearing. Rows three and four are the pair the preregistration's own probe +found: with the option off, the `Clean.scrub` declaration is exactly what +decides both negatives, and template 6's positive is reported correctly through +the undeclared sibling. + +So on Java the option and the requirement point in opposite directions. Category +Z is scored here as the preregistration and the runner gate require — option on, +sanitizer declared — and the outcome (3/4, with template 6's positive as a false +negative) is published as observed. **It is not tuned around.** Declaring a +propagator for `Clean.sanitize` would recover the cell and would be tuning +toward the expected polarity, and category P is one this partition does not +award CE in the first place. + +The proposed amendment this run supports is narrow: for Semgrep CE, the +load-bearing configuration for category Z is +`taint_assume_safe_functions: false`, not `true`, because on a category-Z +fixture the sanitizer's own call is the call the option neutralizes. Writing +that is a dated amendment on [the preregistration](modeling-matrix.md), in its +own commit, and nothing here anticipates it. + +### Joern's propagator declaration, separated from its index + +The category-P false positive above deserves its own counterfactual, because +"the model was ignored" and "the model was applied to the wrong position" are +different findings and only one of them is true. + +| `Opaque.select` semantics | T4 positive (taint at declared position 1) | T4 negative (taint at undeclared position 0) | +| --- | --- | --- | +| `2 -> -1` (committed) | 1 flow | 1 flow | +| declared with no mapping (`NilSemantics`) | 0 | 0 | +| absent from the file entirely | 1 flow, walking the reflective body | 1 flow, walking the reflective body | + +The middle row is the demonstration: the declaration is what the engine acts on, +and switching it from a mapping to no-flow removes both findings. The top row is +the defect: the mapping's index is not what selects the argument. The bottom row +is why the file must declare `select` at all — with no entry, Joern walks the +reflective body through `Method.invoke`'s `Object[]` argument and reaches the +sink on its own. + +## Proposed amendments + +None applied. Recorded here for a separate, dated change on +[the preregistration](modeling-matrix.md)'s own terms: + +1. **Semgrep CE, category Z, load-bearing configuration.** The requirement's + `taint_assume_safe_functions: true` makes the sanitizer declaration inert on + a category-Z fixture; the four-way probe above is the evidence. +2. **Joern, template 8.** `FlowPath`'s access-path destination can be written + but does not discriminate the declared field from its sibling on 4.0.610 — + which is the condition the preregistration itself named for that cell. +3. **Joern, category P, positional fidelity.** The preregistration states the + mapping's index is native; on 4.0.610 it is not enforced. +4. **Bifrost, `require-model`.** The pinned build accepts it. This removes one + of the two stated obstacles to promoting Bifrost's category P; the other — + showing that a propagator or transform section actually lowers — is + untouched, so the cell does not move on this evidence alone. + +## Reproduction + +```bash +cargo run -- run-bifrost-modeling --language java --bifrost /path/to/bifrost +cargo run -- run-codeql-modeling --language java --codeql /path/to/codeql +cargo run -- run-joern-modeling --language java --joern /path/to/joern-cli/joern +cargo run -- run-semgrep-modeling --language java --semgrep /path/to/semgrep +``` + +Run them sequentially, never concurrently. Each writes +`reports/-java-modeling.json` with retained evidence under +`reports/raw/-java-modeling/`; none of the eight paths collides with a +report the v0.4.0 freeze binds. diff --git a/docs/milestones.md b/docs/milestones.md index 07e398c..9abd5e7 100644 --- a/docs/milestones.md +++ b/docs/milestones.md @@ -207,6 +207,18 @@ than discovered as a failure. Unlike the challenge tier, these templates are own scorecards and never enter any language's core denominator. Issue #16's tool-native profiles build on the same category taxonomy and supply no models. +### Wave M1: Java + +Java is the first language of the matrix's three-language wave. Its twenty-four +assertions, the four per-adapter model artifacts encoding the same +analyzer-neutral declarations, and the four runs are recorded in +[the Java modeling report](java-modeling.md). No template proved unimplementable +as preregistered and no partition cell was revised; where a run disagreed with +what the preregistration expected, the disagreement is published as observed and +carried forward as a *proposed* amendment rather than applied. JavaScript and +Python have no modeling denominator until their own waves land, which is +different from having a zero. + ## M4: real-project confirmation Add a small, pinned, manually reviewed corpus drawn from executable or diff --git a/reports/bifrost-java-modeling.json b/reports/bifrost-java-modeling.json new file mode 100644 index 0000000..35b55ed --- /dev/null +++ b/reports/bifrost-java-modeling.json @@ -0,0 +1,418 @@ +{ + "adapter_version": "0.1.0", + "cold_or_warm": "cold", + "configuration_hash": "921d2c8e531813bf7c9bb93fd6da710e62020f60f9caadc7ac0096c5c31121d9", + "ended_at_unix_seconds": 1787743127, + "fixture_revision": "sha256:727c6838741d80705ac5f6ed0754862400ad7504bfc68ac7df32b6bfb73553c6", + "results": [ + { + "case_id": "dfb-taint-java-model-declared-sink-negative", + "diagnostics": [], + "duration_ms": 1124, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-negative.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-sink-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink" + ], + "duration_ms": 173, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-positive.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-negative", + "diagnostics": [], + "duration_ms": 150, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-negative.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink" + ], + "duration_ms": 127, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-positive.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-negative", + "diagnostics": [ + "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-positive", + "diagnostics": [ + "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-negative", + "diagnostics": [ + "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-positive", + "diagnostics": [ + "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-negative", + "diagnostics": [ + "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-positive", + "diagnostics": [ + "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-negative", + "diagnostics": [ + "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-positive", + "diagnostics": [ + "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-negative", + "diagnostics": [ + "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-positive", + "diagnostics": [ + "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-negative", + "diagnostics": [ + "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-positive", + "diagnostics": [ + "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-negative", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-positive", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-negative", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-positive", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-negative", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-positive", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-negative", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-positive", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + } + ], + "schema_version": 1, + "started_at_unix_seconds": 1787743125, + "tool": "bifrost", + "tool_build_identity": "18d09c57d1e5044dec49acac7635d3255ea8e89c", + "tool_version": "bifrost 0.10.6" +} diff --git a/reports/codeql-java-modeling.json b/reports/codeql-java-modeling.json new file mode 100644 index 0000000..1bb7a38 --- /dev/null +++ b/reports/codeql-java-modeling.json @@ -0,0 +1,404 @@ +{ + "adapter_version": "0.1.0", + "cold_or_warm": "cold", + "configuration_hash": "38acb5de67ed39a244c7eb8a9db755ddbcf197488051a5f1ec0d35b65fa30aee", + "ended_at_unix_seconds": 1787747511, + "fixture_revision": "sha256:727c6838741d80705ac5f6ed0754862400ad7504bfc68ac7df32b6bfb73553c6", + "results": [ + { + "case_id": "dfb-taint-java-model-declared-sink-negative", + "diagnostics": [], + "duration_ms": 42218, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-sink-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 183669, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-negative", + "diagnostics": [], + "duration_ms": 32114, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 25767, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-negative", + "diagnostics": [ + "1 finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's", + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 25194, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 156723, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-negative", + "diagnostics": [ + "1 finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's", + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 68234, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 195401, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-negative", + "diagnostics": [], + "duration_ms": 69684, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 175872, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-negative", + "diagnostics": [], + "duration_ms": 37189, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 85117, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-negative", + "diagnostics": [], + "duration_ms": 205474, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 80114, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-negative", + "diagnostics": [], + "duration_ms": 39945, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 108787, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-negative", + "diagnostics": [], + "duration_ms": 88118, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 58095, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-negative", + "diagnostics": [], + "duration_ms": 167520, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 160354, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-negative", + "diagnostics": [], + "duration_ms": 55659, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 41612, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-negative", + "diagnostics": [], + "duration_ms": 36022, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-negative.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-positive", + "diagnostics": [ + "A benchmark-declared model carried input to the declared sink." + ], + "duration_ms": 20444, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-positive.sarif.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + } + ], + "schema_version": 1, + "started_at_unix_seconds": 1787745350, + "tool": "codeql", + "tool_build_identity": "codeql-cli:7d097a43199effe04ecd9c6bd3ad9bb02a45b3d7", + "tool_version": "2.26.3" +} diff --git a/reports/joern-java-modeling.json b/reports/joern-java-modeling.json new file mode 100644 index 0000000..ea615c0 --- /dev/null +++ b/reports/joern-java-modeling.json @@ -0,0 +1,424 @@ +{ + "adapter_version": "0.1.0", + "cold_or_warm": "cold", + "configuration_hash": "8f5fa46060e827c588cd688c684770dee8b99bc609a172c0f64231d89d911b91", + "ended_at_unix_seconds": 1787748744, + "fixture_revision": "sha256:727c6838741d80705ac5f6ed0754862400ad7504bfc68ac7df32b6bfb73553c6", + "results": [ + { + "case_id": "dfb-taint-java-model-declared-sink-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 0 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 46311, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-negative.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-sink-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 18206, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-positive.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-negative", + "diagnostics": [ + "Joern bound 0 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 23397, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-negative.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 13087, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-positive.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-negative", + "diagnostics": [ + "1 finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's", + "Joern bound 1 declared source node(s) and 2 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 12369, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 2 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 131901, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-negative", + "diagnostics": [ + "1 finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's", + "Joern bound 1 declared source node(s) and 2 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 65106, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 2 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 38432, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 37554, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-negative.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 25765, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-positive.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 25549, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-negative.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 30376, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-positive.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 30020, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 42825, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 27303, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 25034, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 25862, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-negative.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 17869, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-positive.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 134012, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-negative.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 42640, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-positive.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 38180, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-negative.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 39551, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-positive.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-negative", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 44752, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-negative.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-positive", + "diagnostics": [ + "Joern bound 1 declared source node(s) and 1 declared sink node(s) under 9 loaded semantic entr(ies)" + ], + "duration_ms": 147997, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-positive.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + } + ], + "schema_version": 1, + "started_at_unix_seconds": 1787747599, + "tool": "joern", + "tool_build_identity": "joern-cli:4.0.610", + "tool_version": "4.0.610" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-negative.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-negative.json new file mode 100644 index 0000000..a0b2fc3 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-negative.json @@ -0,0 +1 @@ +{"schema_version":5,"evaluation":{"evaluation_date":"2026-08-11","suppression_sources":[{"path":".bifrost/suppressions.json","state":"not_found"},{"path":".bifrost/suppressions.private.json","state":"not_found"},{"path":".bifrost/suppressions.local.json","state":"not_found"}],"scope_path":".bifrost/policy-scope.json","scope_document_state":"not_found"},"execution":{"total_elapsed_ms":0,"stage_timings":[],"termination":null,"terminal_stage":null,"active_policy_id":null,"completed_policy_ids":[],"pending_policy_ids":[]},"rules":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","policy_schema":{"version":1,"origin":"explicit"},"selector_schemas":[{"path":"/analysis/sinks/entries/declared-sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sinks/entries/sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/declared-source/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/input/selector","resolution":{"version":1,"origin":"explicit"}}],"endpoint_dependencies":[{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/declared-sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"Audit.record","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"ca5f95a181dd48460b9824d0efa881784970b23cee888d6978b2ac7052d4e1b8","analysis_projection_hash":"d363c6c98379de62f3b873ddd371d29750835db27374c05eaae279abebe4e570","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/declared-sink"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-source"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/declared-source/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"Config.fetchRemote","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"e9a7217df5670b3b88bcdf42ba7e5dfbc6f826f109e75d6d1661192725413ad1","analysis_projection_hash":"cf57d45f5aa9335e9cd6372f1ce817dcc569b8bb153df7d074da79614169b550","origins":[{"type":"policy_local","path":"/analysis/sources/entries/declared-source"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"input"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/input/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"benchmark input","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"a7086bee9e3b830fec298d9c60e31a18d0a1b5def9088091dd89ded489a1b094","analysis_projection_hash":"e8c42d395df5363d0a789c7ce734dfbf40662b3cd18757fc730b80ccaea4bab0","origins":[{"type":"policy_local","path":"/analysis/sources/entries/input"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"benchmark sink","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"b52687a8ab41d5d17210b86f12a811f4685621b9951f5a655b49bf1de1ec394a","analysis_projection_hash":"25d9c2ebb7b961bbe416e36651d6fec2898ab0d1bee858193f0faedd564ed2e8","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/sink"}]}],"match_directory_manifests":[],"precedence_manifest":{"edges":[]},"name":"DataFlowBench Java taint-modeling matrix","message":{"type":"static","text":"A benchmark-declared model carried input to the declared sink"},"severity":{"type":"fixed","level":"warning"},"description":null,"help_uri":null,"tags":[]}],"runs":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","completion":{"type":"complete"},"findings":[],"diagnostics":[],"diagnostics_truncated":false,"obligations":[],"obligations_truncated":false,"omitted_obligations_lower_bound":0,"work":{"scanned_files":4,"scanned_source_bytes":1548,"fact_nodes":70,"pipeline_rows":1,"examined_references":0,"retained_findings":0,"omitted_findings_lower_bound":0,"retained_report_bytes":4127,"metrics":[{"name":"taint.selector_scans","unit":"count","value":4},{"name":"taint.semantic_materialized_files","unit":"count","value":1},{"name":"taint.semantic_peak_retained_bytes","unit":"bytes","value":3654},{"name":"taint.semantic_peak_row_dimension","unit":"rows","value":307},{"name":"taint.semantic_peak_traversal_steps","unit":"count","value":7},{"name":"taint.semantic_program_points","unit":"rows","value":27},{"name":"taint.semantic_source_bytes","unit":"bytes","value":387},{"name":"taint.semantic_traversal_steps","unit":"count","value":7}]}}],"suppressions":[],"scope":[],"diagnostics":[],"diagnostics_truncated":false,"omitted_diagnostics_lower_bound":0,"worst_omitted_diagnostic_severity":null} \ No newline at end of file diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-positive.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-positive.json new file mode 100644 index 0000000..b8a2569 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-sink-positive.json @@ -0,0 +1 @@ +{"schema_version":5,"evaluation":{"evaluation_date":"2026-08-11","suppression_sources":[{"path":".bifrost/suppressions.json","state":"not_found"},{"path":".bifrost/suppressions.private.json","state":"not_found"},{"path":".bifrost/suppressions.local.json","state":"not_found"}],"scope_path":".bifrost/policy-scope.json","scope_document_state":"not_found"},"execution":{"total_elapsed_ms":0,"stage_timings":[],"termination":null,"terminal_stage":null,"active_policy_id":null,"completed_policy_ids":[],"pending_policy_ids":[]},"rules":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","policy_schema":{"version":1,"origin":"explicit"},"selector_schemas":[{"path":"/analysis/sinks/entries/declared-sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sinks/entries/sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/declared-source/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/input/selector","resolution":{"version":1,"origin":"explicit"}}],"endpoint_dependencies":[{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/declared-sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"Audit.record","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"ca5f95a181dd48460b9824d0efa881784970b23cee888d6978b2ac7052d4e1b8","analysis_projection_hash":"d363c6c98379de62f3b873ddd371d29750835db27374c05eaae279abebe4e570","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/declared-sink"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-source"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/declared-source/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"Config.fetchRemote","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"e9a7217df5670b3b88bcdf42ba7e5dfbc6f826f109e75d6d1661192725413ad1","analysis_projection_hash":"cf57d45f5aa9335e9cd6372f1ce817dcc569b8bb153df7d074da79614169b550","origins":[{"type":"policy_local","path":"/analysis/sources/entries/declared-source"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"input"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/input/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"benchmark input","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"a7086bee9e3b830fec298d9c60e31a18d0a1b5def9088091dd89ded489a1b094","analysis_projection_hash":"e8c42d395df5363d0a789c7ce734dfbf40662b3cd18757fc730b80ccaea4bab0","origins":[{"type":"policy_local","path":"/analysis/sources/entries/input"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"benchmark sink","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"b52687a8ab41d5d17210b86f12a811f4685621b9951f5a655b49bf1de1ec394a","analysis_projection_hash":"25d9c2ebb7b961bbe416e36651d6fec2898ab0d1bee858193f0faedd564ed2e8","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/sink"}]}],"match_directory_manifests":[],"precedence_manifest":{"edges":[]},"name":"DataFlowBench Java taint-modeling matrix","message":{"type":"static","text":"A benchmark-declared model carried input to the declared sink"},"severity":{"type":"fixed","level":"warning"},"description":null,"help_uri":null,"tags":[]}],"runs":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","completion":{"type":"complete"},"findings":[{"id":"26ddd9bfde09b49457a474e616d9bc296863c77321fecbffa243b7a9b73f4d84","identity_stability":"strong","policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","severity":"warning","message":"A benchmark-declared model carried input to the declared sink","classification":{"type":"unclassified"},"certainty":{"type":"definite"},"completeness":{"type":"complete"},"primary":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":376},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":35}},"related":[{"relationship":"source","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"evidence_refs":[]}],"related_truncated":false,"omitted_related_locations_lower_bound":0,"evidence":{"type":"taint","evidence":{"analysis_finding_id":"bifrost:0f0da97e6f31d1f6715229294469b40890fe8eb57dbb8e69c467ed391533857b","anchor":{"type":"strong","sink_identity":{"namespace":"java","path":"ModelDeclaredSinkPositive.java","derivation":"canonical_ast_identity","semantic_key":"[[\"file\",\"ModelDeclaredSinkPositive.java\"],[\"type\",\"ModelDeclaredSinkPositive\"],[\"method\",\"run\"],[\"program_point\",null]]"},"sink_site_ordinal":0,"source_endpoint_analysis_projection_hash":"e8c42d395df5363d0a789c7ce734dfbf40662b3cd18757fc730b80ccaea4bab0","sink_endpoint_analysis_projection_hash":"d363c6c98379de62f3b873ddd371d29750835db27374c05eaae279abebe4e570","source_scenario_set_hash":"fcdd6e26abdbafa84a133957b6befa98c3475fe81c2cadb67a915e2266d5c978"},"sink":"bifrost:10ec00ddd8f56f310e1346dfd865524f26586ca985a68bb4f394a5ce0539251d","source_endpoint":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"input"},"sink_endpoint":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-sink"},"source_display_name":"benchmark input","sink_display_name":"Audit.record","source_categories":["input.user-controlled"],"sink_categories":["data.sensitive"],"selected_combination":null,"sink_tags":[],"sink_impacts":[],"reached_source_labels":["attacker-controlled"],"origins":[{"source_endpoint":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"input"},"source_label":"attacker-controlled","source_evidence":null,"primary":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"scenario_id":"bifrost:5332acd675067256244cdd9e5035023b6d92f8d86124319f04d97e15709e5e22:source-event:0","evidence_refs":["bifrost:89ae194caedbcc08974ffdda58fe113abdebbcb88910ee7dab23d64cdc12031d"]}],"origins_truncated":false,"source_scenarios":["bifrost:5332acd675067256244cdd9e5035023b6d92f8d86124319f04d97e15709e5e22:source-event:0"],"source_scenarios_truncated":false,"omitted_source_scenarios_lower_bound":0,"source_scenario_set_hash":"fcdd6e26abdbafa84a133957b6befa98c3475fe81c2cadb67a915e2266d5c978","witness_refs":["bifrost:4ee838183d3276f3d4ead0883201ad23c2261ede0f7b9608c4b5e4a35562b2bf","bifrost:5856f56db63e01060ead3c87f7ebbcba27ab1c5e44a4581e4a3eeee322967e6c","bifrost:7d99f95f61e69f95e5debf2e464008b40f4f1bef5f2b7ce615e86029573485f4"],"witness_refs_truncated":false,"projection_facts_hash":"7023f632d2bf8d71c349cb5c8916357c613b5a3ca968dc436a5af34c700b0120"}},"evidence_refs_truncated":false,"omitted_evidence_refs_lower_bound":0,"cvss":null,"organizational_risk":null,"proof":{"state":"proven","reasons":[{"type":"dataflow_witness"}],"evidence_refs":[]},"witnesses":[{"id":"bifrost:4ee838183d3276f3d4ead0883201ad23c2261ede0f7b9608c4b5e4a35562b2bf","steps":[{"kind":"source","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":322,"end":383},"region":{"start_line":14,"start_column":5,"end_line":16,"end_column":6}},"label":"taint source","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":322,"end":383},"region":{"start_line":14,"start_column":5,"end_line":16,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":340,"end":383},"region":{"start_line":14,"start_column":23,"end_line":16,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":377},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":36}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":355},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":14}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":376},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":35}},"label":"taint propagation","evidence_refs":[]}],"truncated":false,"omitted_steps_lower_bound":0,"retained_bytes":1850},{"id":"bifrost:5856f56db63e01060ead3c87f7ebbcba27ab1c5e44a4581e4a3eeee322967e6c","steps":[{"kind":"source","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":322,"end":383},"region":{"start_line":14,"start_column":5,"end_line":16,"end_column":6}},"label":"taint source","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":322,"end":383},"region":{"start_line":14,"start_column":5,"end_line":16,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":340,"end":383},"region":{"start_line":14,"start_column":23,"end_line":16,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":377},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":36}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":355},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":14}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":376},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":35}},"label":"taint propagation","evidence_refs":[]}],"truncated":false,"omitted_steps_lower_bound":0,"retained_bytes":1850},{"id":"bifrost:7d99f95f61e69f95e5debf2e464008b40f4f1bef5f2b7ce615e86029573485f4","steps":[{"kind":"source","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":322,"end":383},"region":{"start_line":14,"start_column":5,"end_line":16,"end_column":6}},"label":"taint source","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":322,"end":383},"region":{"start_line":14,"start_column":5,"end_line":16,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":340,"end":383},"region":{"start_line":14,"start_column":23,"end_line":16,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":377},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":36}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":355},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":14}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":376},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":35}},"label":"taint propagation","evidence_refs":[]}],"truncated":false,"omitted_steps_lower_bound":0,"retained_bytes":1850}],"witnesses_truncated":false,"omitted_witnesses_lower_bound":0,"display_path":{"schema_version":1,"representative_witness_id":"bifrost:4ee838183d3276f3d4ead0883201ad23c2261ede0f7b9608c4b5e4a35562b2bf","witness_ids":["bifrost:4ee838183d3276f3d4ead0883201ad23c2261ede0f7b9608c4b5e4a35562b2bf","bifrost:5856f56db63e01060ead3c87f7ebbcba27ab1c5e44a4581e4a3eeee322967e6c","bifrost:7d99f95f61e69f95e5debf2e464008b40f4f1bef5f2b7ce615e86029573485f4"],"steps":[{"kind":"source","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":363,"end":375},"region":{"start_line":15,"start_column":22,"end_line":15,"end_column":34}},"label":"dfb_source()"},{"kind":"sink","location":{"path":"ModelDeclaredSinkPositive.java","byte_span":{"start":350,"end":376},"region":{"start_line":15,"start_column":9,"end_line":15,"end_column":35}},"label":"Audit.record(dfb_source())"}],"canonical_incomplete":false,"omitted_meaningful_steps":0,"alternatives_truncated":false,"omitted_alternative_paths_lower_bound":0,"omitted_witnesses_lower_bound":0},"suppression":null,"scope":null}],"diagnostics":[],"diagnostics_truncated":false,"obligations":[],"obligations_truncated":false,"omitted_obligations_lower_bound":0,"work":{"scanned_files":4,"scanned_source_bytes":1544,"fact_nodes":70,"pipeline_rows":2,"examined_references":0,"retained_findings":1,"omitted_findings_lower_bound":0,"retained_report_bytes":13219,"metrics":[{"name":"taint.propagation_shared_memberships","unit":"count","value":0},{"name":"taint.propagation_solves","unit":"count","value":1},{"name":"taint.selector_scans","unit":"count","value":4},{"name":"taint.semantic_materialized_files","unit":"count","value":2},{"name":"taint.semantic_peak_retained_bytes","unit":"bytes","value":3654},{"name":"taint.semantic_peak_row_dimension","unit":"rows","value":307},{"name":"taint.semantic_peak_traversal_steps","unit":"count","value":13},{"name":"taint.semantic_program_points","unit":"rows","value":108},{"name":"taint.semantic_snapshot_materializations","unit":"count","value":4},{"name":"taint.semantic_source_bytes","unit":"bytes","value":1158},{"name":"taint.semantic_traversal_steps","unit":"count","value":19}]}}],"suppressions":[],"scope":[],"diagnostics":[],"diagnostics_truncated":false,"omitted_diagnostics_lower_bound":0,"worst_omitted_diagnostic_severity":null} \ No newline at end of file diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-negative.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-negative.json new file mode 100644 index 0000000..818556c --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-negative.json @@ -0,0 +1 @@ +{"schema_version":5,"evaluation":{"evaluation_date":"2026-08-11","suppression_sources":[{"path":".bifrost/suppressions.json","state":"not_found"},{"path":".bifrost/suppressions.private.json","state":"not_found"},{"path":".bifrost/suppressions.local.json","state":"not_found"}],"scope_path":".bifrost/policy-scope.json","scope_document_state":"not_found"},"execution":{"total_elapsed_ms":0,"stage_timings":[],"termination":null,"terminal_stage":null,"active_policy_id":null,"completed_policy_ids":[],"pending_policy_ids":[]},"rules":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","policy_schema":{"version":1,"origin":"explicit"},"selector_schemas":[{"path":"/analysis/sinks/entries/declared-sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sinks/entries/sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/declared-source/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/input/selector","resolution":{"version":1,"origin":"explicit"}}],"endpoint_dependencies":[{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/declared-sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"Audit.record","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"ca5f95a181dd48460b9824d0efa881784970b23cee888d6978b2ac7052d4e1b8","analysis_projection_hash":"d363c6c98379de62f3b873ddd371d29750835db27374c05eaae279abebe4e570","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/declared-sink"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-source"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/declared-source/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"Config.fetchRemote","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"e9a7217df5670b3b88bcdf42ba7e5dfbc6f826f109e75d6d1661192725413ad1","analysis_projection_hash":"cf57d45f5aa9335e9cd6372f1ce817dcc569b8bb153df7d074da79614169b550","origins":[{"type":"policy_local","path":"/analysis/sources/entries/declared-source"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"input"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/input/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"benchmark input","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"a7086bee9e3b830fec298d9c60e31a18d0a1b5def9088091dd89ded489a1b094","analysis_projection_hash":"e8c42d395df5363d0a789c7ce734dfbf40662b3cd18757fc730b80ccaea4bab0","origins":[{"type":"policy_local","path":"/analysis/sources/entries/input"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"benchmark sink","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"b52687a8ab41d5d17210b86f12a811f4685621b9951f5a655b49bf1de1ec394a","analysis_projection_hash":"25d9c2ebb7b961bbe416e36651d6fec2898ab0d1bee858193f0faedd564ed2e8","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/sink"}]}],"match_directory_manifests":[],"precedence_manifest":{"edges":[]},"name":"DataFlowBench Java taint-modeling matrix","message":{"type":"static","text":"A benchmark-declared model carried input to the declared sink"},"severity":{"type":"fixed","level":"warning"},"description":null,"help_uri":null,"tags":[]}],"runs":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","completion":{"type":"complete"},"findings":[],"diagnostics":[],"diagnostics_truncated":false,"obligations":[],"obligations_truncated":false,"omitted_obligations_lower_bound":0,"work":{"scanned_files":4,"scanned_source_bytes":1664,"fact_nodes":72,"pipeline_rows":1,"examined_references":0,"retained_findings":0,"omitted_findings_lower_bound":0,"retained_report_bytes":4127,"metrics":[{"name":"taint.selector_scans","unit":"count","value":4},{"name":"taint.semantic_materialized_files","unit":"count","value":1},{"name":"taint.semantic_peak_retained_bytes","unit":"bytes","value":4018},{"name":"taint.semantic_peak_row_dimension","unit":"rows","value":323},{"name":"taint.semantic_peak_traversal_steps","unit":"count","value":7},{"name":"taint.semantic_program_points","unit":"rows","value":29},{"name":"taint.semantic_source_bytes","unit":"bytes","value":416},{"name":"taint.semantic_traversal_steps","unit":"count","value":7}]}}],"suppressions":[],"scope":[],"diagnostics":[],"diagnostics_truncated":false,"omitted_diagnostics_lower_bound":0,"worst_omitted_diagnostic_severity":null} \ No newline at end of file diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-positive.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-positive.json new file mode 100644 index 0000000..ec72f79 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-declared-source-positive.json @@ -0,0 +1 @@ +{"schema_version":5,"evaluation":{"evaluation_date":"2026-08-11","suppression_sources":[{"path":".bifrost/suppressions.json","state":"not_found"},{"path":".bifrost/suppressions.private.json","state":"not_found"},{"path":".bifrost/suppressions.local.json","state":"not_found"}],"scope_path":".bifrost/policy-scope.json","scope_document_state":"not_found"},"execution":{"total_elapsed_ms":0,"stage_timings":[],"termination":null,"terminal_stage":null,"active_policy_id":null,"completed_policy_ids":[],"pending_policy_ids":[]},"rules":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","policy_schema":{"version":1,"origin":"explicit"},"selector_schemas":[{"path":"/analysis/sinks/entries/declared-sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sinks/entries/sink/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/declared-source/selector","resolution":{"version":1,"origin":"explicit"}},{"path":"/analysis/sources/entries/input/selector","resolution":{"version":1,"origin":"explicit"}}],"endpoint_dependencies":[{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/declared-sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"Audit.record","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"ca5f95a181dd48460b9824d0efa881784970b23cee888d6978b2ac7052d4e1b8","analysis_projection_hash":"d363c6c98379de62f3b873ddd371d29750835db27374c05eaae279abebe4e570","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/declared-sink"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-source"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/declared-source/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"Config.fetchRemote","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"e9a7217df5670b3b88bcdf42ba7e5dfbc6f826f109e75d6d1661192725413ad1","analysis_projection_hash":"cf57d45f5aa9335e9cd6372f1ce817dcc569b8bb153df7d074da79614169b550","origins":[{"type":"policy_local","path":"/analysis/sources/entries/declared-source"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"input"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sources/entries/input/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"source","display_name":"benchmark input","categories":["input.user-controlled"],"binding":{"type":"return_value"},"taint":{"type":"source","labels":["attacker-controlled"],"evidence":null},"supersedes":[]},"semantic_hash":"a7086bee9e3b830fec298d9c60e31a18d0a1b5def9088091dd89ded489a1b094","analysis_projection_hash":"e8c42d395df5363d0a789c7ce734dfbf40662b3cd18757fc730b80ccaea4bab0","origins":[{"type":"policy_local","path":"/analysis/sources/entries/input"}]},{"identity":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"sink"},"definition_schema":{"type":"policy_document","resolution":{"version":1,"origin":"explicit"}},"selector_path":"/analysis/sinks/entries/sink/selector","selector_schema":{"version":1,"origin":"explicit"},"model":{"role":"sink","display_name":"benchmark sink","categories":["data.sensitive"],"binding":{"type":"argument_index","index":0},"taint":{"type":"sink","accepts":["attacker-controlled"],"tags":[],"impacts":[]},"supersedes":[]},"semantic_hash":"b52687a8ab41d5d17210b86f12a811f4685621b9951f5a655b49bf1de1ec394a","analysis_projection_hash":"25d9c2ebb7b961bbe416e36651d6fec2898ab0d1bee858193f0faedd564ed2e8","origins":[{"type":"policy_local","path":"/analysis/sinks/entries/sink"}]}],"match_directory_manifests":[],"precedence_manifest":{"edges":[]},"name":"DataFlowBench Java taint-modeling matrix","message":{"type":"static","text":"A benchmark-declared model carried input to the declared sink"},"severity":{"type":"fixed","level":"warning"},"description":null,"help_uri":null,"tags":[]}],"runs":[{"policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","completion":{"type":"complete"},"findings":[{"id":"a5a877d3188bf479ea358d7d522c92e33b71e82c8944912b0145230ed8118f35","identity_stability":"strong","policy_id":"dataflowbench.taint.model-java","policy_hash":"c419872859b67e67c0583d6b66a4eea7cf3350a36a3207a89222db636e8f3c61","analysis_type":"taint","severity":"warning","message":"A benchmark-declared model carried input to the declared sink","classification":{"type":"unclassified"},"certainty":{"type":"definite"},"completeness":{"type":"complete"},"primary":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":407},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":39}},"related":[{"relationship":"source","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"evidence_refs":[]}],"related_truncated":false,"omitted_related_locations_lower_bound":0,"evidence":{"type":"taint","evidence":{"analysis_finding_id":"bifrost:e00d01675bf1235d6fd72ce468c9f7046a73b37596ebbd2ef0c0b83a590a6fed","anchor":{"type":"strong","sink_identity":{"namespace":"java","path":"ModelDeclaredSourcePositive.java","derivation":"canonical_ast_identity","semantic_key":"[[\"file\",\"ModelDeclaredSourcePositive.java\"],[\"type\",\"ModelDeclaredSourcePositive\"],[\"method\",\"run\"],[\"program_point\",null]]"},"sink_site_ordinal":0,"source_endpoint_analysis_projection_hash":"cf57d45f5aa9335e9cd6372f1ce817dcc569b8bb153df7d074da79614169b550","sink_endpoint_analysis_projection_hash":"25d9c2ebb7b961bbe416e36651d6fec2898ab0d1bee858193f0faedd564ed2e8","source_scenario_set_hash":"ec850b2c1c787682bfec02125cfb8b33992b0e4334cd856b1078fc79d35c4a64"},"sink":"bifrost:f27823f2e9c4a580765d15dd30a1cf01212b7c55506bcd95613503e6613010f4","source_endpoint":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-source"},"sink_endpoint":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"sink"},"source_display_name":"Config.fetchRemote","sink_display_name":"benchmark sink","source_categories":["input.user-controlled"],"sink_categories":["data.sensitive"],"selected_combination":null,"sink_tags":[],"sink_impacts":[],"reached_source_labels":["attacker-controlled"],"origins":[{"source_endpoint":{"type":"local","policy_id":"dataflowbench.taint.model-java","entry_id":"declared-source"},"source_label":"attacker-controlled","source_evidence":null,"primary":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"scenario_id":"bifrost:0ece02fa406bfd60cd2ffb1a18e36beec3ca367d93661c2bc6b8a99939130bca:source-event:0","evidence_refs":["bifrost:a443d68b45dacdb3e6185cfa13ca92e0306fa7550728d55c36bfbfd70a4e7f01"]}],"origins_truncated":false,"source_scenarios":["bifrost:0ece02fa406bfd60cd2ffb1a18e36beec3ca367d93661c2bc6b8a99939130bca:source-event:0"],"source_scenarios_truncated":false,"omitted_source_scenarios_lower_bound":0,"source_scenario_set_hash":"ec850b2c1c787682bfec02125cfb8b33992b0e4334cd856b1078fc79d35c4a64","witness_refs":["bifrost:37d397db1820c48ce632f7874098b25d455ba86a28d6c654593849af80b71710","bifrost:4d0541b035fb383be82a142536dedd48ca8fb6db74e04080b0fb00649b004edd","bifrost:e2559ba1ef83358ec3138c634166c25dea826db004c2ceebbb67e7a258841ef5"],"witness_refs_truncated":false,"projection_facts_hash":"41d25abaa0ab3935bf5f0e2b385873ac5f64417c7e50b42c1df8a1d9479a6262"}},"evidence_refs_truncated":false,"omitted_evidence_refs_lower_bound":0,"cvss":null,"organizational_risk":null,"proof":{"state":"proven","reasons":[{"type":"dataflow_witness"}],"evidence_refs":[]},"witnesses":[{"id":"bifrost:37d397db1820c48ce632f7874098b25d455ba86a28d6c654593849af80b71710","steps":[{"kind":"source","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":349,"end":414},"region":{"start_line":16,"start_column":5,"end_line":18,"end_column":6}},"label":"taint source","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":349,"end":414},"region":{"start_line":16,"start_column":5,"end_line":18,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":367,"end":414},"region":{"start_line":16,"start_column":23,"end_line":18,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":408},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":40}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":392},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":24}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":407},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":39}},"label":"taint propagation","evidence_refs":[]}],"truncated":false,"omitted_steps_lower_bound":0,"retained_bytes":1868},{"id":"bifrost:4d0541b035fb383be82a142536dedd48ca8fb6db74e04080b0fb00649b004edd","steps":[{"kind":"source","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":349,"end":414},"region":{"start_line":16,"start_column":5,"end_line":18,"end_column":6}},"label":"taint source","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":349,"end":414},"region":{"start_line":16,"start_column":5,"end_line":18,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":367,"end":414},"region":{"start_line":16,"start_column":23,"end_line":18,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":408},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":40}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":392},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":24}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":407},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":39}},"label":"taint propagation","evidence_refs":[]}],"truncated":false,"omitted_steps_lower_bound":0,"retained_bytes":1868},{"id":"bifrost:e2559ba1ef83358ec3138c634166c25dea826db004c2ceebbb67e7a258841ef5","steps":[{"kind":"source","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":349,"end":414},"region":{"start_line":16,"start_column":5,"end_line":18,"end_column":6}},"label":"taint source","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":349,"end":414},"region":{"start_line":16,"start_column":5,"end_line":18,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":367,"end":414},"region":{"start_line":16,"start_column":23,"end_line":18,"end_column":6}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":408},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":40}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":392},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":24}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"taint propagation","evidence_refs":[]},{"kind":"propagation","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":407},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":39}},"label":"taint propagation","evidence_refs":[]}],"truncated":false,"omitted_steps_lower_bound":0,"retained_bytes":1868}],"witnesses_truncated":false,"omitted_witnesses_lower_bound":0,"display_path":{"schema_version":1,"representative_witness_id":"bifrost:37d397db1820c48ce632f7874098b25d455ba86a28d6c654593849af80b71710","witness_ids":["bifrost:37d397db1820c48ce632f7874098b25d455ba86a28d6c654593849af80b71710","bifrost:4d0541b035fb383be82a142536dedd48ca8fb6db74e04080b0fb00649b004edd","bifrost:e2559ba1ef83358ec3138c634166c25dea826db004c2ceebbb67e7a258841ef5"],"steps":[{"kind":"source","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":386,"end":406},"region":{"start_line":17,"start_column":18,"end_line":17,"end_column":38}},"label":"Config.fetchRemote()"},{"kind":"sink","location":{"path":"ModelDeclaredSourcePositive.java","byte_span":{"start":377,"end":407},"region":{"start_line":17,"start_column":9,"end_line":17,"end_column":39}},"label":"dfb_sink(Config.fetchRemote())"}],"canonical_incomplete":false,"omitted_meaningful_steps":0,"alternatives_truncated":false,"omitted_alternative_paths_lower_bound":0,"omitted_witnesses_lower_bound":0},"suppression":null,"scope":null}],"diagnostics":[],"diagnostics_truncated":false,"obligations":[],"obligations_truncated":false,"omitted_obligations_lower_bound":0,"work":{"scanned_files":4,"scanned_source_bytes":1668,"fact_nodes":72,"pipeline_rows":2,"examined_references":0,"retained_findings":1,"omitted_findings_lower_bound":0,"retained_report_bytes":13301,"metrics":[{"name":"taint.propagation_shared_memberships","unit":"count","value":0},{"name":"taint.propagation_solves","unit":"count","value":1},{"name":"taint.selector_scans","unit":"count","value":4},{"name":"taint.semantic_materialized_files","unit":"count","value":2},{"name":"taint.semantic_peak_retained_bytes","unit":"bytes","value":4018},{"name":"taint.semantic_peak_row_dimension","unit":"rows","value":323},{"name":"taint.semantic_peak_traversal_steps","unit":"count","value":13},{"name":"taint.semantic_program_points","unit":"rows","value":116},{"name":"taint.semantic_snapshot_materializations","unit":"count","value":4},{"name":"taint.semantic_source_bytes","unit":"bytes","value":1251},{"name":"taint.semantic_traversal_steps","unit":"count","value":19}]}}],"suppressions":[],"scope":[],"diagnostics":[],"diagnostics_truncated":false,"omitted_diagnostics_lower_bound":0,"worst_omitted_diagnostic_severity":null} \ No newline at end of file diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative-unsupported.json new file mode 100644 index 0000000..fe954ba --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-entrypoint-parameter-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "E", + "modeling_category_label": "framework entry points", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-entrypoint-parameter" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive-unsupported.json new file mode 100644 index 0000000..137f3f9 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-entrypoint-parameter-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "E", + "modeling_category_label": "framework entry points", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-entrypoint-parameter" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative-unsupported.json new file mode 100644 index 0000000..c7d45de --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-entrypoint-selectivity-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "E", + "modeling_category_label": "framework entry points", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-entrypoint-selectivity" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive-unsupported.json new file mode 100644 index 0000000..f805565 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-entrypoint-selectivity-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "E", + "modeling_category_label": "framework entry points", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category E — framework entry points — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: nothing in the repository or the README describes an entry-root declaration for the policy CLI", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-entrypoint-selectivity" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json new file mode 100644 index 0000000..8eff32d --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-opaque-propagator-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-opaque-propagator" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json new file mode 100644 index 0000000..39e1c5e --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-opaque-propagator-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-opaque-propagator" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json new file mode 100644 index 0000000..bb201b0 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-propagator-position-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-propagator-position" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json new file mode 100644 index 0000000..ec28d89 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-propagator-position-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category P — declared propagators — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no committed policy declares a propagator or transform, and the adapter README makes no propagator claim. Additionally, every committed policy sets `:unmodeled optimistic`, so the modeling policy must also be shown to accept `require-model` before either P cell is load-bearing. Both must be demonstrated on the pinned build", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-propagator-position" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-negative-unsupported.json new file mode 100644 index 0000000..03c5bd0 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-sanitizer-kill-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "Z", + "modeling_category_label": "declared sanitizers", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-sanitizer-kill" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-positive-unsupported.json new file mode 100644 index 0000000..fc32b28 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-kill-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-sanitizer-kill-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "Z", + "modeling_category_label": "declared sanitizers", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-sanitizer-kill" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative-unsupported.json new file mode 100644 index 0000000..110547a --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-sanitizer-selectivity-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "Z", + "modeling_category_label": "declared sanitizers", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-sanitizer-selectivity" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive-unsupported.json new file mode 100644 index 0000000..d6919bb --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-sanitizer-selectivity-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "Z", + "modeling_category_label": "declared sanitizers", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category Z — declared sanitizers — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README states it directly: \"Sanitizer lowering is a future Bifrost CLI capability.\" (`adapters/bifrost/README.md`). The matrix surfaces this rather than hiding it. DataFlowBench is published by Bifrost's vendor, and a partition that quietly granted its own engine a category its own documentation says is unimplemented would be the single most damaging thing this document could do", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-sanitizer-selectivity" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json new file mode 100644 index 0000000..69d59b3 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-store-roundtrip-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-roundtrip" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json new file mode 100644 index 0000000..06e687d --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-store-roundtrip-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-roundtrip" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json new file mode 100644 index 0000000..5e1957c --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-store-separation-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-separation" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json new file mode 100644 index 0000000..1393548 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-store-separation-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category B — persistence boundaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): to be verified — unsupported until shown: no persistence-boundary vocabulary is described anywhere for any adapter, Bifrost included", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-separation" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json new file mode 100644 index 0000000..9c95ac5 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-summary-field-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-field" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json new file mode 100644 index 0000000..eb89041 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-summary-field-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-field" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json new file mode 100644 index 0000000..d6684a6 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-summary-through-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-through" +} diff --git a/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json new file mode 100644 index 0000000..e5eef89 --- /dev/null +++ b/reports/raw/bifrost-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "bifrost", + "case_id": "dfb-taint-java-model-summary-through-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Bifrost v0.10.6", + "reason": "category O — opaque procedure summaries — is unsupported for Bifrost v0.10.6 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the adapter README: \"External semantic-model activation requires an embedding with an explicit catalog, so the modeled-external case is reported as `unsupported` by this CLI adapter with an explicit retained reason. It is not a negative result.\" The existing `dfb-taint-java-modeled-external` calibration case already carries that retained reason in the frozen smoke report", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-through" +} diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-negative.sarif.json new file mode 100644 index 0000000..e960c58 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelDeclaredSinkNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:55:56.712371Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":133},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:55:56.713474Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:55:56.761704Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T11:56:04.148640Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelDeclaredSinkNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-positive.sarif.json new file mode 100644 index 0000000..c2c4cde --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-sink-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelDeclaredSinkPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:56:35.827224Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":94},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:56:35.828305Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:56:35.912260Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T11:58:49.965261Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelDeclaredSinkPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelDeclaredSinkPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":15,"startColumn":22,"endColumn":34}}}],"partialFingerprints":{"primaryLocationLineHash":"32fb655c75af365c:1","primaryLocationStartColumnFingerprint":"13"}}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-negative.sarif.json new file mode 100644 index 0000000..8b7c7c7 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelDeclaredSourceNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:59:41.777465Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":101},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:59:41.778651Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T11:59:41.796073Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T11:59:44.792369Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelDeclaredSourceNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-positive.sarif.json new file mode 100644 index 0000000..bc0a2a9 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-declared-source-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelDeclaredSourcePositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:00:11.298211Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":31},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:00:11.299337Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:00:11.312059Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:00:13.566643Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelDeclaredSourcePositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelDeclaredSourcePositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":17,"startColumn":18,"endColumn":38}}}],"partialFingerprints":{"primaryLocationLineHash":"84f543f78695fa0a:1","primaryLocationStartColumnFingerprint":"9"}}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.sarif.json new file mode 100644 index 0000000..5977f25 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:00:40.877636Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":502},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:00:40.881123Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:00:40.900727Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:00:45.032105Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}}}],"partialFingerprints":{"primaryLocationLineHash":"fe44d1380e76e2ef:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":20,"endColumn":32}},"message":{"text":"input : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}},"message":{"text":"input"}}}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":20,"endColumn":32}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.sarif.json new file mode 100644 index 0000000..dd363b1 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:01:02.561162Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":68},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:01:02.564029Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:01:02.583744Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:03:23.508082Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}}}],"partialFingerprints":{"primaryLocationLineHash":"aecd1509fc3b06be:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":20,"endColumn":32}},"message":{"text":"input : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}},"message":{"text":"input"}}}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":20,"endColumn":32}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.sarif.json new file mode 100644 index 0000000..808624e --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:03:39.315046Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":82},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:03:39.316855Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:03:39.346853Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:03:51.924684Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}}}],"partialFingerprints":{"primaryLocationLineHash":"e77e4495f53671cb:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":21,"endColumn":33}},"message":{"text":"input : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}},"message":{"text":"input"}}}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":21,"endColumn":33}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.sarif.json new file mode 100644 index 0000000..78c2125 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:04:49.929493Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":198},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:04:49.931753Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:04:49.943673Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:07:16.411094Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}}}],"partialFingerprints":{"primaryLocationLineHash":"3d6772e6ba714149:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":21,"endColumn":33}},"message":{"text":"input : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":7,"startColumn":18,"endColumn":23}},"message":{"text":"input"}}}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"Handler.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":6,"startColumn":21,"endColumn":33}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-negative.sarif.json new file mode 100644 index 0000000..70c414c --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelOpaquePropagatorNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:08:03.930156Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":186},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:08:03.931801Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:08:03.947925Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:08:14.424013Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelOpaquePropagatorNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-positive.sarif.json new file mode 100644 index 0000000..17a296d --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-opaque-propagator-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelOpaquePropagatorPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:09:12.942673Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":68},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:09:12.944521Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:09:12.956870Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:11:24.862492Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelOpaquePropagatorPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelOpaquePropagatorPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":37,"startColumn":18,"endColumn":44}}}],"partialFingerprints":{"primaryLocationLineHash":"5ada21557e92fb97:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelOpaquePropagatorPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":37,"startColumn":31,"endColumn":43}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelOpaquePropagatorPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":37,"startColumn":18,"endColumn":44}},"message":{"text":"carry(...)"}},"taxa":[{"id":"Config","properties":{"CodeQL/DataflowRole":"step"}}]}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelOpaquePropagatorPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":37,"startColumn":31,"endColumn":43}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-negative.sarif.json new file mode 100644 index 0000000..590212f --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelPropagatorPositionNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:12:08.351558Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":69},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:12:08.353024Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:12:08.367334Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:12:10.891169Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelPropagatorPositionNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-positive.sarif.json new file mode 100644 index 0000000..b2861d1 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-propagator-position-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelPropagatorPositionPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:12:45.546586Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":65},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:12:45.547771Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:12:45.561721Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:12:47.460574Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelPropagatorPositionPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelPropagatorPositionPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":27,"startColumn":18,"endColumn":54}}}],"partialFingerprints":{"primaryLocationLineHash":"ead92e0a01a72fc5:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelPropagatorPositionPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":27,"startColumn":41,"endColumn":53}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelPropagatorPositionPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":27,"startColumn":18,"endColumn":54}},"message":{"text":"select(...)"}},"taxa":[{"id":"Config","properties":{"CodeQL/DataflowRole":"step"}}]}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelPropagatorPositionPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":27,"startColumn":41,"endColumn":53}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.sarif.json new file mode 100644 index 0000000..5ee78ef --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerKillNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:14:13.771419Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":99},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:14:13.772641Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:14:13.788626Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:16:38.644286Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSanitizerKillNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.sarif.json new file mode 100644 index 0000000..a257741 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerKillPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:17:38.761518Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":82},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:17:38.763389Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:17:38.776365Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:17:49.591486Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSanitizerKillPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerKillPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":17,"startColumn":18,"endColumn":30}}}],"partialFingerprints":{"primaryLocationLineHash":"efb75cb48b7ee9b4:1","primaryLocationStartColumnFingerprint":"9"}}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.sarif.json new file mode 100644 index 0000000..1564434 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:18:58.324390Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":86},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:18:58.325410Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:18:58.341612Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:19:00.805248Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSanitizerSelectivityNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.sarif.json new file mode 100644 index 0000000..64c1e72 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:19:38.300498Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":66},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:19:38.302823Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:19:38.316594Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:19:46.185475Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":21,"startColumn":18,"endColumn":46}}}],"partialFingerprints":{"primaryLocationLineHash":"f7e06401abf63749:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":21,"startColumn":33,"endColumn":45}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":8,"startColumn":28,"endColumn":40}},"message":{"text":"value : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":9,"startColumn":16,"endColumn":21}},"message":{"text":"value : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":21,"startColumn":18,"endColumn":46}},"message":{"text":"sanitize(...)"}}}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSanitizerSelectivityPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":21,"startColumn":33,"endColumn":45}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-negative.sarif.json new file mode 100644 index 0000000..f845938 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreRoundtripNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:21:28.707121Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":109},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:21:28.710445Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:21:28.726532Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:21:33.034734Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelStoreRoundtripNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-positive.sarif.json new file mode 100644 index 0000000..3c472ef --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-roundtrip-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreRoundtripPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:23:02.329198Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":407},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:23:02.336045Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:23:02.714329Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:23:13.840155Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelStoreRoundtripPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreRoundtripPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":23,"startColumn":18,"endColumn":32}}}],"partialFingerprints":{"primaryLocationLineHash":"5bfaf43b096b20ae:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreRoundtripPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":19,"startColumn":24,"endColumn":36}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreRoundtripPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":23,"startColumn":18,"endColumn":32}},"message":{"text":"get(...)"}},"taxa":[{"id":"Config","properties":{"CodeQL/DataflowRole":"step"}}]}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreRoundtripPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":19,"startColumn":24,"endColumn":36}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-negative.sarif.json new file mode 100644 index 0000000..d008148 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreSeparationNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:23:51.414120Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":74},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:23:51.416341Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:23:51.430464Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:26:27.317333Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelStoreSeparationNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-positive.sarif.json new file mode 100644 index 0000000..824e2e8 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-store-separation-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreSeparationPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:26:38.532628Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":65},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:26:38.534378Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:26:38.545161Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:27:57.413965Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelStoreSeparationPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreSeparationPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":27,"startColumn":18,"endColumn":32}}}],"partialFingerprints":{"primaryLocationLineHash":"3b7079b5f762b79f:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreSeparationPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":23,"startColumn":24,"endColumn":36}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreSeparationPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":27,"startColumn":18,"endColumn":32}},"message":{"text":"get(...)"}},"taxa":[{"id":"Config","properties":{"CodeQL/DataflowRole":"step"}}]}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelStoreSeparationPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":23,"startColumn":24,"endColumn":36}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-negative.sarif.json new file mode 100644 index 0000000..8576297 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryFieldNegative.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:29:20.901974Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":102},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:29:20.903298Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:29:20.921367Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:29:35.041713Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSummaryFieldNegative.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-positive.sarif.json new file mode 100644 index 0000000..96b9a79 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-field-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryFieldPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:30:16.368849Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":60},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:30:16.370043Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:30:16.382542Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:30:19.972482Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSummaryFieldPositive.java","uriBaseId":"%SRCROOT%","index":0}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryFieldPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":22,"startColumn":18,"endColumn":29}}}],"partialFingerprints":{"primaryLocationLineHash":"eb50e249d481ac68:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryFieldPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":21,"startColumn":24,"endColumn":36}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryFieldPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":22,"startColumn":18,"endColumn":29}},"message":{"text":"box.payload"}},"taxa":[{"id":"Config","properties":{"CodeQL/DataflowRole":"step"}}]}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryFieldPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":21,"startColumn":24,"endColumn":36}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-negative.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-negative.sarif.json new file mode 100644 index 0000000..e05ff7e --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-negative.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Bridge.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryThroughNegative.java","uriBaseId":"%SRCROOT%","index":1}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:30:57.430372Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":116},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:30:57.433283Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:30:57.449400Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:31:00.554938Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"Bridge.java","uriBaseId":"%SRCROOT%","index":0}},{"location":{"uri":"ModelSummaryThroughNegative.java","uriBaseId":"%SRCROOT%","index":1}}],"results":[],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-positive.sarif.json b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-positive.sarif.json new file mode 100644 index 0000000..51a9654 --- /dev/null +++ b/reports/raw/codeql-java-modeling/dfb-taint-java-model-summary-through-positive.sarif.json @@ -0,0 +1 @@ +{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"CodeQL","organization":"GitHub","semanticVersion":"2.26.3","notifications":[{"id":"java/baseline/expected-extracted-files","name":"java/baseline/expected-extracted-files","shortDescription":{"text":"Expected extracted files"},"fullDescription":{"text":"Files appearing in the source archive that are expected to be extracted."},"defaultConfiguration":{"enabled":true},"properties":{"tags":["expected-extracted-files","telemetry"]}},{"id":"cli/file-coverage-baseline","name":"cli/file-coverage-baseline","shortDescription":{"text":"File coverage baseline telemetry"},"fullDescription":{"text":"File coverage baseline telemetry"},"defaultConfiguration":{"enabled":true}},{"id":"cli/platform","name":"cli/platform","shortDescription":{"text":"Platform"},"fullDescription":{"text":"Platform"},"defaultConfiguration":{"enabled":true}},{"id":"cli/sip-enablement","name":"cli/sip-enablement","shortDescription":{"text":"macOS SIP enablement status"},"fullDescription":{"text":"macOS SIP enablement status"},"defaultConfiguration":{"enabled":true}},{"id":"java/extractor/summary","name":"java/extractor/summary","shortDescription":{"text":"Java extractor telemetry"},"fullDescription":{"text":"Java extractor telemetry"},"defaultConfiguration":{"enabled":true}}],"rules":[{"id":"dataflowbench/java-taint-modeling","name":"dataflowbench/java-taint-modeling","shortDescription":{"text":"DataFlowBench Java taint-modeling matrix"},"fullDescription":{"text":"Encodes the twelve benchmark-supplied model declarations of docs/modeling-matrix.md natively in CodeQL's data-flow configuration surface, for the Java modeling population."},"defaultConfiguration":{"enabled":true,"level":"warning"},"properties":{"tags":["security"],"description":"Encodes the twelve benchmark-supplied model declarations of\n docs/modeling-matrix.md natively in CodeQL's data-flow\n configuration surface, for the Java modeling population.","id":"dataflowbench/java-taint-modeling","kind":"path-problem","name":"DataFlowBench Java taint-modeling matrix","precision":"high","problem.severity":"warning"}}]},"extensions":[{"name":"dataflowbench/codeql-java","semanticVersion":"0.0.1","locations":[{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/codeql/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/java-all","semanticVersion":"9.2.3+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/java-all/9.2.3/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]},{"name":"codeql/threat-models","semanticVersion":"1.0.55+44a68d3a47fcbcd6a6a76ec7d1c1b3a1a28b201e","locations":[{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/","description":{"text":"The QL pack root directory."},"properties":{"tags":["CodeQL/LocalPackRoot"]}},{"uri":"file:///Users/dave/.codeql/packages/codeql/threat-models/1.0.55/qlpack.yml","description":{"text":"The QL pack definition file."},"properties":{"tags":["CodeQL/LocalPackDefinitionFile"]}}]}]},"invocations":[{"toolExecutionNotifications":[{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Bridge.java","uriBaseId":"%SRCROOT%","index":1}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryThroughPositive.java","uriBaseId":"%SRCROOT%","index":0}}}],"message":{"text":""},"level":"none","descriptor":{"id":"java/baseline/expected-extracted-files","index":0},"properties":{"formattedMessage":{"text":""}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:31:33.296215Z","descriptor":{"id":"cli/file-coverage-baseline","index":1},"properties":{"attributes":{"durationMilliseconds":110},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:31:33.298436Z","descriptor":{"id":"cli/platform","index":2},"properties":{"attributes":{"arch":"aarch64","name":"Mac OS X","version":"26.6.2"},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":""},"level":"none","timeUtc":"2026-08-26T12:31:33.311921Z","descriptor":{"id":"cli/sip-enablement","index":3},"properties":{"attributes":{"isEnabled":true},"visibility":{"statusPage":false,"telemetry":true}}},{"message":{"text":"Internal telemetry for the Java extractor.\n\nNo action needed.","markdown":"Internal telemetry for the Java extractor.\n\nNo action needed."},"level":"note","timeUtc":"2026-08-26T12:31:36.006284Z","descriptor":{"id":"java/extractor/summary","index":4},"properties":{"attributes":{"java_vendor":"Eclipse Adoptium","java_version":"21.0.8"},"visibility":{"statusPage":false,"telemetry":true}}}],"executionSuccessful":true}],"artifacts":[{"location":{"uri":"ModelSummaryThroughPositive.java","uriBaseId":"%SRCROOT%","index":0}},{"location":{"uri":"Bridge.java","uriBaseId":"%SRCROOT%","index":1}}],"results":[{"ruleId":"dataflowbench/java-taint-modeling","ruleIndex":0,"rule":{"id":"dataflowbench/java-taint-modeling","index":0},"message":{"text":"A benchmark-declared model carried input to the declared sink."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryThroughPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":11,"startColumn":18,"endColumn":43}}}],"partialFingerprints":{"primaryLocationLineHash":"b44d1b374e8684bb:1","primaryLocationStartColumnFingerprint":"9"},"codeFlows":[{"threadFlows":[{"locations":[{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryThroughPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":11,"startColumn":30,"endColumn":42}},"message":{"text":"dfb_source(...) : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"Bridge.java","uriBaseId":"%SRCROOT%","index":1},"region":{"startLine":4,"startColumn":24,"endColumn":36}},"message":{"text":"value : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"Bridge.java","uriBaseId":"%SRCROOT%","index":1},"region":{"startLine":5,"startColumn":16,"endColumn":21}},"message":{"text":"value : String"}}},{"location":{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryThroughPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":11,"startColumn":18,"endColumn":43}},"message":{"text":"pass(...)"}}}]}]}],"relatedLocations":[{"physicalLocation":{"artifactLocation":{"uri":"ModelSummaryThroughPositive.java","uriBaseId":"%SRCROOT%","index":0},"region":{"startLine":11,"startColumn":30,"endColumn":42}}}]}],"columnKind":"utf16CodeUnits","properties":{"semmle.formatSpecifier":"sarif-latest"}}]} \ No newline at end of file diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-negative.json new file mode 100644 index 0000000..f0cff3d --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-declared-sink-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":6,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":0,"source_nodes":[{"label":"CALL","file":"ModelDeclaredSinkNegative.java","line":15,"method":"dataflowbench.taint.ModelDeclaredSinkNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-positive.json new file mode 100644 index 0000000..6b0dbd1 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-sink-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-declared-sink-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":6,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelDeclaredSinkPositive.java","line":15,"method":"dataflowbench.taint.ModelDeclaredSinkPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelDeclaredSinkPositive.java","line":15,"method":"dataflowbench.taint.ModelDeclaredSinkPositive.run:void()","code":"dfb_source()"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelDeclaredSinkPositive.java","line":15,"method":"dataflowbench.taint.ModelDeclaredSinkPositive.run:void()","code":"dfb_source()"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-negative.json new file mode 100644 index 0000000..72f1658 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-declared-source-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":6,"declared_semantics_count":9,"source_node_count":0,"sink_node_count":1,"source_nodes":[],"sink_nodes":[{"label":"CALL","file":"ModelDeclaredSourceNegative.java","line":17,"method":"dataflowbench.taint.ModelDeclaredSourceNegative.run:void()","code":"Config.fetchLocal()"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-positive.json new file mode 100644 index 0000000..5449bc3 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-declared-source-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-declared-source-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":6,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelDeclaredSourcePositive.java","line":17,"method":"dataflowbench.taint.ModelDeclaredSourcePositive.run:void()","code":"Config.fetchRemote()"}],"sink_nodes":[{"label":"CALL","file":"ModelDeclaredSourcePositive.java","line":17,"method":"dataflowbench.taint.ModelDeclaredSourcePositive.run:void()","code":"Config.fetchRemote()"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelDeclaredSourcePositive.java","line":17,"method":"dataflowbench.taint.ModelDeclaredSourcePositive.run:void()","code":"Config.fetchRemote()"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json new file mode 100644 index 0000000..7d9afc3 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-entrypoint-parameter-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":4,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":2,"source_nodes":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"String input"}],"sink_nodes":[{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"input"},{"label":"IDENTIFIER","file":"Handler.java","line":11,"method":"dataflowbench.taint.Handler.onIgnored:void(java.lang.String)","code":"input"}],"flow_count":1,"flows":[{"elements":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"String input"},{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"input"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json new file mode 100644 index 0000000..9a00623 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-entrypoint-parameter-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":4,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":2,"source_nodes":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"String input"}],"sink_nodes":[{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"input"},{"label":"IDENTIFIER","file":"Handler.java","line":11,"method":"dataflowbench.taint.Handler.onIgnored:void(java.lang.String)","code":"input"}],"flow_count":1,"flows":[{"elements":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"String input"},{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onRequest:void(java.lang.String)","code":"input"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json new file mode 100644 index 0000000..7963063 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-entrypoint-selectivity-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":4,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":2,"source_nodes":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"String input"}],"sink_nodes":[{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"input"},{"label":"IDENTIFIER","file":"Handler.java","line":11,"method":"dataflowbench.taint.Handler.onUndeclared:void(java.lang.String)","code":"input"}],"flow_count":1,"flows":[{"elements":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"String input"},{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"input"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json new file mode 100644 index 0000000..4c578ae --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-entrypoint-selectivity-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":4,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":2,"source_nodes":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"String input"}],"sink_nodes":[{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"input"},{"label":"IDENTIFIER","file":"Handler.java","line":11,"method":"dataflowbench.taint.Handler.onUndeclared:void(java.lang.String)","code":"input"}],"flow_count":1,"flows":[{"elements":[{"label":"METHOD_PARAMETER_IN","file":"Handler.java","line":6,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"String input"},{"label":"IDENTIFIER","file":"Handler.java","line":7,"method":"dataflowbench.taint.Handler.onDeclared:void(java.lang.String)","code":"input"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-negative.json new file mode 100644 index 0000000..5474fea --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-opaque-propagator-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":14,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelOpaquePropagatorNegative.java","line":37,"method":"dataflowbench.taint.ModelOpaquePropagatorNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelOpaquePropagatorNegative.java","line":37,"method":"dataflowbench.taint.ModelOpaquePropagatorNegative.run:void()","code":"Opaque.block(dfb_source())"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-positive.json new file mode 100644 index 0000000..5bd3434 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-opaque-propagator-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-opaque-propagator-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":14,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelOpaquePropagatorPositive.java","line":37,"method":"dataflowbench.taint.ModelOpaquePropagatorPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelOpaquePropagatorPositive.java","line":37,"method":"dataflowbench.taint.ModelOpaquePropagatorPositive.run:void()","code":"Opaque.carry(dfb_source())"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelOpaquePropagatorPositive.java","line":37,"method":"dataflowbench.taint.ModelOpaquePropagatorPositive.run:void()","code":"dfb_source()"},{"label":"CALL","file":"ModelOpaquePropagatorPositive.java","line":37,"method":"dataflowbench.taint.ModelOpaquePropagatorPositive.run:void()","code":"Opaque.carry(dfb_source())"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-negative.json new file mode 100644 index 0000000..8a135ff --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-propagator-position-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":13,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelPropagatorPositionNegative.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelPropagatorPositionNegative.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionNegative.run:void()","code":"Opaque.select(dfb_source(), \"clean\")"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelPropagatorPositionNegative.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionNegative.run:void()","code":"dfb_source()"},{"label":"CALL","file":"ModelPropagatorPositionNegative.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionNegative.run:void()","code":"Opaque.select(dfb_source(), \"clean\")"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-positive.json new file mode 100644 index 0000000..d773f37 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-propagator-position-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-propagator-position-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":13,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelPropagatorPositionPositive.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelPropagatorPositionPositive.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionPositive.run:void()","code":"Opaque.select(\"clean\", dfb_source())"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelPropagatorPositionPositive.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionPositive.run:void()","code":"dfb_source()"},{"label":"CALL","file":"ModelPropagatorPositionPositive.java","line":27,"method":"dataflowbench.taint.ModelPropagatorPositionPositive.run:void()","code":"Opaque.select(\"clean\", dfb_source())"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json new file mode 100644 index 0000000..273e0b6 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-sanitizer-kill-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":6,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSanitizerKillNegative.java","line":17,"method":"dataflowbench.taint.ModelSanitizerKillNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSanitizerKillNegative.java","line":17,"method":"dataflowbench.taint.ModelSanitizerKillNegative.run:void()","code":"Clean.scrub(dfb_source())"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json new file mode 100644 index 0000000..29a9817 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-sanitizer-kill-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":6,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSanitizerKillPositive.java","line":17,"method":"dataflowbench.taint.ModelSanitizerKillPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSanitizerKillPositive.java","line":17,"method":"dataflowbench.taint.ModelSanitizerKillPositive.run:void()","code":"dfb_source()"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelSanitizerKillPositive.java","line":17,"method":"dataflowbench.taint.ModelSanitizerKillPositive.run:void()","code":"dfb_source()"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json new file mode 100644 index 0000000..aed65f3 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-sanitizer-selectivity-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":7,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSanitizerSelectivityNegative.java","line":21,"method":"dataflowbench.taint.ModelSanitizerSelectivityNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSanitizerSelectivityNegative.java","line":21,"method":"dataflowbench.taint.ModelSanitizerSelectivityNegative.run:void()","code":"Clean.scrub(dfb_source())"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json new file mode 100644 index 0000000..d53a556 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-sanitizer-selectivity-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":7,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSanitizerSelectivityPositive.java","line":21,"method":"dataflowbench.taint.ModelSanitizerSelectivityPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSanitizerSelectivityPositive.java","line":21,"method":"dataflowbench.taint.ModelSanitizerSelectivityPositive.run:void()","code":"Clean.sanitize(dfb_source())"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelSanitizerSelectivityPositive.java","line":21,"method":"dataflowbench.taint.ModelSanitizerSelectivityPositive.run:void()","code":"dfb_source()"},{"label":"METHOD_PARAMETER_IN","file":"ModelSanitizerSelectivityPositive.java","line":8,"method":"dataflowbench.taint.Clean.sanitize:java.lang.String(java.lang.String)","code":"String value"},{"label":"IDENTIFIER","file":"ModelSanitizerSelectivityPositive.java","line":9,"method":"dataflowbench.taint.Clean.sanitize:java.lang.String(java.lang.String)","code":"value"},{"label":"RETURN","file":"ModelSanitizerSelectivityPositive.java","line":9,"method":"dataflowbench.taint.Clean.sanitize:java.lang.String(java.lang.String)","code":"return value;"},{"label":"METHOD_RETURN","file":"ModelSanitizerSelectivityPositive.java","line":8,"method":"dataflowbench.taint.Clean.sanitize:java.lang.String(java.lang.String)","code":"RET"},{"label":"CALL","file":"ModelSanitizerSelectivityPositive.java","line":21,"method":"dataflowbench.taint.ModelSanitizerSelectivityPositive.run:void()","code":"Clean.sanitize(dfb_source())"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-negative.json new file mode 100644 index 0000000..6e9e2c2 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-store-roundtrip-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":8,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelStoreRoundtripNegative.java","line":19,"method":"dataflowbench.taint.ModelStoreRoundtripNegative.writeSide:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelStoreRoundtripNegative.java","line":23,"method":"dataflowbench.taint.ModelStoreRoundtripNegative.readSide:void()","code":"Store.get(\"b\")"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-positive.json new file mode 100644 index 0000000..8a9aaeb --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-roundtrip-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-store-roundtrip-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":8,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelStoreRoundtripPositive.java","line":19,"method":"dataflowbench.taint.ModelStoreRoundtripPositive.writeSide:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelStoreRoundtripPositive.java","line":23,"method":"dataflowbench.taint.ModelStoreRoundtripPositive.readSide:void()","code":"Store.get(\"k\")"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-negative.json new file mode 100644 index 0000000..8eb5814 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-store-separation-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":12,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelStoreSeparationNegative.java","line":23,"method":"dataflowbench.taint.ModelStoreSeparationNegative.writeSide:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelStoreSeparationNegative.java","line":27,"method":"dataflowbench.taint.ModelStoreSeparationNegative.readSide:void()","code":"ModelStoreSeparationNegative.beta.get(\"k\")"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-positive.json new file mode 100644 index 0000000..e4e6a2f --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-store-separation-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-store-separation-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":12,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelStoreSeparationPositive.java","line":23,"method":"dataflowbench.taint.ModelStoreSeparationPositive.writeSide:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelStoreSeparationPositive.java","line":27,"method":"dataflowbench.taint.ModelStoreSeparationPositive.readSide:void()","code":"ModelStoreSeparationPositive.alpha.get(\"k\")"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-negative.json new file mode 100644 index 0000000..178897c --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-summary-field-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":10,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSummaryFieldNegative.java","line":21,"method":"dataflowbench.taint.ModelSummaryFieldNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSummaryFieldNegative.java","line":22,"method":"dataflowbench.taint.ModelSummaryFieldNegative.run:void()","code":"box.spare"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelSummaryFieldNegative.java","line":21,"method":"dataflowbench.taint.ModelSummaryFieldNegative.run:void()","code":"dfb_source()"},{"label":"IDENTIFIER","file":"ModelSummaryFieldNegative.java","line":21,"method":"dataflowbench.taint.ModelSummaryFieldNegative.run:void()","code":"box"},{"label":"CALL","file":"ModelSummaryFieldNegative.java","line":22,"method":"dataflowbench.taint.ModelSummaryFieldNegative.run:void()","code":"box.spare"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-positive.json new file mode 100644 index 0000000..791b5ef --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-field-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-summary-field-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":10,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSummaryFieldPositive.java","line":21,"method":"dataflowbench.taint.ModelSummaryFieldPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSummaryFieldPositive.java","line":22,"method":"dataflowbench.taint.ModelSummaryFieldPositive.run:void()","code":"box.payload"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelSummaryFieldPositive.java","line":21,"method":"dataflowbench.taint.ModelSummaryFieldPositive.run:void()","code":"dfb_source()"},{"label":"IDENTIFIER","file":"ModelSummaryFieldPositive.java","line":21,"method":"dataflowbench.taint.ModelSummaryFieldPositive.run:void()","code":"box"},{"label":"CALL","file":"ModelSummaryFieldPositive.java","line":22,"method":"dataflowbench.taint.ModelSummaryFieldPositive.run:void()","code":"box.payload"}]}]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-negative.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-negative.json new file mode 100644 index 0000000..13ba48a --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-negative.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-summary-through-negative/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":7,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSummaryThroughNegative.java","line":11,"method":"dataflowbench.taint.ModelSummaryThroughNegative.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSummaryThroughNegative.java","line":11,"method":"dataflowbench.taint.ModelSummaryThroughNegative.run:void()","code":"Bridge.hold(dfb_source())"}],"flow_count":0,"flows":[]} diff --git a/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-positive.json b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-positive.json new file mode 100644 index 0000000..cb87868 --- /dev/null +++ b/reports/raw/joern-java-modeling/dfb-taint-java-model-summary-through-positive.json @@ -0,0 +1 @@ +{"adapter":"joern","evidence_kind":"joern-reachable-by-flows","input_path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-joern/dfb-taint-java-model-summary-through-positive/source","frontend_language":"JAVASRC","semantics_path":"/Users/dave/Workspace/BrokkAi/dataflowbench/.claude/worktrees/agent-af332237afc5e1bcf/adapters/joern/semantics/model-java.semantics","source_function":"dfb_source|fetchRemote","sink_function":"dfb_sink|record","state":"analyzed","method_count":7,"declared_semantics_count":9,"source_node_count":1,"sink_node_count":1,"source_nodes":[{"label":"CALL","file":"ModelSummaryThroughPositive.java","line":11,"method":"dataflowbench.taint.ModelSummaryThroughPositive.run:void()","code":"dfb_source()"}],"sink_nodes":[{"label":"CALL","file":"ModelSummaryThroughPositive.java","line":11,"method":"dataflowbench.taint.ModelSummaryThroughPositive.run:void()","code":"Bridge.pass(dfb_source())"}],"flow_count":1,"flows":[{"elements":[{"label":"CALL","file":"ModelSummaryThroughPositive.java","line":11,"method":"dataflowbench.taint.ModelSummaryThroughPositive.run:void()","code":"dfb_source()"},{"label":"CALL","file":"ModelSummaryThroughPositive.java","line":11,"method":"dataflowbench.taint.ModelSummaryThroughPositive.run:void()","code":"Bridge.pass(dfb_source())"}]}]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-negative.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-negative.json new file mode 100644 index 0000000..c73f05d --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-negative.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-declared-sink-negative/source/ModelDeclaredSinkNegative.java"]},"time":{"rules":[],"rules_parse_time":0.0004630088806152344,"profiling_times":{"config_time":0.2720451354980469,"core_time":0.4353749752044678,"ignores_time":9.799003601074219e-05,"total_time":0.7164452075958252},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.017676115036010742,"per_file_time":{"mean":0.017676115036010742,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92060352},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-positive.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-positive.json new file mode 100644 index 0000000..c1f43fe --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-positive.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-declared-sink-positive/source/ModelDeclaredSinkPositive.java","start":{"line":15,"col":9,"offset":350},"end":{"line":15,"col":35,"offset":376},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-declared-sink-positive/source/ModelDeclaredSinkPositive.java"]},"time":{"rules":[],"rules_parse_time":0.00048613548278808594,"profiling_times":{"config_time":0.24777698516845703,"core_time":0.7031681537628174,"ignores_time":0.00010991096496582031,"total_time":0.9610931873321533},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.013252973556518555,"per_file_time":{"mean":0.013252973556518555,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92584640},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-negative.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-negative.json new file mode 100644 index 0000000..fde86be --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-negative.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-declared-source-negative/source/ModelDeclaredSourceNegative.java"]},"time":{"rules":[],"rules_parse_time":0.0006690025329589844,"profiling_times":{"config_time":0.21710419654846191,"core_time":0.41209983825683594,"ignores_time":8.511543273925781e-05,"total_time":0.63797926902771},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.011426210403442383,"per_file_time":{"mean":0.011426210403442383,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92322496},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-positive.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-positive.json new file mode 100644 index 0000000..9332754 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-positive.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-declared-source-positive/source/ModelDeclaredSourcePositive.java","start":{"line":17,"col":9,"offset":377},"end":{"line":17,"col":39,"offset":407},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-declared-source-positive/source/ModelDeclaredSourcePositive.java"]},"time":{"rules":[],"rules_parse_time":0.0004661083221435547,"profiling_times":{"config_time":0.17896604537963867,"core_time":0.3390007019042969,"ignores_time":4.792213439941406e-05,"total_time":0.5259761810302734},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.012178182601928711,"per_file_time":{"mean":0.012178182601928711,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92584640},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json new file mode 100644 index 0000000..a38f8d0 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-parameter-negative/source/Handler.java","start":{"line":7,"col":9,"offset":185},"end":{"line":7,"col":24,"offset":200},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-parameter-negative/source/Handler.java"]},"time":{"rules":[],"rules_parse_time":0.0004470348358154297,"profiling_times":{"config_time":0.2449052333831787,"core_time":0.4414808750152588,"ignores_time":7.510185241699219e-05,"total_time":0.6954281330108643},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.008599996566772461,"per_file_time":{"mean":0.008599996566772461,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":90832192},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json new file mode 100644 index 0000000..ca9ccd9 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-parameter-positive/source/Handler.java","start":{"line":7,"col":9,"offset":234},"end":{"line":7,"col":24,"offset":249},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-parameter-positive/source/Handler.java"]},"time":{"rules":[],"rules_parse_time":0.00041294097900390625,"profiling_times":{"config_time":0.29282712936401367,"core_time":0.3767573833465576,"ignores_time":5.412101745605469e-05,"total_time":0.678196907043457},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.007975101470947266,"per_file_time":{"mean":0.007975101470947266,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":93191488},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json new file mode 100644 index 0000000..f3ffeb8 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-selectivity-negative/source/Handler.java","start":{"line":7,"col":9,"offset":188},"end":{"line":7,"col":24,"offset":203},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-selectivity-negative/source/Handler.java"]},"time":{"rules":[],"rules_parse_time":0.0005080699920654297,"profiling_times":{"config_time":0.1679370403289795,"core_time":0.4052290916442871,"ignores_time":7.224082946777344e-05,"total_time":0.5841422080993652},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.009079217910766602,"per_file_time":{"mean":0.009079217910766602,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":91356480},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json new file mode 100644 index 0000000..c31d20b --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-selectivity-positive/source/Handler.java","start":{"line":7,"col":9,"offset":239},"end":{"line":7,"col":24,"offset":254},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-entrypoint-selectivity-positive/source/Handler.java"]},"time":{"rules":[],"rules_parse_time":0.00046896934509277344,"profiling_times":{"config_time":0.21598100662231445,"core_time":0.4657728672027588,"ignores_time":8.487701416015625e-05,"total_time":0.6897749900817871},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.008553981781005859,"per_file_time":{"mean":0.008553981781005859,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":91356480},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json new file mode 100644 index 0000000..13eea35 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-opaque-propagator-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-opaque-propagator" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json new file mode 100644 index 0000000..5ddd167 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-opaque-propagator-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-opaque-propagator" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json new file mode 100644 index 0000000..97562a8 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-propagator-position-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-propagator-position" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json new file mode 100644 index 0000000..83dc49f --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-propagator-position-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "P", + "modeling_category_label": "declared propagators", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-propagator-position" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json new file mode 100644 index 0000000..e3eab42 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-sanitizer-kill-negative/source/ModelSanitizerKillNegative.java"]},"time":{"rules":[],"rules_parse_time":0.0007860660552978516,"profiling_times":{"config_time":0.21359682083129883,"core_time":0.5097429752349854,"ignores_time":7.700920104980469e-05,"total_time":0.7329020500183105},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.008786916732788086,"per_file_time":{"mean":0.008786916732788086,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":93371072},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json new file mode 100644 index 0000000..9ab7807 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[{"check_id":"Users.dave.Workspace.BrokkAi.dataflowbench..claude.worktrees.agent-af332237afc5e1bcf.adapters.semgrep.rules.dfb-model-java","path":"/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-sanitizer-kill-positive/source/ModelSanitizerKillPositive.java","start":{"line":17,"col":9,"offset":381},"end":{"line":17,"col":31,"offset":403},"extra":{"message":"a benchmark-declared model carried input to the declared sink","metadata":{},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-sanitizer-kill-positive/source/ModelSanitizerKillPositive.java"]},"time":{"rules":[],"rules_parse_time":0.0004928112030029297,"profiling_times":{"config_time":0.1905357837677002,"core_time":0.4105219841003418,"ignores_time":8.416175842285156e-05,"total_time":0.6107509136199951},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.01027679443359375,"per_file_time":{"mean":0.01027679443359375,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92322496},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json new file mode 100644 index 0000000..8ca7b20 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-sanitizer-selectivity-negative/source/ModelSanitizerSelectivityNegative.java"]},"time":{"rules":[],"rules_parse_time":0.0005290508270263672,"profiling_times":{"config_time":0.23120522499084473,"core_time":0.6883370876312256,"ignores_time":7.319450378417969e-05,"total_time":0.9267151355743408},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.014635801315307617,"per_file_time":{"mean":0.014635801315307617,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92355264},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json new file mode 100644 index 0000000..a8aa717 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json @@ -0,0 +1 @@ +{"version":"1.174.0","results":[],"errors":[],"paths":{"scanned":["/var/folders/t1/k_27wjcd4095w9w121dm92_w0000gn/T/dataflowbench-modeling-semgrep/dfb-taint-java-model-sanitizer-selectivity-positive/source/ModelSanitizerSelectivityPositive.java"]},"time":{"rules":[],"rules_parse_time":0.000514984130859375,"profiling_times":{"config_time":0.2223529815673828,"core_time":0.42598700523376465,"ignores_time":7.414817810058594e-05,"total_time":0.6579949855804443},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.010510921478271484,"per_file_time":{"mean":0.010510921478271484,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":1.0,"rules_matched_ratio":1.0},"targets":[],"total_bytes":0,"max_memory_bytes":92355264},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json new file mode 100644 index 0000000..3f33a2e --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-store-roundtrip-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-roundtrip" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json new file mode 100644 index 0000000..ceba22e --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-store-roundtrip-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-roundtrip" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json new file mode 100644 index 0000000..1f80456 --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-store-separation-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-separation" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json new file mode 100644 index 0000000..7338c9f --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-store-separation-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "B", + "modeling_category_label": "persistence boundaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-store-separation" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json new file mode 100644 index 0000000..d7b6a9c --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-summary-field-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-field" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json new file mode 100644 index 0000000..dc6e01c --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-summary-field-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-field" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json new file mode 100644 index 0000000..798cffe --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-summary-through-negative", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-through" +} diff --git a/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json new file mode 100644 index 0000000..84b827e --- /dev/null +++ b/reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json @@ -0,0 +1,13 @@ +{ + "adapter": "semgrep", + "case_id": "dfb-taint-java-model-summary-through-positive", + "evidence_kind": "retained-capability-decision", + "modeling_category": "O", + "modeling_category_label": "opaque procedure summaries", + "partition_source": "docs/modeling-matrix.md#per-tool-capability-partition", + "pinned_tool_identity": "Semgrep CE 1.174.0", + "reason": "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary", + "stage": "preregistered-modeling-partition", + "state": "unsupported", + "template_id": "dfb-template-model-summary-through" +} diff --git a/reports/semgrep-java-modeling.json b/reports/semgrep-java-modeling.json new file mode 100644 index 0000000..2dd6980 --- /dev/null +++ b/reports/semgrep-java-modeling.json @@ -0,0 +1,402 @@ +{ + "adapter_version": "0.1.0", + "cold_or_warm": "cold", + "configuration_hash": "d25d4a4058ae7bd67131d38d05d0579a642ad1841071f965719dd8cea7efd59e", + "ended_at_unix_seconds": 1787748825, + "fixture_revision": "sha256:727c6838741d80705ac5f6ed0754862400ad7504bfc68ac7df32b6bfb73553c6", + "results": [ + { + "case_id": "dfb-taint-java-model-declared-sink-negative", + "diagnostics": [], + "duration_ms": 3786, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-negative.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-sink-positive", + "diagnostics": [], + "duration_ms": 4030, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-sink-positive.json", + "sink_anchors": [ + "DFB-SINK: model-declared-sink-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-sink-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-negative", + "diagnostics": [], + "duration_ms": 2994, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-negative.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-declared-source-positive", + "diagnostics": [], + "duration_ms": 2317, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-declared-source-positive.json", + "sink_anchors": [ + "DFB-SINK: model-declared-source-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-declared-source-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-negative", + "diagnostics": [ + "1 finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's" + ], + "duration_ms": 2723, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-negative.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-parameter-positive", + "diagnostics": [], + "duration_ms": 2797, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-parameter-positive.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-parameter-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-parameter-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-negative", + "diagnostics": [ + "1 finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's" + ], + "duration_ms": 2739, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-negative.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-entrypoint-selectivity-positive", + "diagnostics": [], + "duration_ms": 2891, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-entrypoint-selectivity-positive.json", + "sink_anchors": [ + "DFB-SINK: model-entrypoint-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-entrypoint-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-negative", + "diagnostics": [ + "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-opaque-propagator-positive", + "diagnostics": [ + "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-opaque-propagator-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-opaque-propagator-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-opaque-propagator-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-negative", + "diagnostics": [ + "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-propagator-position-positive", + "diagnostics": [ + "category P — declared propagators — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): verified twice over. First, `pattern-propagators` binds `to:` to a **metavariable**, not to a call's return value: a propagator written `pattern: prop($A,$B) / from: $B / to: prop(...)` produced no finding when the default pass-through was disabled. Second, with the default enabled, CE reports the sink whether taint sits at the declared position 1 or the undeclared position 0 — so both cells of template 4 are decided by the default, not the model, and the load-bearing-model requirement is violated either way. Arg→return propagation is outside CE's propagator vocabulary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-propagator-position-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-propagator-position-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-propagator-position-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-negative", + "diagnostics": [], + "duration_ms": 3152, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-negative.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-kill-positive", + "diagnostics": [], + "duration_ms": 2485, + "outcome": "reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-kill-positive.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-kill-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-kill-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-negative", + "diagnostics": [], + "duration_ms": 2855, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-negative.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-sanitizer-selectivity-positive", + "diagnostics": [], + "duration_ms": 2585, + "outcome": "not-reached", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-sanitizer-selectivity-positive.json", + "sink_anchors": [ + "DFB-SINK: model-sanitizer-selectivity-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-sanitizer-selectivity-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-negative", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-roundtrip-positive", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-roundtrip-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-roundtrip-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-roundtrip-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-negative", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-store-separation-positive", + "diagnostics": [ + "category B — persistence boundaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): the write and the read are in two different procedures by construction, and the pinned CE engine has no interprocedural taint at all: `semgrep scan --help` offers `--pro-intrafile` (\"Intra-file inter-procedural taint analysis … Requires Semgrep Pro Engine\"), so the step from `put` to `get` is outside the engine regardless of what is declared" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-store-separation-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-store-separation-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-store-separation-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-negative", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-field-positive", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-field-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-field-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-field-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-negative", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-negative-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + }, + { + "case_id": "dfb-taint-java-model-summary-through-positive", + "diagnostics": [ + "category O — opaque procedure summaries — is unsupported for Semgrep CE 1.174.0 by the preregistered modeling partition (docs/modeling-matrix.md#per-tool-capability-partition): template 7 needs arg→return summary semantics, which P has already established CE cannot express, and puts the summarized procedure in a separate file, which CE's intra-file engine does not cross. Template 8's destination is a *field* of an argument; `to: $L` reaches the whole object, and the pinned CE documents only \"Experimental support for basic field-sensitive taint tracking\" — so the field-separation negative would be decided by CE's heap approximation rather than by the summary" + ], + "duration_ms": 0, + "outcome": "unsupported", + "peak_memory_mb": null, + "raw_output": "reports/raw/semgrep-java-modeling/dfb-taint-java-model-summary-through-positive-unsupported.json", + "sink_anchors": [ + "DFB-SINK: model-summary-through-sink" + ], + "source_anchors": [ + "DFB-SOURCE: model-summary-through-input" + ], + "witness_checkpoints": [] + } + ], + "schema_version": 1, + "started_at_unix_seconds": 1787748786, + "tool": "semgrep", + "tool_build_identity": "semgrep-oss:1.174.0", + "tool_version": "1.174.0" +} diff --git a/src/main.rs b/src/main.rs index e9c17ae..517a76d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -104,6 +104,12 @@ const BIFROST_EXPLICIT_NEGATIVE_POLICY: &str = "adapters/bifrost/policies/explic /// evaluated with. As with Kotlin and Scala, the frozen direct-propagation pair /// names its own historical policies, so the run pins this one for the whole /// population and every assertion shares one configuration hash. +/// The UTC date every Bifrost run evaluates suppression expiry against. It is +/// pinned rather than taken from the clock so two runs of the same commit +/// evaluate the same policy, and it is named here so the kernel and modeling +/// runners cannot drift onto different dates. +const BIFROST_EVALUATION_DATE: &str = "2026-08-11"; + const BIFROST_JAVA_POLICY: &str = "adapters/bifrost/policies/core-java-kernel.rqlp"; /// The language-qualified Bifrost policy every JavaScript kernel assertion is /// evaluated with. Its frozen direct-propagation pair names the cross-language @@ -857,7 +863,14 @@ impl ModelingLanguage { "adapters/bifrost/policies/model-javascript.rqlp" } (ModelingTool::Bifrost, Self::Python) => "adapters/bifrost/policies/model-python.rqlp", - (ModelingTool::Codeql, Self::Java) => "adapters/codeql/java/queries/JavaModeling.ql", + // Java is the one language whose CodeQL pack *is* the adapter root: + // `adapters/codeql/qlpack.yml` declares `dataflowbench/codeql-java` + // and `adapters/codeql/queries/JavaKernel.ql` already lives beside + // it. The convention is "inside that language's existing qlpack", + // and for Java that pack has no `java/` subdirectory to descend + // into — a query under one would resolve no `codeql/java-all` + // dependency at all. + (ModelingTool::Codeql, Self::Java) => "adapters/codeql/queries/JavaModeling.ql", (ModelingTool::Codeql, Self::Javascript) => { "adapters/codeql/javascript/queries/JavaScriptModeling.ql" } @@ -3659,7 +3672,7 @@ fn run_bifrost(binary: &Path, run: BifrostRun) -> Result<()> { .arg("policy.rqlp") .args([ "--evaluation-date", - "2026-08-11", + BIFROST_EVALUATION_DATE, "--format", "json", "--fail-on", @@ -7705,8 +7718,18 @@ fn run_semgrep_kernel(binary: &Path, kernel: SemgrepKernel) -> Result<()> { Ok(()) } -/// Every committed Semgrep rule file, so one `configuration_hash` binds the -/// whole rule set rather than only the language that happened to run. +/// Every committed Semgrep **kernel** rule file, so one `configuration_hash` +/// binds the whole kernel rule set rather than only the language that happened +/// to run. +/// +/// The `model-.yaml` modeling artifacts share this directory and are +/// deliberately excluded. They are not kernel configuration: a modeling rule is +/// the benchmark-controlled modeling matrix's declaration set, hash-bound on its +/// own into that population's report. Folding them in here would make every +/// retained kernel report's configuration hash move each time a language's +/// modeling wave lands — a change that describes nothing about the kernel the +/// report is evidence for, and one that would silently strand the v0.4.0 +/// freeze's reproduction instructions. fn semgrep_rule_paths() -> Result> { let mut paths = BTreeSet::new(); for entry in fs::read_dir(SEMGREP_RULES_DIR) @@ -7714,7 +7737,14 @@ fn semgrep_rule_paths() -> Result> { .filter_map(std::result::Result::ok) { let path = entry.path(); - if path.is_file() && path.extension().is_some_and(|ext| ext == "yaml") { + let is_modeling_artifact = path + .file_name() + .and_then(|name| name.to_str()) + .is_some_and(|name| name.starts_with("model-")); + if path.is_file() + && path.extension().is_some_and(|ext| ext == "yaml") + && !is_modeling_artifact + { paths.insert(path); } } @@ -8490,178 +8520,1145 @@ fn modeling_partition_outcome( Ok(Some(("unsupported", reason, raw_path))) } -/// Run one adapter's modeling matrix for one language. +/// The anchor dialect a modeling language's fixtures are written in. Wave M1's +/// three languages reuse the dialects the kernels already reconcile against; +/// no modeling-only dialect exists, and none should. +fn modeling_dialect(language: ModelingLanguage) -> AnchorDialect { + match language { + ModelingLanguage::Java => AnchorDialect::Java, + ModelingLanguage::Javascript => AnchorDialect::Ecma, + ModelingLanguage::Python => AnchorDialect::Python, + } +} + +/// The `importCode` frontend identifier the Joern modeling script is invoked +/// with, per language. +fn modeling_joern_frontend(language: ModelingLanguage) -> &'static str { + match language { + ModelingLanguage::Java => "JAVASRC", + ModelingLanguage::Javascript => "JSSRC", + ModelingLanguage::Python => "PYTHONSRC", + } +} + +/// The region of a fixture that one case's own source anchor governs: the +/// anchored declaration, its body, and every callsite of the anchored source +/// function. /// -/// The staged shape of this command is deliberate and is recorded in -/// docs/adapters.md: the population gate, the artifact gate, the load-bearing -/// gate, and the partition's `unsupported` arm are infrastructure and land -/// here; the arm that actually invokes the analyzer over a scored cell lands -/// with the language pull request that authors that adapter's declarations, -/// because there is nothing to invoke it against until then. A scored cell -/// with no execution arm is a hard error — this adapter will not synthesize a -/// tool result, and `docs/adapters.md` forbids it. -fn run_modeling( - tool: ModelingTool, - binary: &Path, - language: ModelingLanguage, - codeql_packs: Option<&Path>, -) -> Result<()> { - if let Some(packs) = codeql_packs - && !packs.is_dir() - { - bail!("CodeQL pack search path {} does not exist", packs.display()); +/// **Why the modeling tier reconciles the source side at all.** A kernel +/// fixture carries exactly one flow, so a finding on the case's sink anchor is +/// unambiguously *the* assertion. A modeling fixture carries both halves of its +/// pair by construction — the declared entity and its undeclared sibling live in +/// one type, because that is what the templates say makes the negative a +/// negative. Category E makes the consequence unavoidable: a handler needs no +/// caller, so the *declared* handler's flow is present in the negative fixture +/// too, on a callsite of the same sink function. Reconciling only the sink would +/// read that sibling's flow as this case's finding. Reconciling the source as +/// well is what keeps the two assertions apart, and it is the same reconciliation +/// for every tool, so no adapter can drift into a laxer one. +/// +/// **Why the region and not only the marker line.** Three adapters report three +/// different things: CodeQL's SARIF carries the flow's source location, Joern's +/// evidence carries the flow's first element, and the pinned Semgrep CE emits no +/// dataflow trace at all in its OSS output — only the finding's own position. So +/// the region is defined as the *lines the anchored declaration governs*, which +/// all three can be tested against: the declaration line itself (where a +/// parameter source lives), the declaration's body (where an intraprocedural +/// engine's finding lives), and the source function's callsites (where a call +/// source lives). +struct ModelingSourceRegion { + file: String, + lines: BTreeSet, +} + +impl ModelingSourceRegion { + fn contains(&self, file: &str, line: u64) -> bool { + evidence_path_matches_file(file, &self.file) && self.lines.contains(&line) } - let plan = plan_modeling_run(tool, language)?; +} - let scored = modeling_supported_templates(plan.tool); - let scored_cases: Vec<&str> = plan - .cases - .iter() - .filter_map(|(_, case)| case["template_id"].as_str()) - .filter(|template| scored.contains(template)) - .collect(); - if !scored_cases.is_empty() { - bail!( - "{} has {} scored {} modeling assertion(s) ({scored_cases:?}) but this adapter's modeling execution arm is not wired yet; it lands with the language pull request that authors {} (docs/modeling-matrix.md#rollout-plan). Refusing to write a report rather than synthesizing an outcome", - plan.tool.pinned_identity(), - scored_cases.len(), - plan.language.display_name(), - plan.language.artifact(plan.tool) - ); +/// The block a declaration governs, decided by indentation rather than by a +/// dialect's block punctuation. +/// +/// A declaration's body is exactly the run of lines that are blank or indented +/// deeper than the declaration, up to the first line that is not. That is true +/// of a braced body (the closing brace sits back at the declaration's own +/// indentation and terminates the run) and of an indented one, so one rule +/// serves every wave-M1 language without a per-dialect brace matcher whose only +/// caller would be this function. +fn declaration_block_lines(body: &str, declaration_line: u64) -> BTreeSet { + let lines: Vec<&str> = body.lines().collect(); + let mut block = BTreeSet::from([declaration_line]); + let index = declaration_line as usize - 1; + let Some(declaration) = lines.get(index) else { + return block; + }; + let declaration_indent = leading_whitespace(declaration); + for (offset, line) in lines.iter().enumerate().skip(index + 1) { + if line.trim().is_empty() { + continue; + } + if leading_whitespace(line) <= declaration_indent { + break; + } + block.insert(offset as u64 + 1); } + block +} - // Reached only by a tool that declines every category this population - // carries: a complete report of retained capability decisions, with the - // analyzer never invoked. - fs::create_dir_all(&plan.raw_dir)?; - let started = now_seconds()?; - let (version, build_identity) = modeling_version_identity(plan.tool, binary)?; - let revision = fixture_revision()?; - let mut results = Vec::with_capacity(plan.cases.len()); - for (_, case) in &plan.cases { - let id = required_string(case, "id", "modeling case")?; - let start = Instant::now(); - let (outcome, reason, raw_path) = - modeling_partition_outcome(plan.tool, case, &plan.raw_dir)? - .expect("every remaining cell is an unsupported one"); - results.push(normalized_result( - case, - id, - outcome, - vec![reason], - start.elapsed(), - &raw_path, +fn leading_whitespace(line: &str) -> usize { + line.len() - line.trim_start().len() +} + +/// Resolve one modeling case's source region. A case with more than one source +/// anchor has no single region, which no modeling template declares and the +/// matrix's own balance check would not admit. +fn modeling_source_region( + case_path: &Path, + case: &Value, + dialect: AnchorDialect, +) -> std::result::Result { + let fixture_root = case_path + .parent() + .ok_or_else(|| "case path has no parent".to_string())?; + let anchors = case["source_anchors"] + .as_array() + .ok_or_else(|| "case has no source anchors".to_string())?; + let [anchor] = anchors.as_slice() else { + return Err(format!( + "a modeling case declares exactly one source anchor; found {}", + anchors.len() )); - } - let report = json!({ - "schema_version": 1, - "tool": plan.tool.key(), - "tool_version": version, - "tool_build_identity": build_identity, - "adapter_version": ADAPTER_VERSION, - "configuration_hash": hash_paths(&plan.configuration_paths)?, - "fixture_revision": revision, - "started_at_unix_seconds": started, - "ended_at_unix_seconds": now_seconds()?, - "cold_or_warm": "cold", - "results": results - }); - write_and_validate_report(&plan.report, &report)?; - println!("wrote {}", plan.report.display()); - Ok(()) + }; + let file = anchor["file"] + .as_str() + .ok_or_else(|| "source anchor lacks file".to_string())?; + let marker = anchor["marker"] + .as_str() + .ok_or_else(|| "source anchor lacks marker".to_string())?; + let body = fs::read_to_string(fixture_root.join(file)) + .map_err(|error| format!("read source fixture {file}: {error}"))?; + let declaration_line = anchor_marker_line(&body, marker, anchor["line_hint"].as_u64())?; + let declaration = body + .lines() + .nth(declaration_line as usize - 1) + .ok_or_else(|| format!("source anchor line {declaration_line} is outside {file}"))?; + let function_name = dialect + .declared_function_name(declaration, marker) + .ok_or_else(|| format!("source marker {marker:?} is not on a function declaration"))?; + let mut lines = declaration_block_lines(&body, declaration_line); + lines.extend(modeling_callsite_lines( + &body, + &function_name, + declaration_line, + dialect, + )); + Ok(ModelingSourceRegion { + file: file.to_string(), + lines, + }) } -/// The pinned version identity a modeling report records, read from the same -/// surface each adapter's kernel reports already read it from. -fn modeling_version_identity(tool: ModelingTool, binary: &Path) -> Result<(String, String)> { - match tool { - ModelingTool::Bifrost => Ok(( - command_output(Command::new(binary).arg("--version")) - .unwrap_or_else(|_| "unknown".into()), - command_output(Command::new(binary).arg("--build-identity")) - .unwrap_or_else(|_| "unknown".into()), - )), - ModelingTool::Codeql => codeql_version_identity(binary), - ModelingTool::Joern => joern_version_identity(binary), - ModelingTool::Semgrep => semgrep_version_identity(binary), +/// The lines that call one declared entity, on the modeling tier's terms. +/// +/// The kernels' dialect rule deliberately *rejects* a member-prefixed call: a +/// kernel endpoint is a free function, so `other.dfb_sink(x)` is a different +/// function that happens to share a name. The modeling declaration language +/// binds by a **type-plus-member** triple, and half of its entities are +/// therefore reached through their declaring type — `Audit.record(...)`, +/// `Config.fetchRemote()`, `alpha.get("k")`. So the modeling tier accepts a +/// member-qualified call as well, and the two rules together cover both +/// spellings without changing what a kernel reconciles. +fn modeling_callsite_lines( + body: &str, + function_name: &str, + declaration_line: u64, + dialect: AnchorDialect, +) -> BTreeSet { + body.lines() + .enumerate() + .filter_map(|(offset, candidate)| { + let line = offset as u64 + 1; + (line != declaration_line + && (dialect.is_call(candidate, function_name) + || member_qualified_call(candidate, function_name))) + .then_some(line) + }) + .collect() +} + +/// Whether a line reaches `function_name` through a member operator and calls +/// it. The three operators are the ones the corpus's dialects already treat as +/// member access: `.` everywhere, `::` in Ruby and C++, and `->` in C and C++. +fn member_qualified_call(line: &str, function_name: &str) -> bool { + let line = code_without_literals_in(&line.replace("->", "."), CommentSyntax::DoubleSlashOrHash); + let mut search_from = 0; + while let Some(offset) = line[search_from..].find(function_name) { + let start = search_from + offset; + let end = start + function_name.len(); + let before = line[..start].chars().next_back(); + let after = line[end..] + .chars() + .find(|character| !character.is_whitespace()); + if matches!(before, Some('.') | Some(':')) && after == Some('(') { + return true; + } + search_from = end; } + false } -#[cfg(test)] -mod tests { - use super::*; +/// Everything one modeling case is reconciled against: the region its source +/// anchor governs and the callsites of its anchored sink function. +struct ModelingAnchors { + source: ModelingSourceRegion, + sinks: Vec, +} - /// Creates a fresh scratch directory under the system temp dir. Parallel - /// test threads share a pid and can observe the same nanosecond timestamp, - /// so a process-wide counter disambiguates, and `create_dir` (not - /// `create_dir_all`) atomically claims the path so a leftover directory - /// from a prior run is never silently reused. - fn unique_test_dir(prefix: &str) -> PathBuf { - use std::sync::atomic::{AtomicU64, Ordering}; - static COUNTER: AtomicU64 = AtomicU64::new(0); - loop { - let unique = format!( - "{prefix}-{}-{}-{}", - std::process::id(), - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_nanos(), - COUNTER.fetch_add(1, Ordering::Relaxed), - ); - let root = std::env::temp_dir().join(unique); - match fs::create_dir(&root) { - Ok(()) => return root, - Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => continue, - Err(error) => panic!("creating scratch dir {}: {error}", root.display()), - } +fn modeling_anchors( + case_path: &Path, + case: &Value, + dialect: AnchorDialect, +) -> std::result::Result { + Ok(ModelingAnchors { + source: modeling_source_region(case_path, case, dialect)?, + sinks: modeling_sink_locations(case_path, case, dialect)?, + }) +} + +/// The modeling tier's sink-anchor resolution. +/// +/// Identical to `sink_anchor_locations` except that it accepts a +/// member-qualified callsite, for the reason `modeling_callsite_lines` gives: +/// a declared sink like `Audit.record` is reached through its declaring type, +/// and the kernels' receiverless-only rule would report it as having no +/// callsites at all. +fn modeling_sink_locations( + case_path: &Path, + case: &Value, + dialect: AnchorDialect, +) -> std::result::Result, String> { + let fixture_root = case_path + .parent() + .ok_or_else(|| "case path has no parent".to_string())?; + let mut locations = Vec::new(); + for anchor in case["sink_anchors"] + .as_array() + .ok_or_else(|| "case has no sink anchors".to_string())? + { + let file = anchor["file"] + .as_str() + .ok_or_else(|| "sink anchor lacks file".to_string())?; + let marker = anchor["marker"] + .as_str() + .ok_or_else(|| "sink anchor lacks marker".to_string())?; + let body = fs::read_to_string(fixture_root.join(file)) + .map_err(|error| format!("read sink fixture {file}: {error}"))?; + let marker_line = anchor_marker_line(&body, marker, anchor["line_hint"].as_u64())?; + let declaration = body + .lines() + .nth(marker_line as usize - 1) + .ok_or_else(|| format!("sink anchor line {marker_line} is outside {file}"))?; + let function_name = dialect + .declared_function_name(declaration, marker) + .ok_or_else(|| format!("sink marker {marker:?} is not on a function declaration"))?; + let callsite_lines = modeling_callsite_lines(&body, &function_name, marker_line, dialect); + if callsite_lines.is_empty() { + return Err(format!( + "sink function {function_name} has no callsites in {file}" + )); } + locations.push(SinkAnchorLocation { + file: file.to_string(), + marker_line, + function_name, + callsite_lines, + }); + } + if locations.is_empty() { + return Err("case has no resolvable sink locations".to_string()); } + Ok(locations) +} - struct FreezeFixture { - root: PathBuf, - manifest: PathBuf, - report: PathBuf, - raw: PathBuf, +impl ModelingAnchors { + fn sink_matches(&self, file: &str, line: u64) -> bool { + self.sinks.iter().any(|location| { + evidence_path_matches_file(file, &location.file) + && location.callsite_lines.contains(&line) + }) } +} - impl FreezeFixture { - fn new(outcome: &str, raw: Value) -> Self { - let root = unique_test_dir("dataflowbench-freeze-test"); - fs::create_dir_all(root.join("schemas")).unwrap(); - fs::create_dir_all(root.join("cases/taint/test")).unwrap(); - fs::create_dir_all(root.join("reports/raw")).unwrap(); - for schema in [ - "case.schema.json", - "result.schema.json", - "freeze.schema.json", - ] { - fs::copy( - Path::new("schemas").join(schema), - root.join("schemas").join(schema), - ) - .unwrap(); - } +/// Fold a tally of reconciled findings into one result-schema outcome. +/// +/// The three-way vocabulary is the corpus's own, with one modeling-specific +/// reading of `unmatched`. On a kernel, a finding that reconciles to nothing is +/// unusable evidence and stays `inconclusive`. On this tier a finding that +/// reconciles to nothing is *expected*: the fixture carries the pair's other +/// entity, and a flow on that entity is fully attributable and says nothing +/// about this case's anchors. So an unmatched finding is `not-reached` with the +/// count retained, and only evidence with no usable location at all — which is +/// still unreadable — stays `inconclusive`. +fn modeling_tally_outcome( + matched: usize, + unmatched: usize, + ambiguous: usize, +) -> (&'static str, Vec) { + if ambiguous > 0 { + return ( + "inconclusive", + vec![format!( + "{ambiguous} modeling finding(s) carry no usable or an ambiguous location" + )], + ); + } + if matched > 0 { + return ("reached", Vec::new()); + } + if unmatched > 0 { + return ( + "not-reached", + vec![format!( + "{unmatched} finding(s) reconciled to neither this case's source region nor its sink anchor; on the modeling tier a fixture carries its pair's other entity by construction, so a flow on that entity is not this assertion's" + )], + ); + } + ("not-reached", Vec::new()) +} - let case_relative = "cases/taint/test/case.json"; - let fixture_relative = "cases/taint/test/flow.c"; - let case_path = root.join(case_relative); - fs::write( - &case_path, - serde_json::to_vec_pretty(&json!({ - "schema_version": 2, - "id": "dfb-taint-test", - "template_id": "dfb-template-test", - "polarity": "positive", - "score_tier": "core", - "track": "taint", - "language": "c", - "semantic_dimensions": ["local-flow"], - "feature_tags": ["intraprocedural"], - "model_profile": "benchmark-controlled", - "fixture_files": ["flow.c"], - "source_anchors": [{"marker": "DFB-SOURCE: input", "file": "flow.c"}], - "sink_anchors": [{"marker": "DFB-SINK: sink", "file": "flow.c"}], +/// The physical location of one SARIF location object, if it carries one. +fn sarif_location_position(location: &Value) -> Option<(String, u64)> { + let physical = &location["physicalLocation"]; + let file = physical["artifactLocation"]["uri"].as_str()?; + let line = physical["region"]["startLine"].as_u64()?; + Some((file.to_string(), line)) +} + +/// Reconcile one CodeQL path-problem result against a modeling case's anchors. +fn modeling_sarif_match(result: &Value, anchors: &ModelingAnchors) -> EvidenceAnchorMatch { + let Some(sink) = result["locations"] + .as_array() + .and_then(|locations| locations.first()) + .and_then(sarif_location_position) + else { + return EvidenceAnchorMatch::Ambiguous; + }; + // A `@kind path-problem` result carries its source as the first location of + // its first thread flow, and repeats it in `relatedLocations`. Either is the + // query's own statement of where the flow began. A flow whose source and + // sink are the *same* node — `dfb_sink(dfb_source())`, which is exactly what + // several one-hop modeling templates are — carries neither, because there is + // no path to draw; its own location is then the flow's whole extent, and + // that is a complete statement of where it began, not a missing one. + let source = result["codeFlows"] + .as_array() + .and_then(|flows| flows.first()) + .and_then(|flow| flow["threadFlows"].as_array()) + .and_then(|threads| threads.first()) + .and_then(|thread| thread["locations"].as_array()) + .and_then(|locations| locations.first()) + .and_then(|entry| sarif_location_position(&entry["location"])) + .or_else(|| { + result["relatedLocations"] + .as_array() + .and_then(|locations| locations.first()) + .and_then(sarif_location_position) + }) + .unwrap_or_else(|| sink.clone()); + let (source_file, source_line) = source; + if anchors.sink_matches(&sink.0, sink.1) && anchors.source.contains(&source_file, source_line) { + EvidenceAnchorMatch::Matched + } else { + EvidenceAnchorMatch::Unmatched + } +} + +/// Normalize a CodeQL SARIF document for one modeling case. +fn modeling_codeql_outcome( + case_path: &Path, + case: &Value, + sarif: &Value, + dialect: AnchorDialect, +) -> (&'static str, Vec) { + let mut diagnostics = sarif_messages(sarif); + if sarif["runs"].as_array().is_none_or(|runs| runs.is_empty()) { + diagnostics.push("CodeQL SARIF contains no analysis runs".to_string()); + return ("runner-error", diagnostics); + } + let anchors = match modeling_anchors(case_path, case, dialect) { + Ok(anchors) => anchors, + Err(reason) => { + diagnostics.push(format!( + "cannot reconcile a CodeQL finding against this case's anchors: {reason}" + )); + return ("inconclusive", diagnostics); + } + }; + let (mut matched, mut unmatched, mut ambiguous) = (0, 0, 0); + for result in sarif["runs"] + .as_array() + .into_iter() + .flatten() + .flat_map(|run| run["results"].as_array().into_iter().flatten()) + { + match modeling_sarif_match(result, &anchors) { + EvidenceAnchorMatch::Matched => matched += 1, + EvidenceAnchorMatch::Unmatched => unmatched += 1, + EvidenceAnchorMatch::Ambiguous => ambiguous += 1, + } + } + let (outcome, tally) = modeling_tally_outcome(matched, unmatched, ambiguous); + diagnostics.extend(tally); + diagnostics.sort(); + diagnostics.dedup(); + (outcome, diagnostics) +} + +/// Normalize a Joern modeling evidence document for one case. +/// +/// This deliberately does not reuse `joern_flow_outcome`. That function reports +/// `inconclusive` when a run resolved zero source or zero sink nodes, because on +/// a kernel an unobserved endpoint means the run never saw the assertion. On the +/// modeling tier an unobserved endpoint is frequently *the measurement*: the +/// declared-source negative's `Config.fetchLocal` and the declared-sink +/// negative's `Audit.discard` are undeclared on purpose, so the model binds no +/// node and zero is the correct, informative answer. Converting that into +/// `inconclusive` would hide the one thing category S exists to show. A run that +/// produced no CPG at all is still unusable, and stays `runner-error`. +fn modeling_joern_outcome( + case_path: &Path, + case: &Value, + raw: &Value, + dialect: AnchorDialect, +) -> (&'static str, Vec) { + match raw["state"].as_str() { + Some("analyzed") => {} + Some("runner-error") => { + return ( + "runner-error", + vec![ + raw["diagnostic"] + .as_str() + .unwrap_or("Joern reported a runner error without a diagnostic") + .to_string(), + ], + ); + } + Some(other) => { + return ( + "runner-error", + vec![format!( + "Joern modeling evidence declares unexpected state {other:?}" + )], + ); + } + None => { + return ( + "runner-error", + vec!["Joern modeling evidence declares no state".to_string()], + ); + } + } + if raw["method_count"].as_u64().is_none_or(|count| count == 0) { + return ( + "runner-error", + vec!["Joern modeling run produced no methods; the frontend extracted nothing".into()], + ); + } + let Some(flows) = raw["flows"].as_array() else { + return ( + "runner-error", + vec!["Joern modeling evidence lacks its flows array".to_string()], + ); + }; + let mut diagnostics = vec![format!( + "Joern bound {} declared source node(s) and {} declared sink node(s) under {} loaded semantic entr(ies)", + raw["source_node_count"].as_u64().unwrap_or_default(), + raw["sink_node_count"].as_u64().unwrap_or_default(), + raw["declared_semantics_count"].as_u64().unwrap_or_default() + )]; + if flows.is_empty() { + return ("not-reached", diagnostics); + } + let anchors = match modeling_anchors(case_path, case, dialect) { + Ok(anchors) => anchors, + Err(reason) => { + diagnostics.push(format!( + "cannot reconcile a Joern flow against this case's anchors: {reason}" + )); + return ("inconclusive", diagnostics); + } + }; + let (mut matched, mut unmatched, mut ambiguous) = (0, 0, 0); + for flow in flows { + match modeling_joern_flow_match(flow, &anchors) { + EvidenceAnchorMatch::Matched => matched += 1, + EvidenceAnchorMatch::Unmatched => unmatched += 1, + EvidenceAnchorMatch::Ambiguous => ambiguous += 1, + } + } + let (outcome, tally) = modeling_tally_outcome(matched, unmatched, ambiguous); + diagnostics.extend(tally); + diagnostics.sort(); + diagnostics.dedup(); + (outcome, diagnostics) +} + +/// A Joern flow matches when its first element sits in the case's source region +/// and some element sits on a callsite of its anchored sink function. +fn modeling_joern_flow_match(flow: &Value, anchors: &ModelingAnchors) -> EvidenceAnchorMatch { + let Some(elements) = flow["elements"].as_array() else { + return EvidenceAnchorMatch::Ambiguous; + }; + let mut positions = Vec::with_capacity(elements.len()); + for element in elements { + let (Some(file), Some(line)) = (element["file"].as_str(), element["line"].as_u64()) else { + return EvidenceAnchorMatch::Ambiguous; + }; + positions.push((file, line)); + } + let Some((source_file, source_line)) = positions.first().copied() else { + return EvidenceAnchorMatch::Ambiguous; + }; + let sink_matched = positions + .iter() + .any(|(file, line)| anchors.sink_matches(file, *line)); + if sink_matched && anchors.source.contains(source_file, source_line) { + EvidenceAnchorMatch::Matched + } else { + EvidenceAnchorMatch::Unmatched + } +} + +/// Normalize a Semgrep `--json` document for one modeling case. +/// +/// The pinned CE distribution emits no dataflow trace in its OSS output, so a +/// finding states only its own position. That is sufficient here precisely +/// because the CE engine is intraprocedural: a finding it reports lies inside +/// the procedure its source was taken from, so a finding that falls in the +/// case's source region *is* a finding of this case's assertion. +fn modeling_semgrep_outcome( + case_path: &Path, + case: &Value, + raw: &Value, + dialect: AnchorDialect, +) -> (&'static str, Vec) { + let errors = raw["errors"].as_array().map(Vec::as_slice).unwrap_or(&[]); + if !errors.is_empty() { + let mut diagnostics: Vec = errors + .iter() + .map(|error| { + format!( + "Semgrep reported a scan error: {}", + error["message"].as_str().unwrap_or("no message") + ) + }) + .collect(); + diagnostics.sort(); + diagnostics.dedup(); + return ("runner-error", diagnostics); + } + let Some(results) = raw["results"].as_array() else { + return ( + "runner-error", + vec!["Semgrep evidence lacks its results array".to_string()], + ); + }; + if results.is_empty() { + return ("not-reached", Vec::new()); + } + let anchors = match modeling_anchors(case_path, case, dialect) { + Ok(anchors) => anchors, + Err(reason) => { + return ( + "inconclusive", + vec![format!( + "cannot reconcile a Semgrep finding against this case's anchors: {reason}" + )], + ); + } + }; + let (mut matched, mut unmatched, mut ambiguous) = (0, 0, 0); + for result in results { + let (Some(path), Some(line)) = (result["path"].as_str(), result["start"]["line"].as_u64()) + else { + ambiguous += 1; + continue; + }; + if anchors.sink_matches(path, line) && anchors.source.contains(path, line) { + matched += 1; + } else { + unmatched += 1; + } + } + let (outcome, diagnostics) = modeling_tally_outcome(matched, unmatched, ambiguous); + (outcome, diagnostics) +} + +/// Materialize one modeling case's fixtures in a fresh scratch workspace. +fn materialize_modeling_workspace( + tool: ModelingTool, + case_path: &Path, + case: &Value, + id: &str, +) -> Result { + let scratch = std::env::temp_dir() + .join(format!("dataflowbench-modeling-{}", tool.key())) + .join(id); + if scratch.exists() { + fs::remove_dir_all(&scratch).with_context(|| format!("clear {}", scratch.display()))?; + } + let workspace = scratch.join("source"); + fs::create_dir_all(&workspace)?; + let fixture_root = case_path.parent().expect("case path has parent"); + for fixture in case["fixture_files"].as_array().expect("schema validated") { + let fixture = fixture.as_str().expect("schema validated"); + fs::copy(fixture_root.join(fixture), workspace.join(fixture))?; + } + Ok(scratch) +} + +/// Run one scored modeling cell through Bifrost's policy CLI, reusing the +/// adapter's own per-case machinery: the same workspace materialization, the +/// same invocation, and the same `normalize_bifrost` reading of the report. +fn run_bifrost_modeling_case( + binary: &Path, + plan: &ModelingRunPlan, + case_path: &Path, + case: &Value, + id: &str, +) -> Result<(&'static str, Vec, PathBuf)> { + let policy = plan.language.artifact(ModelingTool::Bifrost); + let raw_path = plan.raw_dir.join(format!("{id}.json")); + if raw_path.exists() { + fs::remove_file(&raw_path).with_context(|| format!("clear {}", raw_path.display()))?; + } + let workspace = materialize_bifrost_workspace(case_path, case, policy)?; + let mut command = Command::new(binary); + command + .arg("--root") + .arg(&workspace) + .arg("--policy-file") + .arg("policy.rqlp") + .args([ + "--evaluation-date", + BIFROST_EVALUATION_DATE, + "--format", + "json", + "--fail-on", + "never", + "--output", + ]) + .arg(&raw_path); + let output = match command.output() { + Ok(output) => output, + Err(error) => { + let diagnostic = format!("failed to run {}: {error}", binary.display()); + write_bifrost_error(&raw_path, id, None, "spawn", "", &diagnostic)?; + return Ok(("runner-error", vec![diagnostic], raw_path)); + } + }; + let status_code = output.status.code(); + if !raw_path.is_file() { + let diagnostic = format!( + "Bifrost policy execution produced no JSON report (status {})", + output.status + ); + write_bifrost_error( + &raw_path, + id, + status_code, + "evaluate", + String::from_utf8_lossy(&output.stdout).trim(), + &format!( + "{diagnostic}\n{}", + String::from_utf8_lossy(&output.stderr).trim() + ), + )?; + return Ok(("runner-error", vec![diagnostic], raw_path)); + } + let raw = + fs::read_to_string(&raw_path).with_context(|| format!("read {}", raw_path.display()))?; + let report: Value = match serde_json::from_str(&raw) { + Ok(report) => report, + Err(error) => { + let diagnostic = format!("parse Bifrost JSON report {}: {error}", raw_path.display()); + return Ok(("runner-error", vec![diagnostic], raw_path)); + } + }; + let (outcome, diagnostics, _) = normalize_bifrost(case, &report, status_code)?; + Ok((outcome, diagnostics, raw_path)) +} + +/// Run one scored modeling cell through the Joern modeling script, which loads +/// the per-language flow-semantics artifact into the engine. +fn run_joern_modeling_case( + binary: &Path, + plan: &ModelingRunPlan, + case_path: &Path, + case: &Value, + id: &str, +) -> Result<(&'static str, Vec, PathBuf)> { + let script = + fs::canonicalize(JOERN_MODELING_SCRIPT).context("resolve the Joern modeling script")?; + let semantics = fs::canonicalize(plan.language.artifact(ModelingTool::Joern)) + .context("resolve the Joern modeling semantics")?; + let raw_root = + fs::canonicalize(&plan.raw_dir).context("resolve the Joern modeling evidence directory")?; + let raw_path = plan.raw_dir.join(format!("{id}.json")); + let absolute_raw_path = raw_root.join(format!("{id}.json")); + for stale in [&raw_path, &plan.raw_dir.join(format!("{id}-error.json"))] { + if stale.exists() { + fs::remove_file(stale).with_context(|| format!("clear {}", stale.display()))?; + } + } + let scratch = materialize_modeling_workspace(ModelingTool::Joern, case_path, case, id)?; + let workspace = scratch.join("source"); + + let result = (|| { + let mut command = Command::new(binary); + command + // Joern materializes its console project under the working + // directory, so keeping that inside the per-case scratch root means + // no case can observe another case's CPG. + .current_dir(&scratch) + .arg("--script") + .arg(&script) + .arg("--param") + .arg(format!("inputPath={}", workspace.display())) + .arg("--param") + .arg(format!( + "language={}", + modeling_joern_frontend(plan.language) + )) + .arg("--param") + .arg(format!("semanticsPath={}", semantics.display())) + .arg("--param") + .arg(format!("outputPath={}", absolute_raw_path.display())) + .stdin(std::process::Stdio::null()); + let output = match command.output() { + Ok(output) => output, + Err(error) => { + let diagnostic = format!( + "failed to run the Joern modeling script with {}: {error}", + binary.display() + ); + let path = write_joern_error(&plan.raw_dir, id, "script-spawn", &diagnostic, None)?; + return Ok(("runner-error", vec![diagnostic], path)); + } + }; + if !output.status.success() { + let diagnostic = format!("Joern modeling script failed with status {}", output.status); + let path = write_joern_error( + &plan.raw_dir, + id, + "script-execution", + &diagnostic, + Some(&output), + )?; + return Ok(("runner-error", vec![diagnostic], path)); + } + if !raw_path.is_file() { + let diagnostic = "Joern modeling script produced no evidence document".to_string(); + let path = write_joern_error( + &plan.raw_dir, + id, + "script-output", + &diagnostic, + Some(&output), + )?; + return Ok(("runner-error", vec![diagnostic], path)); + } + let text = match fs::read_to_string(&raw_path) { + Ok(text) => text, + Err(error) => { + return Ok(( + "runner-error", + vec![format!( + "read Joern modeling evidence {}: {error}", + raw_path.display() + )], + raw_path.clone(), + )); + } + }; + let raw: Value = match serde_json::from_str(&text) { + Ok(raw) => raw, + Err(error) => { + return Ok(( + "runner-error", + vec![format!( + "parse Joern modeling evidence {}: {error}", + raw_path.display() + )], + raw_path.clone(), + )); + } + }; + let (outcome, diagnostics) = + modeling_joern_outcome(case_path, case, &raw, modeling_dialect(plan.language)); + Ok((outcome, diagnostics, raw_path.clone())) + })(); + + let cleanup = + fs::remove_dir_all(&scratch).with_context(|| format!("clear {}", scratch.display())); + finish_modeling_case("Joern", result, cleanup) +} + +/// Run one scored modeling cell through Semgrep CE. +/// +/// The modeling rule carries no runner-substituted placeholder: the whole point +/// of the tier is that the declarations are the benchmark's, written out once in +/// the committed artifact, so the invocation names the committed file directly. +fn run_semgrep_modeling_case( + binary: &Path, + plan: &ModelingRunPlan, + case_path: &Path, + case: &Value, + id: &str, +) -> Result<(&'static str, Vec, PathBuf)> { + let rule = fs::canonicalize(plan.language.artifact(ModelingTool::Semgrep)) + .context("resolve the Semgrep modeling rule")?; + let raw_path = plan.raw_dir.join(format!("{id}.json")); + for stale in [&raw_path, &plan.raw_dir.join(format!("{id}-error.json"))] { + if stale.exists() { + fs::remove_file(stale).with_context(|| format!("clear {}", stale.display()))?; + } + } + let scratch = materialize_modeling_workspace(ModelingTool::Semgrep, case_path, case, id)?; + let workspace = scratch.join("source"); + + let result = (|| { + let mut command = Command::new(binary); + command + .current_dir(&scratch) + .arg("scan") + // Never report usage metrics, and never let the Pro engine or the + // registry enter the run: this population is CE-only by contract. + .arg("--metrics=off") + .arg("--oss-only") + .arg("--disable-version-check") + .arg("--no-git-ignore") + .arg("--quiet") + .arg("--json") + .arg("--config") + .arg(&rule) + .arg(&workspace) + .stdin(std::process::Stdio::null()); + let output = match command.output() { + Ok(output) => output, + Err(error) => { + let diagnostic = format!( + "failed to run the Semgrep modeling scan with {}: {error}", + binary.display() + ); + let path = write_semgrep_error(&plan.raw_dir, id, "scan-spawn", &diagnostic, None)?; + return Ok(("runner-error", vec![diagnostic], path)); + } + }; + // Semgrep exits 0 with or without findings and reserves higher codes + // for its own failures, so anything non-zero is a runner error and can + // never be read as an empty finding list. + if !output.status.success() { + let diagnostic = format!("Semgrep modeling scan failed with status {}", output.status); + let path = write_semgrep_error( + &plan.raw_dir, + id, + "scan-execution", + &diagnostic, + Some(&output), + )?; + return Ok(("runner-error", vec![diagnostic], path)); + } + fs::write(&raw_path, &output.stdout)?; + let raw: Value = match serde_json::from_slice(&output.stdout) { + Ok(raw) => raw, + Err(error) => { + let diagnostic = format!( + "parse Semgrep modeling evidence {}: {error}", + raw_path.display() + ); + let path = + write_semgrep_error(&plan.raw_dir, id, "scan-output", &diagnostic, None)?; + return Ok(("runner-error", vec![diagnostic], path)); + } + }; + let (outcome, diagnostics) = + modeling_semgrep_outcome(case_path, case, &raw, modeling_dialect(plan.language)); + Ok((outcome, diagnostics, raw_path.clone())) + })(); + + let cleanup = + fs::remove_dir_all(&scratch).with_context(|| format!("clear {}", scratch.display())); + finish_modeling_case("Semgrep", result, cleanup) +} + +/// Fold a per-case result together with its scratch cleanup, so a cleanup +/// failure is retained rather than swallowed and never leaves a clean negative +/// standing on a workspace that could not be torn down. +fn finish_modeling_case( + tool: &str, + result: Result<(&'static str, Vec, PathBuf)>, + cleanup: Result<()>, +) -> Result<(&'static str, Vec, PathBuf)> { + match (result, cleanup) { + (Ok(normalized), Ok(())) => Ok(normalized), + (Ok((_, mut diagnostics, path)), Err(error)) => { + diagnostics.push(format!( + "{tool} modeling case artifact cleanup failed: {error}" + )); + diagnostics.sort(); + diagnostics.dedup(); + Ok(("runner-error", diagnostics, path)) + } + (Err(error), Ok(())) => Err(error), + (Err(error), Err(cleanup_error)) => Err(error.context(format!( + "{tool} modeling case artifact cleanup also failed: {cleanup_error}" + ))), + } +} + +/// Run one scored modeling cell through CodeQL, reusing the Java kernel's own +/// per-case machinery — workspace materialization, the traced `javac` +/// extraction, `database analyze`, and the SARIF execution-error check — and +/// substituting only the modeling reconciliation for the kernel's raw result +/// count. +fn run_codeql_modeling_case( + binary: &Path, + packs: Option<&Path>, + plan: &ModelingRunPlan, + case_path: &Path, + case: &Value, +) -> Result<(&'static str, Vec, PathBuf)> { + let query = PathBuf::from(plan.language.artifact(ModelingTool::Codeql)); + let language = match plan.language { + ModelingLanguage::Java => CodeqlLanguage::Java, + ModelingLanguage::Python => CodeqlLanguage::Python, + // The ECMAScript CodeQL populations are extracted through their own + // per-kernel path rather than through `CodeqlLanguage`, so wiring this + // arm is part of the JavaScript language pull request. Until then a + // scored JavaScript cell is a hard error, never a synthesized outcome. + ModelingLanguage::Javascript => bail!( + "the CodeQL modeling execution arm for JavaScript lands with that language's pull request (docs/modeling-matrix.md#rollout-plan); refusing to synthesize an outcome for {}", + required_string(case, "id", "modeling case")? + ), + }; + let (outcome, diagnostics, raw_path) = run_codeql_case_for_language( + binary, + packs, + case_path, + case, + &query, + &plan.raw_dir, + language, + )?; + // Only a completed analysis is re-normalized: a runner error keeps its own + // outcome and its own retained evidence. + if outcome == "runner-error" { + return Ok((outcome, diagnostics, raw_path)); + } + let sarif: Value = match fs::read_to_string(&raw_path) + .ok() + .and_then(|text| serde_json::from_str(&text).ok()) + { + Some(sarif) => sarif, + None => { + return Ok(( + "runner-error", + vec![format!( + "read CodeQL modeling SARIF {}: unreadable", + raw_path.display() + )], + raw_path, + )); + } + }; + let (outcome, diagnostics) = + modeling_codeql_outcome(case_path, case, &sarif, modeling_dialect(plan.language)); + Ok((outcome, diagnostics, raw_path)) +} + +/// Run one adapter's modeling matrix for one language. +/// +/// The command's staged shape is recorded in docs/adapters.md: the population +/// gate, the artifact gate, the load-bearing gate, and the partition's +/// `unsupported` arm are infrastructure, and the arm that invokes the analyzer +/// over a *scored* cell lands with the language pull request that authors that +/// adapter's declarations. Both arms are live for every language whose +/// declarations exist; a scored cell an adapter has no execution arm for is +/// still a hard error, never a synthesized outcome. +fn run_modeling( + tool: ModelingTool, + binary: &Path, + language: ModelingLanguage, + codeql_packs: Option<&Path>, +) -> Result<()> { + if let Some(packs) = codeql_packs + && !packs.is_dir() + { + bail!("CodeQL pack search path {} does not exist", packs.display()); + } + let plan = plan_modeling_run(tool, language)?; + let scored = modeling_supported_templates(plan.tool); + + fs::create_dir_all(&plan.raw_dir)?; + let started = now_seconds()?; + let (version, build_identity) = modeling_version_identity(plan.tool, binary)?; + let revision = fixture_revision()?; + let mut results = Vec::with_capacity(plan.cases.len()); + for (case_path, case) in &plan.cases { + let id = required_string(case, "id", "modeling case")?; + let template = required_string(case, "template_id", id)?; + let start = Instant::now(); + // The capability decision comes first and is read from the + // preregistered partition by template identity. A declined cell is + // never handed to the analyzer, so it cannot produce an empty finding + // list that later reads as a negative. + let (outcome, diagnostics, raw_path) = + match modeling_partition_outcome(plan.tool, case, &plan.raw_dir)? { + Some((outcome, reason, raw_path)) => (outcome, vec![reason], raw_path), + None => { + if !scored.contains(&template) { + bail!( + "{template:?} is neither scored nor declined for {}", + plan.tool.key() + ); + } + match plan.tool { + ModelingTool::Bifrost => { + run_bifrost_modeling_case(binary, &plan, case_path, case, id)? + } + ModelingTool::Codeql => { + run_codeql_modeling_case(binary, codeql_packs, &plan, case_path, case)? + } + ModelingTool::Joern => { + run_joern_modeling_case(binary, &plan, case_path, case, id)? + } + ModelingTool::Semgrep => { + run_semgrep_modeling_case(binary, &plan, case_path, case, id)? + } + } + } + }; + results.push(normalized_result( + case, + id, + outcome, + diagnostics, + start.elapsed(), + &raw_path, + )); + } + let report = json!({ + "schema_version": 1, + "tool": plan.tool.key(), + "tool_version": version, + "tool_build_identity": build_identity, + "adapter_version": ADAPTER_VERSION, + "configuration_hash": hash_paths(&plan.configuration_paths)?, + "fixture_revision": revision, + "started_at_unix_seconds": started, + "ended_at_unix_seconds": now_seconds()?, + "cold_or_warm": "cold", + "results": results + }); + write_and_validate_report(&plan.report, &report)?; + println!("wrote {}", plan.report.display()); + Ok(()) +} + +/// The pinned version identity a modeling report records, read from the same +/// surface each adapter's kernel reports already read it from. +fn modeling_version_identity(tool: ModelingTool, binary: &Path) -> Result<(String, String)> { + match tool { + ModelingTool::Bifrost => Ok(( + command_output(Command::new(binary).arg("--version")) + .unwrap_or_else(|_| "unknown".into()), + command_output(Command::new(binary).arg("--build-identity")) + .unwrap_or_else(|_| "unknown".into()), + )), + ModelingTool::Codeql => codeql_version_identity(binary), + ModelingTool::Joern => joern_version_identity(binary), + ModelingTool::Semgrep => semgrep_version_identity(binary), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Creates a fresh scratch directory under the system temp dir. Parallel + /// test threads share a pid and can observe the same nanosecond timestamp, + /// so a process-wide counter disambiguates, and `create_dir` (not + /// `create_dir_all`) atomically claims the path so a leftover directory + /// from a prior run is never silently reused. + fn unique_test_dir(prefix: &str) -> PathBuf { + use std::sync::atomic::{AtomicU64, Ordering}; + static COUNTER: AtomicU64 = AtomicU64::new(0); + loop { + let unique = format!( + "{prefix}-{}-{}-{}", + std::process::id(), + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos(), + COUNTER.fetch_add(1, Ordering::Relaxed), + ); + let root = std::env::temp_dir().join(unique); + match fs::create_dir(&root) { + Ok(()) => return root, + Err(error) if error.kind() == std::io::ErrorKind::AlreadyExists => continue, + Err(error) => panic!("creating scratch dir {}: {error}", root.display()), + } + } + } + + struct FreezeFixture { + root: PathBuf, + manifest: PathBuf, + report: PathBuf, + raw: PathBuf, + } + + impl FreezeFixture { + fn new(outcome: &str, raw: Value) -> Self { + let root = unique_test_dir("dataflowbench-freeze-test"); + fs::create_dir_all(root.join("schemas")).unwrap(); + fs::create_dir_all(root.join("cases/taint/test")).unwrap(); + fs::create_dir_all(root.join("reports/raw")).unwrap(); + for schema in [ + "case.schema.json", + "result.schema.json", + "freeze.schema.json", + ] { + fs::copy( + Path::new("schemas").join(schema), + root.join("schemas").join(schema), + ) + .unwrap(); + } + + let case_relative = "cases/taint/test/case.json"; + let fixture_relative = "cases/taint/test/flow.c"; + let case_path = root.join(case_relative); + fs::write( + &case_path, + serde_json::to_vec_pretty(&json!({ + "schema_version": 2, + "id": "dfb-taint-test", + "template_id": "dfb-template-test", + "polarity": "positive", + "score_tier": "core", + "track": "taint", + "language": "c", + "semantic_dimensions": ["local-flow"], + "feature_tags": ["intraprocedural"], + "model_profile": "benchmark-controlled", + "fixture_files": ["flow.c"], + "source_anchors": [{"marker": "DFB-SOURCE: input", "file": "flow.c"}], + "sink_anchors": [{"marker": "DFB-SINK: sink", "file": "flow.c"}], "expected_flows": [{"source": "DFB-SOURCE: input", "sink": "DFB-SINK: sink"}], "expected_nonflows": [], "expected_analysis_capability": {"kind": "intraprocedural-taint"}, @@ -11555,6 +12552,17 @@ mod tests { for kernel in SEMGREP_KERNELS { assert!(hashed.contains(&PathBuf::from(kernel.rule()))); } + // The modeling artifacts share the rules directory and are bound into + // their own population's hash instead. A kernel hash that moved when a + // modeling wave landed would describe nothing about the kernel. + assert_eq!(hashed.len(), SEMGREP_KERNELS.len()); + for language in [ + ModelingLanguage::Java, + ModelingLanguage::Javascript, + ModelingLanguage::Python, + ] { + assert!(!hashed.contains(&PathBuf::from(language.artifact(ModelingTool::Semgrep)))); + } } /// The bounded profile is a declared-capability decision taken from the @@ -12928,31 +13936,31 @@ mod tests { assert!(SCORE_TIER_ORDER.contains(&"modeling")); } - /// This pull request is infrastructure only: the corpus carries no - /// modeling case, and every modeling run therefore fails fast rather than - /// writing an empty report. + /// Presence is the signal. Java's twenty-four assertions have landed, so + /// its population is the balanced twelve-template one and validates as + /// such; the two languages whose pull requests have not landed still have + /// no modeling denominator at all, which is different from having a zero. #[test] - fn the_checked_in_corpus_carries_no_modeling_case() { - for path in case_paths() { - let case: Value = serde_json::from_str(&fs::read_to_string(&path).unwrap()).unwrap(); - assert_ne!( - case["score_tier"], - "modeling", - "{} is a modeling case; this PR is infrastructure only", - path.display() - ); + fn the_rolled_out_modeling_populations_are_the_ones_that_landed() { + let java = select_modeling_cases(ModelingLanguage::Java).unwrap(); + assert_eq!(java.len(), MODELING_CASE_COUNT); + let templates: BTreeSet<&str> = java + .iter() + .filter_map(|(_, case)| case["template_id"].as_str()) + .collect(); + assert_eq!(templates, MODELING_TEMPLATE_IDS.into_iter().collect()); + for (_, case) in &java { + assert_eq!(case["model_profile"], MODELING_MODEL_PROFILE); + assert_eq!(case["score_tier"], "modeling"); } - for language in [ - ModelingLanguage::Java, - ModelingLanguage::Javascript, - ModelingLanguage::Python, - ] { + for language in [ModelingLanguage::Javascript, ModelingLanguage::Python] { assert!(select_modeling_cases(language).unwrap().is_empty()); } } /// With no population, a run fails with a clear error naming the language - /// and never writes a report. + /// and never writes a report. Java's population exists, so the language + /// that still exercises this arm is one whose pull request has not landed. #[test] fn a_modeling_run_without_a_population_fails_fast() { for (tool, binary) in [ @@ -12961,14 +13969,14 @@ mod tests { (ModelingTool::Joern, "joern"), (ModelingTool::Semgrep, "semgrep"), ] { - let error = run_modeling(tool, Path::new(binary), ModelingLanguage::Java, None) + let error = run_modeling(tool, Path::new(binary), ModelingLanguage::Python, None) .unwrap_err() .to_string(); assert!( - error.starts_with("no modeling population for java"), + error.starts_with("no modeling population for python"), "{error}" ); - assert!(!ModelingLanguage::Java.report(tool).exists()); + assert!(!ModelingLanguage::Python.report(tool).exists()); } } @@ -13020,6 +14028,98 @@ mod tests { ); } + /// Every Java modeling case resolves its own anchors, and the two halves of + /// each entry-point pair resolve to *disjoint* source regions. + /// + /// The second half is the load-bearing one. Category E's fixtures carry both + /// the declared and the undeclared handler, both uncalled, both sinking + /// their parameter — so the declared handler's flow is present in the + /// negative's fixture. If the two regions ever overlapped, the negative + /// would be scored on its sibling's finding. + #[test] + fn java_modeling_cases_resolve_disjoint_anchors() { + let mut entry_point_regions = Vec::new(); + for (path, case) in select_modeling_cases(ModelingLanguage::Java).unwrap() { + let anchors = modeling_anchors(&path, &case, AnchorDialect::Java) + .unwrap_or_else(|error| panic!("{}: {error}", path.display())); + assert!(!anchors.sinks.is_empty()); + assert!(!anchors.source.lines.is_empty()); + let template = case["template_id"].as_str().unwrap(); + if template.contains("entrypoint") { + entry_point_regions.push(( + template.to_string(), + case["polarity"].as_str().unwrap().to_string(), + anchors.source.lines.clone(), + )); + } + } + assert_eq!(entry_point_regions.len(), 4); + for template in [ + "dfb-template-model-entrypoint-parameter", + "dfb-template-model-entrypoint-selectivity", + ] { + let pair: Vec<&BTreeSet> = entry_point_regions + .iter() + .filter(|(id, _, _)| id == template) + .map(|(_, _, lines)| lines) + .collect(); + assert_eq!(pair.len(), 2, "{template} is not a pair"); + assert!( + pair[0].is_disjoint(pair[1]), + "{template}'s two source regions overlap: {:?} and {:?}", + pair[0], + pair[1] + ); + } + } + + /// A declared entity is reached through its declaring type, so the modeling + /// tier's callsite rule accepts a member-qualified call that the kernels' + /// receiverless-only rule rejects. Both spellings still have to be accepted. + #[test] + fn the_modeling_callsite_rule_accepts_a_member_qualified_call() { + assert!(member_qualified_call( + " Audit.record(dfb_source());", + "record" + )); + assert!(member_qualified_call( + " dfb_sink(Config.fetchRemote());", + "fetchRemote" + )); + assert!(member_qualified_call( + " dfb_sink(alpha.get(\"k\"));", + "get" + )); + // Not a call, and not this member. + assert!(!member_qualified_call( + " Audit.discard(x);", + "record" + )); + assert!(!member_qualified_call( + " static void record(String v) { }", + "record" + )); + // The kernels' receiverless spelling stays the dialect's business, and + // this rule must not start claiming it as member-qualified. + assert!(!member_qualified_call( + " dfb_sink(value);", + "dfb_sink" + )); + assert!(AnchorDialect::Java.is_call(" dfb_sink(value);", "dfb_sink")); + } + + /// A declaration governs its own line and the block indented beneath it, in + /// a braced language and an indented one alike. + #[test] + fn a_declaration_block_ends_where_the_indentation_returns() { + let braced = "final class Handler {\n void onRequest(String input) {\n dfb_sink(input);\n }\n\n void onIgnored(String input) {\n dfb_sink(input);\n }\n}\n"; + assert_eq!(declaration_block_lines(braced, 2), BTreeSet::from([2, 3])); + assert_eq!(declaration_block_lines(braced, 6), BTreeSet::from([6, 7])); + let indented = "class Handler:\n def on_request(self, value):\n dfb_sink(value)\n\n def on_ignored(self, value):\n dfb_sink(value)\n"; + assert_eq!(declaration_block_lines(indented, 2), BTreeSet::from([2, 3])); + assert_eq!(declaration_block_lines(indented, 5), BTreeSet::from([5, 6])); + } + /// The model-artifact, report, and raw-evidence paths the language pull /// requests populate. Twelve distinct artifacts, one per tool per language. #[test] @@ -13067,10 +14167,34 @@ mod tests { ModelingLanguage::Javascript.artifact(ModelingTool::Codeql), "adapters/codeql/javascript/queries/JavaScriptModeling.ql" ); - // No modeling artifact is committed yet; every one arrives with the - // language pull request that authors its declarations. - for artifact in artifacts { - assert!(!Path::new(artifact).exists(), "{artifact} exists already"); + // A modeling artifact arrives with the language pull request that + // authors its declarations, so exactly the landed languages' artifacts + // exist. Java's four are committed; the other eight are not. + let _ = &artifacts; + for tool in ModelingTool::ALL { + for (language, landed) in [ + (ModelingLanguage::Java, true), + (ModelingLanguage::Javascript, false), + (ModelingLanguage::Python, false), + ] { + let artifact = language.artifact(tool); + assert_eq!( + Path::new(artifact).exists(), + landed, + "{artifact} presence does not match its language's rollout" + ); + } } + assert!(Path::new(JOERN_MODELING_SCRIPT).is_file()); + // Java's CodeQL modeling query joins the adapter's root pack, which is + // the Java pack: `adapters/codeql/qlpack.yml` declares + // `dataflowbench/codeql-java` and the kernel query already sits beside + // it. A query under a `java/` subdirectory would resolve no + // `codeql/java-all` dependency, because there is no pack there. + assert_eq!( + ModelingLanguage::Java.artifact(ModelingTool::Codeql), + "adapters/codeql/queries/JavaModeling.ql" + ); + assert!(Path::new("adapters/codeql/qlpack.yml").is_file()); } }