crosswalks: refresh cfgaudit to v1.11.0 (53 rules onto 23 classes) - #123
crosswalks: refresh cfgaudit to v1.11.0 (53 rules onto 23 classes)#123predictor2718 wants to merge 2 commits into
Conversation
Follow-up to aveproject#67, and it closes most of what aveproject#68 was tracking. Coverage goes from 35 rules onto 19 classes to 53 onto 23. Most of that is not new cfgaudit rules: five were added in v1.11.0 and three of them map. The other fifteen new mappings are rules that existed all along and now have a home in AVE-2026-00061 through AVE-2026-00064, the four config classes added from this crosswalk's own gap list. 00061 TLS verification disabled CFG075 00062 unpinned dependency CFG010, CFG074, CFG055, CFG089 00063 approval gate bypassed by config CFG003, CFG004, CFG048, CFG053, CFG063, CFG079, CFG087, CFG091, CFG093, CFG096 00064 zero-click project-load auto-run CFG047, CFG067, CFG086 One mapping moved. CFG091 (qwen tools.approvalMode: "yolo") was on AVE-2026-00021, whose text describes "a component that explicitly INSTRUCTS the agent to bypass this confirmation step". It is a setting, not an instruction, and 00063 is explicit that it covers the declarative case "independent of any instruction text". 00021 keeps the instruction-driven rule, CFG029. Four of the eight config surfaces listed at v1.10.0 are therefore closed. The four that remain now carry mechanism-level detail rather than a topic label, which was the specific request in aveproject#68: container posture is three distinct mechanisms with no shared detection logic, MCP network posture is five. Both are surfaces rather than classes, and the daemon redirect and the bind-all case are the highest-value single records if either is picked up. Two shapes are added that have no class in either direction: a cleartext endpoint, which is distinct from TLS verification being disabled, and natural-language steering of an approval classifier, which falls between 00063 (explicitly not instruction text) and 00021 (an instruction to the agent rather than to a gatekeeper). Three gaps added going the other way, classes cfgaudit does not cover: 00060 and 00069 need server source and binary image analysis respectively, and 00065 (A2A agent card poisoning) is reachable only as far as the committed pointer. cfgaudit recognises an inline agent_card_json well enough to classify the file as a remote agent and flags a cleartext agent_card_url or a credential literal beside it, but does not audit the card's contents. Validated against schema/crosswalk-1.0.0.schema.json, every referenced AVE id resolves to a record in this repo, and all 53 pairs match cfgaudit's avemap.go exactly.
|
Read the full diff, not just the summary. Two things worth raising before merge, one confirmed, one needing a quick answer from you. Confirmed: the "what cfgaudit reads" column in the markdown table is populated for the four newest mappings (00061-00064) but empty for every pre-existing row, CFG031 through CFG090 all show a blank fourth cell where real descriptive content used to be ("sensitive-path read, env dump, embedded exfil shell" and similar). Looks like an artifact of the refresh rather than intentional. Worth restoring before merge if it's accidental. Worth confirming: your top-level comment cites 432 real repositories for the v1.11.0 false-positive pass, but the .md gap note for AVE-2026-00036 cites 422 real instruction files for the earlier revert. Could genuinely be two separate passes at different times, that's plausible on its face, just want to confirm rather than assume given how close the two numbers are. Everything else, the CFG091 remap, the two new surfaces, the coverage arithmetic, checks out on direct read. |
Review catch, and it was mine: I regenerated the markdown table from the machine-readable mapping instead of editing it, which had no Notes content, so every pre-existing row lost its fourth cell and only the four new records kept one. The table also silently switched from the short class names to the AVE record titles. Restored the original rows and their notes verbatim, then added only what actually changed: - CFG091 leaves the 00021 row and joins 00063 - CFG097 joins the 00047 row, with its own note - four new rows for 00061 through 00064 The diff against upstream is now two removed lines and five added ones, which is what a mapping refresh should look like.
|
Both correct. The first one is a bug I introduced, fixed in d489609. The empty Notes columnI regenerated the markdown table from the machine-readable mapping rather than editing it, and the JSON has no equivalent of that column, so every pre-existing row lost its fourth cell while the four new records kept one. The table had also silently switched from the short class names to the AVE record titles. Restored the original rows and notes verbatim, then added only what actually changed:
The table diff against main is now two removed lines and five added ones, which is what a mapping refresh should look like. Thanks for reading the diff rather than the summary; a generated table quietly dropping a column is exactly the kind of thing a summary hides. 432 vs 422Two separate passes. Different dates, different units, different purpose. The numbers landing ten apart is coincidence. 422 real instruction files, 2026-07-22, before v1.10.0. Scoped to files containing network-reconnaissance vocabulary, to decide whether that rule could be made precise enough to keep. It could, but only by requiring an internal, private or subnet target: after tightening it fired on 2 of the 422, both genuine 432 real repositories, 2026-08-04, before v1.11.0. Scoped to the ten config surfaces that release added, to measure the false-positive rate of pointing existing rule families at files they had never seen. It found one: Neither pass touches a mapped rule, so neither changes anything in this crosswalk. Happy to put the distinction in the |
|
Checked both gaps you flagged here as "no class in either direction." Cleartext endpoint (no TLS at all): this turned out to already be covered, not a new record. I checked it against Natural-language steering of an approval classifier (Cursor Credited to you and this PR in both records' references. |
…and agent_card_url No score change, no new record. While verifying a candidate from predictor2718's PR #123 (a committed cleartext http:// endpoint for an MCP server URL or agent_card_url), it turned out AVE-2026-00073 already covers this: its detection_methodology and remediation already say to reject cleartext http:// destinations regardless of whether the host is otherwise legitimate. The only gap was textual -- payload_surface and behavioral_fingerprint named a model/provider base URL and telemetry endpoint explicitly but left MCP server URLs and agent_card_url under an implicit "equivalent traffic-destination value" catch-all. Naming them explicitly so a future reader doesn't have to re-derive that they're in scope.
Follow-up to #67, and it closes most of what #68 was tracking.
Coverage
35 rules onto 19 classes → 53 onto 23.
Most of that is not new cfgaudit rules. Five were added in v1.11.0 and three of them map. The other fifteen new mappings are rules that existed all along and now have a home in the four config classes you added from this crosswalk's own gap list:
AVE-2026-00061TLS verification disabledAVE-2026-00062unpinned dependencyAVE-2026-00063approval gate bypassed by configAVE-2026-00064zero-click project-load auto-run00063is doing a lot of work, which I take as a sign it was the right class to add.One mapping moved, on your wording
CFG091(qwentools.approvalMode: "yolo") was onAVE-2026-00021, whose text is "a component that explicitly instructs the agent to bypass this confirmation step". It is a setting, not an instruction, and00063says it covers the declarative case "independent of any instruction text". Moved.00021keeps the instruction-driven rule,CFG029.The two surfaces you were blocked on
Both are now at mechanism level rather than a topic label, matching what I posted in #68.
Container posture is three mechanisms with no shared detection logic: the daemon redirected off-host (
DOCKER_HOST,-H), image trust verification disabled (DOCKER_CONTENT_TRUST=0,--disable-content-trust,--insecure-registry), and a Chromium launcher flag replacing the browser subprocess.MCP network posture is five: bind-all, wildcard CORS escalating when auth is off in the same env, deprecated
sse, a non-loopback proxy, and HTTP transport without log redaction.Neither is one class. If you pick either up, the daemon redirect and the bind-all case are the highest-value single records.
Two shapes with no class in either direction
Added to the surfaces table because they are the honest leftovers:
00061covers verification switched off; this is no TLS at all. A committedhttp://MCP server URL, model base URL, oragent_card_url.autoRun.allow_instructionsis prose the repository feeds to the classifier that decides whether a tool call runs unattended. It falls between00063(explicitly not instruction text) and00021(an instruction to the agent, not to a gatekeeper).Three gaps added going the other way
Classes cfgaudit does not cover, recorded so the crosswalk is honest in both directions:
00060and00069need server source and binary image analysis respectively, the same layer as00052,00053and00024.00065(A2A agent card poisoning) is reachable only as far as the committed pointer. A.gemini/agents/*.mdmay carry an inlineagent_card_json, which cfgaudit recognises well enough to classify the file as a remote agent, but it does not audit the card's contents. It does flag a cleartextagent_card_urland a credential literal in the same file'sauthblock.Validation
crosswalks/cfgaudit-to-ave.jsonvalidates againstschema/crosswalk-1.0.0.schema.jsoncmd/cfgaudit/avemap.goexactly, which is itself drift-guarded on our side by a test that fails if the map and the crosswalk divergedist/ave-records-latest.manifest.json(70 records) and adetection_stagetally (51 static)One note on cfgaudit's side, since it affects nothing here but is the reason the version moved: v1.11.0 shipped after a false-positive pass over 432 real repositories, which changed two rules. Neither is mapped.