Repository navigation
fix(osv): one malware predicate (MAL- id/alias or CWE-506), with the CWE ids stored (parity decision 1) - #992
Merged
Merged
Conversation
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
…depengine::is_malware); crossenv vector on contains_malware now calls fourda_depengine::is_malware over each match's (advisory_id, aliases, cwe_ids): a MAL- id or alias, or CWE-506 in database_specific.cwe_ids. The local MAL-only predicate is deleted. Stacked on fix/malware-cwe (#992), which stores cwe_ids; this lands after it. sv-021: crossenv GHSA-c2m4-w5hm-vqjw (live OSV 2026-10-18: aliases [CVE-2017-16074], cwe_ids [CWE-506], own label HIGH) on the installed 1.0.1 is Critical, its severity its own high. The vector checker reads database_specific.cwe_ids as osv::sync stores it. Knowledge Gaps reads the cwe_ids column with the rows it grades. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
runyourempire
force-pushed
the
fix/malware-cwe
branch
from
October 18, 2026 14:32
8f21fca to
b18f364
Compare
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
…t stores the CWEs (review of #992) B1: is_malware(id, aliases, cwe_ids, summary) gains a third rule: the summary starts with GitHub's malware advisory title template, "Malicious Package in " or "Malicious code in " (case-insensitive, anchored). Some GitHub malware records carry neither a MAL- alias nor a CWE: GHSA-28f8-hqmc-7ph8 ("Malicious Package in ember-power-timepicker", aliases [], cwe_ids []). Prose that merely mentions malice elsewhere is not read. The release gate's summary test is restored and the record is pinned; every caller (parent releases, the release gate, StoredAdvisory, MatchedAdvisory, the rule vectors) passes the summary. Preemption: an unrated advisory's urgency reads the shared predicate (High) instead of a MAL- id prefix only. Migration: the column is added with add_column_if_missing, and the sync is made due by setting last_synced_at back exactly the max age (osv_sync_max_age_hours), not to 1970. The sync stores cwe_ids in its one upsert (upsert_osv_advisory_record; COALESCE like the aliases) instead of a second UPDATE. malware.rs no longer claims "both engines": it names the MCP server as the mirror of the same three rules. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 18, 2026
…WE ids stored `fourda_depengine::is_malware(id, aliases, cwe_ids)`: a malicious-package record is an OSV `MAL-` id or alias, or carries CWE-506 in database_specific.cwe_ids. GitHub's malware advisories often have no `MAL-` alias: crossenv GHSA-c2m4-w5hm-vqjw ("crossenv is malware") has aliases ["CVE-2017-16074"] and cwe_ids ["CWE-506"] (live 2026-10-18), so the parent-release predicate read it as an unfixed ordinary advisory. No summary keyword is read (the release gate's "Malicious code in" prefix check is replaced by the shared rule). Phase 128 adds osv_advisories.cwe_ids (additive; schema 128, so a 127 binary refuses the database through the existing too-new guard) and makes every ecosystem's advisory sync due, so rows stored before it are re-upserted with their CWE ids on the next cycle instead of staying NULL. The sync stores database_specific.cwe_ids; StoredAdvisory and MatchedAdvisory carry them. Wired where MAL- was matched: the parent-release Advisory (osv/parent_release.rs) and the release gate (osv/release_advisories.rs). Severity is left to #986. No new egress. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7
…t stores the CWEs (review of #992) B1: is_malware(id, aliases, cwe_ids, summary) gains a third rule: the summary starts with GitHub's malware advisory title template, "Malicious Package in " or "Malicious code in " (case-insensitive, anchored). Some GitHub malware records carry neither a MAL- alias nor a CWE: GHSA-28f8-hqmc-7ph8 ("Malicious Package in ember-power-timepicker", aliases [], cwe_ids []). Prose that merely mentions malice elsewhere is not read. The release gate's summary test is restored and the record is pinned; every caller (parent releases, the release gate, StoredAdvisory, MatchedAdvisory, the rule vectors) passes the summary. Preemption: an unrated advisory's urgency reads the shared predicate (High) instead of a MAL- id prefix only. Migration: the column is added with add_column_if_missing, and the sync is made due by setting last_synced_at back exactly the max age (osv_sync_max_age_hours), not to 1970. The sync stores cwe_ids in its one upsert (upsert_osv_advisory_record; COALESCE like the aliases) instead of a second UPDATE. malware.rs no longer claims "both engines": it names the MCP server as the mirror of the same three rules. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7
…ge of #988 and #992) #988 landed a stack_change test that builds an AdvisoryWindow literal before #992 added the cwe_ids field, so the merge-queue build failed with E0063. Same fixture, empty CWE list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7
runyourempire
force-pushed
the
fix/malware-cwe
branch
from
October 18, 2026 14:59
b18f364 to
a86529d
Compare
runyourempire
enabled auto-merge
October 18, 2026 15:00
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
…depengine::is_malware); crossenv vector on contains_malware now calls fourda_depengine::is_malware over each match's (advisory_id, aliases, cwe_ids): a MAL- id or alias, or CWE-506 in database_specific.cwe_ids. The local MAL-only predicate is deleted. Stacked on fix/malware-cwe (#992), which stores cwe_ids; this lands after it. sv-021: crossenv GHSA-c2m4-w5hm-vqjw (live OSV 2026-10-18: aliases [CVE-2017-16074], cwe_ids [CWE-506], own label HIGH) on the installed 1.0.1 is Critical, its severity its own high. The vector checker reads database_specific.cwe_ids as osv::sync stores it. Knowledge Gaps reads the cwe_ids column with the rows it grades. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
runyourempire
added a commit
that referenced
this pull request
Oct 18, 2026
…edAdvisory::is_malware); sv-022 title-only malware contains_malware calls MatchedAdvisory::is_malware, the merged fourda_depengine::is_malware(id, aliases, cwe_ids, summary): a MAL- id or alias, CWE-506, or GitHub's "Malicious Package in" / "Malicious code in" title. #992's unrated-malware test now pins Critical on the alert path (most_urgent_tier) instead of the deleted summary heuristic. sv-022: GHSA-28f8-hqmc-7ph8 "Malicious Package in ember-power-timepicker" (live OSV 2026-10-19: no aliases, cwe_ids [], own label CRITICAL, versions [1.0.8]) installed is Critical; a unit test pins the title arm beside a low own grade. Restores a closing brace the rebase dropped in briefing_deterministic_tests.rs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KSXWNneouUjTiVV3Rc3FH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Parity decision 1. This adds ONE malware predicate for every reader in this app, and stores the data it needs. The MCP server (
@4da/mcp-server) must implement the same three rules; the depengine tests are the contract it mirrors. This PR does not export the function to the MCP.fourda_depengine::is_malware(id: &str, aliases: &[String], cwe_ids: &[String], summary: &str) -> bool. It is pure; the wasm build has zero imports andcheck-wasm.cjspasses. A record is malware when ANY of these holds:MAL-id.database_specific.cwe_ids. Example: crossenv GHSA-c2m4-w5hm-vqjw ("crossenv is malware") has aliases["CVE-2017-16074"],cwe_ids: ["CWE-506"]and noMAL-alias (live, 2026-10-18).Malicious Package inorMalicious code in(case-insensitive, anchored at the start). Example: GHSA-28f8-hqmc-7ph8 ("Malicious Package in ember-power-timepicker") hasaliases: []andcwe_ids: []. GitHub generates this template; it is not prose. A summary that mentions "malicious" anywhere else does not match, and the tests cover that.osv_advisories.cwe_ids TEXT(a JSON array), added with theadd_column_if_missinghelper.TARGET_VERSIONis now 128 andcontract/app-schema.sqlis regenerated.SCHEMA_TOO_NEW_PHRASE, whichstate.rs::is_schema_newer_than_binaryroutes away from the corrupt-database fallback). Rebuild fourda and fourda-engine together after merge.osv_sync_status.last_synced_atback to exactlydatetime('now', '-<osv_sync_max_age_hours> hours'), soneeds_syncis true on the next cycle. It does not set 1970, so every surface that shows the last sync time still shows a plausible one. That sync re-upserts every row, and rows written before the migration get their CWE ids.store_vulnerabilitystoresdatabase_specific.cwe_idsin its single upsert (Database::upsert_osv_advisory_record, whichupsert_osv_advisory_with_metanow wraps). On conflict it usesCOALESCE, the same as the aliases.StoredAdvisoryandMatchedAdvisorycarrycwe_ids, and theiris_malware()calls the shared function.Advisory::new(osv/parent_release.rs);AdvisoryWindow::is_malware(osv/release_advisories.rs). Its earlier unanchored summary check ("starts with malicious") is replaced by the anchored template;infer_urgency_from_summary(used only when an advisory has no severity): a record that matches the shared predicate is High. Before, only an id starting withmal-was.osv/severity.rscontains_malware) belongs to fix(severity): one grade per advisory, inherited from GHSA aliases when unrated; one tier for unknown #986. Whichever PR lands second switches it tois_malware.Upgrade window (disclosed)
Until the first sync after the upgrade, a stored row has
cwe_idsNULL. During that window, a malware record identified only by its CWE reads as non-malware. An example is GHSA-hxxf-q3w9-4xgw (eslint-scope), whose summary does not match the template. The migration makes that sync due at once, so the window lasts until the next refresh cycle, not 6 hours. Records with aMAL-id or alias, or with the title template, are recognised from the first launch, because those fields are already stored. A record matched only by the template (rule 3) is also read correctly from the first launch, since summaries are already stored.Tests
is_malware:MAL-id, aMAL-alias, and a CWE written with whitespace or lowercase;CWE-1333,CWE-5060andMALWARE-NOTE, plus six pieces of prose that look like the template (Malicious packages can...,foo: Malicious Package in bar,Malicious Packagein baz,...allows malicious code in qux).MAL-id are all High; unrelated prose is Watch.cwe_idson the next sync once the migration's step makes the sync due, and crossenv then reads as malware.cargo test --lib -- osv:: preemption db:: app_schema_contract evidence:: brief_facts scoring::security: 1011 passed, 0 failed. The pre-push gate passed after the rebase ontoc88feb2ae.clippy --lib -D warnings, and the wasm32 release build with 0 imports all pass.cargo clippy --lib -D warningsand rustfmt are clean.🤖 Generated with Claude Code
https://claude.ai/code/session_018hjX3pEMmC7CHfG41PiPj7