Commit 016791c
feat(assail): exempt JSON-LD / JSON-Schema identifier URIs from InsecureProtocol (#53)
## Summary
The cross-language InsecureProtocol detector was flagging JSON-LD
`@type`, `@id`, `@context` namespace URIs and JSON-Schema `$schema`
identifiers as if they were configured HTTP endpoints. They aren't: per
spec, those URIs are namespace identifiers (often historical `http://`
even for schemas served over HTTPS or not at all) and are never
dereferenced at runtime.
**Stacked on #52** (line-comment stripper) — that PR handled doc-comment
FPs; this one handles JSON-LD literal FPs that survive into runtime
code.
## Why a detector enhancement rather than verisimdb or the
user-classification registry
| Approach | Verdict |
|---|---|
| **VeriSimDB** | Storage + query, not a classifier. Cannot pre-empt FP
at detection time — would persist the FP and need a downstream rule.
Wrong layer. |
| **User-classification registry**
(`audits/assail-classifications.a2ml`) | Right tool for per-instance
audited TPs (\"UnsafeCode in `zig_bridge.rs` §1\"). Wrong tool for a
**categorical** FP class shared by every JSON-LD / JSON-Schema consumer
in the estate — would require N entries across N repos. |
| **Detector enhancement** (this PR) | Removes the recurring tax across
every estate repo with a single rule. The FP class is well-defined by
spec, low-risk to suppress. |
## Fix
New `RE_HTTP_JSONLD_IDENTIFIER` regex that matches the standard JSON-LD
/ JSON-Schema identifier keys (scalar or array form) and subtracts those
hits from the InsecureProtocol total before reporting.
| Pattern | Subtracted |
|---|---|
| `\"@type\": \"http://...\"` | ✓ |
| `\"@id\": \"http://...\"` | ✓ |
| `\"@context\": \"http://...\"` | ✓ |
| `\"types\": [\"http://...\"]` | ✓ |
| `\"$schema\": \"http://...\"` | ✓ |
| `\"url\": \"http://...\"` | ✗ — not an identifier key |
| `client.get(\"http://...\")` | ✗ — bare endpoint |
Exempted keys: `@id`, `@type`, `@context`, `@vocab`, `@graph` (JSON-LD);
`id`, `type`, `types` (common shorthands); `$schema`, `$id`, `$ref`
(JSON Schema).
## Regression coverage
7 new tests in `assail::analyzer::tests` (via a shared
`count_http_findings` test helper):
| Test | Asserts |
|---|---|
| `jsonld_at_type_uri_is_exempt` | `{\"@type\": \"http://...\"}` → 0
findings |
| `jsonld_at_id_uri_is_exempt` | `{\"@id\": \"http://...\"}` → 0
findings |
| `jsonld_at_context_uri_is_exempt` | `{\"@context\": \"http://...\"}` →
0 findings |
| `jsonld_types_array_is_exempt` | `{\"types\": [\"http://...\"]}` → 0
findings (exact self-scan repro) |
| `json_schema_dollar_schema_is_exempt` | `{\"$schema\":
\"http://...\"}` → 0 findings |
| `real_endpoint_url_is_still_flagged` | `client.get(\"http://...\")` →
>0 findings (invariant) |
| `endpoint_key_named_url_is_still_flagged` | `{\"url\":
\"http://...\"}` → >0 findings (invariant) |
Test URLs are runtime-composed (`format!(\"htt{}p://...\", \"\")`) so
the source itself contains no literal `http://[alphanum]` substring —
prevents a meta-circular self-scan finding when panic-attack scans its
own `analyzer.rs`.
## Verification
- [x] `cargo test --bin panic-attack --features signing,http` — **249
passed** (+7 new tests)
- [x] `cargo clippy --all-targets --features signing,http -- -D
warnings` — clean
- [x] `cargo fmt --check` — clean
- [x] **Self-scan progression** (cumulative):
- baseline: 12 findings (1 Critical UnboundedAlloc, 2 InsecureProtocol
FPs)
- after #51: 11 findings (Critical resolved)
- after #52: 11 findings (doc-comment InsecureProtocol FP resolved;
JSON-LD literal FP remained)
- **after this PR: 10 findings (last InsecureProtocol FP resolved)**
All 10 remaining findings are intentional (test unwraps,
`examples/vulnerable_program.rs` unsafe blocks, scaffold `flake.nix`,
etc.).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent ff3552e commit 016791c
1 file changed
Lines changed: 101 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
242 | 242 | | |
243 | 243 | | |
244 | 244 | | |
| 245 | + | |
245 | 246 | | |
246 | 247 | | |
247 | 248 | | |
| |||
4747 | 4748 | | |
4748 | 4749 | | |
4749 | 4750 | | |
| 4751 | + | |
| 4752 | + | |
| 4753 | + | |
| 4754 | + | |
| 4755 | + | |
| 4756 | + | |
| 4757 | + | |
| 4758 | + | |
| 4759 | + | |
| 4760 | + | |
| 4761 | + | |
| 4762 | + | |
| 4763 | + | |
| 4764 | + | |
| 4765 | + | |
| 4766 | + | |
| 4767 | + | |
| 4768 | + | |
| 4769 | + | |
4750 | 4770 | | |
4751 | 4771 | | |
4752 | | - | |
| 4772 | + | |
| 4773 | + | |
| 4774 | + | |
| 4775 | + | |
4753 | 4776 | | |
4754 | 4777 | | |
4755 | 4778 | | |
| |||
5942 | 5965 | | |
5943 | 5966 | | |
5944 | 5967 | | |
| 5968 | + | |
| 5969 | + | |
| 5970 | + | |
| 5971 | + | |
| 5972 | + | |
| 5973 | + | |
| 5974 | + | |
| 5975 | + | |
| 5976 | + | |
| 5977 | + | |
| 5978 | + | |
| 5979 | + | |
| 5980 | + | |
| 5981 | + | |
| 5982 | + | |
| 5983 | + | |
| 5984 | + | |
| 5985 | + | |
| 5986 | + | |
| 5987 | + | |
| 5988 | + | |
| 5989 | + | |
| 5990 | + | |
| 5991 | + | |
| 5992 | + | |
| 5993 | + | |
| 5994 | + | |
| 5995 | + | |
| 5996 | + | |
| 5997 | + | |
| 5998 | + | |
| 5999 | + | |
| 6000 | + | |
| 6001 | + | |
| 6002 | + | |
| 6003 | + | |
| 6004 | + | |
| 6005 | + | |
| 6006 | + | |
| 6007 | + | |
| 6008 | + | |
| 6009 | + | |
| 6010 | + | |
| 6011 | + | |
| 6012 | + | |
| 6013 | + | |
| 6014 | + | |
| 6015 | + | |
| 6016 | + | |
| 6017 | + | |
| 6018 | + | |
| 6019 | + | |
| 6020 | + | |
| 6021 | + | |
| 6022 | + | |
| 6023 | + | |
| 6024 | + | |
| 6025 | + | |
| 6026 | + | |
| 6027 | + | |
| 6028 | + | |
| 6029 | + | |
| 6030 | + | |
| 6031 | + | |
| 6032 | + | |
| 6033 | + | |
| 6034 | + | |
| 6035 | + | |
| 6036 | + | |
| 6037 | + | |
| 6038 | + | |
| 6039 | + | |
| 6040 | + | |
| 6041 | + | |
| 6042 | + | |
| 6043 | + | |
| 6044 | + | |
5945 | 6045 | | |
5946 | 6046 | | |
5947 | 6047 | | |
| |||
0 commit comments