mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-16 03:49:26 +00:00
feat(pre-push-safety-net): preserve uncertainty in benchmark scoring
This commit is contained in:
@@ -44,3 +44,48 @@ Python populations are explicitly missing in `capability_prerequisites`. VAmPI r
|
||||
known targets (including SQLI), with `vulnerable=1`; these snapshot regressions are not paired pushes.
|
||||
Libpng is an envelope/unsupported-arithmetic control, not a detection success or a supported miss.
|
||||
The validator makes no finding, precision, recall, silence, latency or admission claim.
|
||||
|
||||
## Frozen diagnostic scoring (task 1.3)
|
||||
|
||||
`push_scoring` consumes recorded execution evidence; it does not run the scanner or
|
||||
implement push delta/admission policy. Freeze the workload and expected configuration
|
||||
**before** executing it:
|
||||
|
||||
```sh
|
||||
.venv/bin/python -m openultrasast.push_scoring freeze benchmarks/push/inputs.json benchmarks/push/diagnostic-config-v1.json > /tmp/profile.json
|
||||
.venv/bin/python -m openultrasast.push_scoring score /tmp/profile.json benchmarks/push/input-validation.json benchmarks/push/unmeasured-run-v1.json
|
||||
```
|
||||
|
||||
The committed v1 profile reserves the 11 declared cases and exact tip target locations.
|
||||
It is a proposed 30-second evidence-mode experiment, not measured performance. The
|
||||
`unmeasured-run-v1.json` deliberately contains no executions: scoring it exits **1**,
|
||||
retains all 11 unresolved cases, and earns no recall, coverage or admission. An invalid
|
||||
profile/runtime identity exits **2**. A fully resolved diagnostic score exits **0**;
|
||||
that exit status is not capability admission. Freeze a new version when configuration,
|
||||
source manifest, core, facts, query semantics or scope changes; do not edit a measured
|
||||
profile to match later execution. Runtime `context` must record the actual values,
|
||||
not merely copy an expected profile hash. Profiles are content identities, not signatures.
|
||||
|
||||
Each `records` entry supplies `case_id`, actual `ranking_mode`, `rank` (or null), exact
|
||||
`selected`/`deferred` question IDs, `queries`, `alerts`, `delta`, `coverage`, `cache_state`
|
||||
and nonnegative elapsed `timings` including `total`. Cache states distinguish `cold`,
|
||||
`warm_changed` and `identical_tip`; stage costs remain beside each outcome. Queries
|
||||
supply `id`, `status` and `outcome`. A positive needs a finding with the exact frozen
|
||||
`site` and `family`, a supported `rung`, and a nonempty actual `witness`. A transitive
|
||||
claim additionally needs a recorded `origin` and ordered `flow` from that region to
|
||||
the frozen target's path/function. Missing rank never proves transitivity. Negative
|
||||
answers require the exact `target` and a witnessed discharge; empty/failed queries
|
||||
cannot earn fixed-side silence. These checks establish evidence association, not the
|
||||
truth of an arbitrary supplied witness: use engine output and review the attribution.
|
||||
|
||||
Alerts are separate from raw findings. Only reviewed `actionable_true` alerts with
|
||||
`review_evidence`, `question_id` and exact `site` association can contribute precision;
|
||||
unreviewed/wrong-target alerts remain in its denominator. Benign comment changes retain
|
||||
vulnerable backlog, so a raw positive is not automatically a new alert. The scorer
|
||||
consumes a recorded delta; task 5.1 supplies replay, and the policy tasks establish it.
|
||||
|
||||
Reports retain unresolved cases, sample counts, Wilson intervals, separate regression
|
||||
results, per-capability metrics, coverage and cold/warm latency. Missing benign runs
|
||||
have unknown interruption rate. VAmPI's readable regression may be measured while
|
||||
independent admission prerequisites remain missing. Unsupported/unreviewed populations
|
||||
stay visible. All results remain experimental pending the later joint admission gate.
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"version": "pre-push-diagnostic-v1-2026-09-12",
|
||||
"ranking_mode": "evidence",
|
||||
"engine": "joern-4.0.625",
|
||||
"facts": "642d643d5b40a20fe482ace566cc77d132870930ecd2f2e881dcecd7dc9a0641",
|
||||
"queries": "64c1534edb07e770ab8631b48bc156ef54b71ddb8d8ee4357fd5022eb11f0229",
|
||||
"policy": "diagnostic-only-no-admission-v1",
|
||||
"scope": "first-party-only; declared vendor exclusion in graph and targets; exact selected/deferred question IDs required per record",
|
||||
"hardware": "Linux-6.8.0-138-generic-x86_64-with-glibc2.39",
|
||||
"budget_seconds": 30,
|
||||
"core": "7ac2bc93b35ce9d0cdcfc543266025519999ff45339657d4a5d283c67957d682",
|
||||
"targets": {
|
||||
"pmpro-introduce": {
|
||||
"path": "classes/class.memberorder.php",
|
||||
"function": "getMemberOrderByCode",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
936
|
||||
]
|
||||
},
|
||||
"pmpro-repair": {
|
||||
"path": "classes/class.memberorder.php",
|
||||
"function": "getMemberOrderByCode",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
937
|
||||
]
|
||||
},
|
||||
"pmpro-benign": {
|
||||
"path": "classes/class.memberorder.php",
|
||||
"function": "getMemberOrderByCode",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
937
|
||||
]
|
||||
},
|
||||
"nodegoat-introduce": {
|
||||
"path": "app/routes/contributions.js",
|
||||
"function": "handleContributionsUpdate",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
32,
|
||||
33,
|
||||
34
|
||||
]
|
||||
},
|
||||
"nodegoat-repair": {
|
||||
"path": "app/routes/contributions.js",
|
||||
"function": "handleContributionsUpdate",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
32,
|
||||
33,
|
||||
34
|
||||
]
|
||||
},
|
||||
"nodegoat-benign": {
|
||||
"path": "app/routes/contributions.js",
|
||||
"function": "handleContributionsUpdate",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
32,
|
||||
33,
|
||||
34
|
||||
]
|
||||
},
|
||||
"VAmPI-SQLI": {
|
||||
"path": "models/user_model.py",
|
||||
"function": "get_user",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
73
|
||||
]
|
||||
},
|
||||
"VAmPI-BOLA": {
|
||||
"path": "api_views/users.py",
|
||||
"function": "update_password",
|
||||
"family": "access_control",
|
||||
"lines": [
|
||||
187
|
||||
]
|
||||
},
|
||||
"VAmPI-BOLA-BOOKS": {
|
||||
"path": "api_views/books.py",
|
||||
"function": "get_by_title",
|
||||
"family": "access_control",
|
||||
"lines": [
|
||||
51
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"manifest_sha256": "eec13cb19fe5e2c2402e61ebf4fd17fa809482f321e7a8e615215a12e1bcf845",
|
||||
"cases": [
|
||||
{
|
||||
"id": "pmpro-introduce",
|
||||
"base": "pmpro-fixed",
|
||||
"tip": "pmpro-vulnerable",
|
||||
"label": "vulnerable",
|
||||
"role": "development",
|
||||
"capability": "php/wordpress/injection",
|
||||
"provenance": "Authored replay direction reintroducing the reviewed operation; not a claim about the historical introducing commit.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "pmpro-repair",
|
||||
"base": "pmpro-vulnerable",
|
||||
"tip": "pmpro-fixed",
|
||||
"label": "fixed",
|
||||
"role": "development",
|
||||
"capability": "php/wordpress/injection",
|
||||
"provenance": "PMPro upstream2.9.7 to2.9.8 parameter binding fix for CVE-2023-23488.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "pmpro-benign",
|
||||
"base": "pmpro-vulnerable",
|
||||
"tip": "pmpro-benign",
|
||||
"label": "benign",
|
||||
"role": "development",
|
||||
"capability": "php/wordpress/injection",
|
||||
"provenance": "Authored comment-only change: no new defect; vulnerable backlog remains. This label does not mean repository-clean.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "nodegoat-introduce",
|
||||
"base": "nodegoat-fixed",
|
||||
"tip": "nodegoat-vulnerable",
|
||||
"label": "vulnerable",
|
||||
"role": "transfer",
|
||||
"capability": "javascript/express/injection",
|
||||
"provenance": "Authored replay direction reintroducing the reviewed operation; not a claim about the historical introducing commit.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "nodegoat-repair",
|
||||
"base": "nodegoat-vulnerable",
|
||||
"tip": "nodegoat-fixed",
|
||||
"label": "fixed",
|
||||
"role": "transfer",
|
||||
"capability": "javascript/express/injection",
|
||||
"provenance": "Authored replacement of three eval calls with Number conversion; source tutorial also documents alternate numeric parsing.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "nodegoat-benign",
|
||||
"base": "nodegoat-vulnerable",
|
||||
"tip": "nodegoat-benign",
|
||||
"label": "benign",
|
||||
"role": "transfer",
|
||||
"capability": "javascript/express/injection",
|
||||
"provenance": "Authored comment-only change: no new defect; vulnerable backlog remains. This label does not mean repository-clean.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "VAmPI-SQLI",
|
||||
"base": "vampi-regression",
|
||||
"tip": "vampi-regression",
|
||||
"label": "regression",
|
||||
"role": "regression",
|
||||
"capability": "python/flask/injection",
|
||||
"provenance": "Existing recipe known target, full target population retained; environment vulnerable=1. Snapshot regression, not an introducing push.",
|
||||
"prerequisites": [
|
||||
"Reviewed independent vulnerable/fixed/benign push pair required before hook admission."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "VAmPI-BOLA",
|
||||
"base": "vampi-regression",
|
||||
"tip": "vampi-regression",
|
||||
"label": "regression",
|
||||
"role": "regression",
|
||||
"capability": "python/flask/access_control",
|
||||
"provenance": "Existing recipe known target, full target population retained; environment vulnerable=1. Snapshot regression, not an introducing push.",
|
||||
"prerequisites": [
|
||||
"Reviewed independent vulnerable/fixed/benign push pair required before hook admission."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "VAmPI-BOLA-BOOKS",
|
||||
"base": "vampi-regression",
|
||||
"tip": "vampi-regression",
|
||||
"label": "regression",
|
||||
"role": "regression",
|
||||
"capability": "python/flask/access_control",
|
||||
"provenance": "Existing recipe known target, full target population retained; environment vulnerable=1. Snapshot regression, not an introducing push.",
|
||||
"prerequisites": [
|
||||
"Reviewed independent vulnerable/fixed/benign push pair required before hook admission."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "libpng-CVE-2025-66293",
|
||||
"base": "libpng-envelope",
|
||||
"tip": "libpng-envelope",
|
||||
"label": "unsupported",
|
||||
"role": "envelope",
|
||||
"capability": "c/libpng/memory_safety",
|
||||
"provenance": "Arithmetic/bounds is outside the current abstract domain; measures graph/cost envelope only.",
|
||||
"prerequisites": []
|
||||
},
|
||||
{
|
||||
"id": "ghost-reserved-population",
|
||||
"base": "ghost-reserved",
|
||||
"tip": "ghost-reserved",
|
||||
"label": "unreviewed",
|
||||
"role": "reserved_holdout",
|
||||
"capability": "javascript/express/unreviewed",
|
||||
"provenance": "Reserved from production API/module/async shape and public security-fix history before scanner results. Manifest6.64.0-rc.0, Express4.22.2. Not an ESM or Express5 coverage claim.",
|
||||
"prerequisites": [
|
||||
"Review and freeze supported positive/fixed/benign changes from independent history; select family before scanning.",
|
||||
"Freeze core and existing facts after development; preserve reservation and record any contamination."
|
||||
]
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"version": "pre-push-diagnostic-v1-2026-09-12",
|
||||
"ranking_mode": "evidence",
|
||||
"engine": "joern-4.0.625",
|
||||
"facts": "642d643d5b40a20fe482ace566cc77d132870930ecd2f2e881dcecd7dc9a0641",
|
||||
"queries": "64c1534edb07e770ab8631b48bc156ef54b71ddb8d8ee4357fd5022eb11f0229",
|
||||
"policy": "diagnostic-only-no-admission-v1",
|
||||
"scope": "first-party-only; declared vendor exclusion in graph and targets; exact selected/deferred question IDs required per record",
|
||||
"hardware": "Linux-6.8.0-138-generic-x86_64-with-glibc2.39",
|
||||
"budget_seconds": 30,
|
||||
"core": "7ac2bc93b35ce9d0cdcfc543266025519999ff45339657d4a5d283c67957d682",
|
||||
"targets": {
|
||||
"pmpro-introduce": {
|
||||
"path": "classes/class.memberorder.php",
|
||||
"function": "getMemberOrderByCode",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
936
|
||||
]
|
||||
},
|
||||
"pmpro-repair": {
|
||||
"path": "classes/class.memberorder.php",
|
||||
"function": "getMemberOrderByCode",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
937
|
||||
]
|
||||
},
|
||||
"pmpro-benign": {
|
||||
"path": "classes/class.memberorder.php",
|
||||
"function": "getMemberOrderByCode",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
937
|
||||
]
|
||||
},
|
||||
"nodegoat-introduce": {
|
||||
"path": "app/routes/contributions.js",
|
||||
"function": "handleContributionsUpdate",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
32,
|
||||
33,
|
||||
34
|
||||
]
|
||||
},
|
||||
"nodegoat-repair": {
|
||||
"path": "app/routes/contributions.js",
|
||||
"function": "handleContributionsUpdate",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
32,
|
||||
33,
|
||||
34
|
||||
]
|
||||
},
|
||||
"nodegoat-benign": {
|
||||
"path": "app/routes/contributions.js",
|
||||
"function": "handleContributionsUpdate",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
32,
|
||||
33,
|
||||
34
|
||||
]
|
||||
},
|
||||
"VAmPI-SQLI": {
|
||||
"path": "models/user_model.py",
|
||||
"function": "get_user",
|
||||
"family": "injection",
|
||||
"lines": [
|
||||
73
|
||||
]
|
||||
},
|
||||
"VAmPI-BOLA": {
|
||||
"path": "api_views/users.py",
|
||||
"function": "update_password",
|
||||
"family": "access_control",
|
||||
"lines": [
|
||||
187
|
||||
]
|
||||
},
|
||||
"VAmPI-BOLA-BOOKS": {
|
||||
"path": "api_views/books.py",
|
||||
"function": "get_by_title",
|
||||
"family": "access_control",
|
||||
"lines": [
|
||||
51
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"gates": {
|
||||
"precision": 0.95,
|
||||
"recall": 0.9,
|
||||
"completion": 0.95,
|
||||
"warm_p95_seconds": 30.0,
|
||||
"fixed_false_alerts": 0,
|
||||
"benign_false_alerts": 0
|
||||
},
|
||||
"profile_sha256": "95c26cf474573766fa24c44f4375cfcb506b196412cd421deadff35b4eb9ef3f"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"profile_sha256": "95c26cf474573766fa24c44f4375cfcb506b196412cd421deadff35b4eb9ef3f",
|
||||
"context": {
|
||||
"ranking_mode": "evidence",
|
||||
"engine": "joern-4.0.625",
|
||||
"facts": "642d643d5b40a20fe482ace566cc77d132870930ecd2f2e881dcecd7dc9a0641",
|
||||
"queries": "64c1534edb07e770ab8631b48bc156ef54b71ddb8d8ee4357fd5022eb11f0229",
|
||||
"policy": "diagnostic-only-no-admission-v1",
|
||||
"scope": "first-party-only; declared vendor exclusion in graph and targets; exact selected/deferred question IDs required per record",
|
||||
"hardware": "Linux-6.8.0-138-generic-x86_64-with-glibc2.39",
|
||||
"budget_seconds": 30,
|
||||
"core": "7ac2bc93b35ce9d0cdcfc543266025519999ff45339657d4a5d283c67957d682"
|
||||
},
|
||||
"records": []
|
||||
}
|
||||
Reference in New Issue
Block a user