Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
| ebb54f028e |
1 changed files with 43 additions and 0 deletions
|
|
@ -46,6 +46,13 @@ runs:
|
|||
run: |
|
||||
.nyx-src/target/release/nyx scan --format json --quiet > nyx-results-raw.json 2>nyx-scan.stderr
|
||||
|
||||
# Per-finding triage decisions (from the nyx serve UI) are keyed by a blake3
|
||||
# portable fingerprint. Best-effort install so the gate can honor them; if it
|
||||
# can't be installed the gate falls back to (rule_id, path) matching.
|
||||
python3 -c 'import blake3' 2>/dev/null \
|
||||
|| python3 -m pip install --quiet --break-system-packages blake3 2>/dev/null \
|
||||
|| true
|
||||
|
||||
python3 -c "
|
||||
import json, os
|
||||
|
||||
|
|
@ -61,8 +68,10 @@ runs:
|
|||
with open('.nyx/triage.json') as f:
|
||||
triage = json.load(f)
|
||||
rules = triage.get('suppression_rules', [])
|
||||
decisions = triage.get('decisions', [])
|
||||
except:
|
||||
rules = []
|
||||
decisions = []
|
||||
|
||||
def rel_path(p):
|
||||
p = p.replace(workspace, '').lstrip('/')
|
||||
|
|
@ -76,7 +85,41 @@ runs:
|
|||
i = rid.find(' (source ')
|
||||
return rid[:i] if i != -1 else rid
|
||||
|
||||
# Per-finding triage decisions (nyx serve UI), keyed by portable fingerprint:
|
||||
# blake3(id \0 rel_path \0 sink_snippet \0 source_snippet \0 func) — mirrors
|
||||
# nyx server/models.rs compute_portable_fingerprint. States open/investigating
|
||||
# still block; suppressed/false_positive/accepted_risk do not. If blake3 is
|
||||
# unavailable, fall back to (rule_id, path) — coarser but never crashes the gate.
|
||||
SUPPRESSING = ('suppressed', 'false_positive', 'accepted_risk')
|
||||
active = [d for d in decisions if d.get('state') in SUPPRESSING]
|
||||
try:
|
||||
import blake3
|
||||
def portable_fp(f):
|
||||
ev = f.get('evidence') or {}
|
||||
sink = ((ev.get('sink') or {}).get('snippet')) or ''
|
||||
src = ((ev.get('source') or {}).get('snippet')) or ''
|
||||
func = ''
|
||||
for s in (ev.get('flow_steps') or []):
|
||||
if s.get('function'):
|
||||
func = s['function']
|
||||
break
|
||||
data = '\0'.join([f.get('id', ''), rel_path(f.get('path', '')), sink, src, func]).encode('utf-8')
|
||||
return blake3.blake3(data).hexdigest()
|
||||
decided_fps = set(d.get('fingerprint', '') for d in active)
|
||||
def decided(f):
|
||||
return portable_fp(f) in decided_fps
|
||||
if active:
|
||||
print('decisions: matching', len(active), 'by portable fingerprint (blake3)')
|
||||
except ImportError:
|
||||
decided_keys = set((d.get('rule_id', ''), d.get('path', '')) for d in active)
|
||||
def decided(f):
|
||||
return (f.get('id', ''), rel_path(f.get('path', ''))) in decided_keys
|
||||
if active:
|
||||
print('decisions: blake3 unavailable, matching', len(active), 'by (rule_id, path)')
|
||||
|
||||
def is_suppressed(f):
|
||||
if decided(f):
|
||||
return True
|
||||
rule_id = base_rule(f.get('id', ''))
|
||||
path = rel_path(f.get('path', ''))
|
||||
for r in rules:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue