Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
334bb96
Add cfgaudit → AVE crosswalk (static config-auditor) (#67)
predictor2718 Jul 23, 2026
f4d9b4e
docs: scaling and governance policy (#80)
chaksaray Jul 27, 2026
0ce799e
docs: cross-reference scaling-and-governance.md in README (#83)
chaksaray Jul 28, 2026
a367da6
docs: cross-reference scaling-and-governance.md in CLAUDE.md (#82)
chaksaray Jul 28, 2026
79406d0
docs: cross-reference scaling-and-governance.md in CONTEXT.md (#84)
chaksaray Jul 28, 2026
798a9c6
docs: cross-reference scaling-and-governance.md in CONTRIBUTING.md (#85)
chaksaray Jul 28, 2026
43928ee
docs: cross-reference scaling-and-governance.md in GOVERNANCE.md (#86)
chaksaray Jul 28, 2026
ad2ecf2
docs: add status glossary entry, cross-referencing scaling-and-govern…
chaksaray Jul 28, 2026
e94a8de
docs: CHANGELOG entry for scaling-and-governance.md (#88)
chaksaray Jul 28, 2026
8fcc70b
docs: cross-reference scaling-and-governance.md in ARCHITECTURE.md (#89)
chaksaray Jul 28, 2026
86a2a71
feat: validate records and update skills (#91)
chaksaray Jul 28, 2026
a699f5e
fix add ave record skill
chaksaray Jul 28, 2026
5b2b340
feat: AVE-2026-00060 through 00064 -- five new records from policy/co…
chaksaray Jul 28, 2026
fbbb422
Merge remote-tracking branch 'origin/main' into develop
chaksaray Jul 28, 2026
0cedb18
chore: regenerate consolidated records JSON
chaksaray Jul 28, 2026
f4cc426
feat: AVE-2026-00065 -- A2A agent card poisoning via embedded adversa…
chaksaray Jul 29, 2026
c9dce1e
Merge remote-tracking branch 'origin/main' into develop
chaksaray Jul 29, 2026
445a178
fix: stale piranha.bawbel.io reference in README (#99)
chaksaray Jul 31, 2026
a08240e
docs: add researcher-process.md (#101)
chaksaray Jul 31, 2026
8955456
chore: add ave gap diagram (#107)
chaksaray Jul 31, 2026
e1fe630
fix: GOVERNANCE.md deprecation_reason field claim (#106)
chaksaray Jul 31, 2026
2789ac1
docs: add API link and gap diagram to README (#108)
chaksaray Jul 31, 2026
e5953c6
Change image width to 100% in README
chaksaray Jul 31, 2026
b464ed9
docs: link AVE-2026-00046 writeup from its own record (#111)
chaksaray Aug 2, 2026
d8861a5
feat: AVE-2026-00066 -- hallucinated skill-name squatting (HalluSquat…
chaksaray Aug 3, 2026
46fc1ce
feat: AVE-2026-00067 -- skill composition trust transfer (SCR-TrustLi…
chaksaray Aug 3, 2026
c302152
feat: AVE-2026-00068 -- CLI command composition risk (MOSAIC) (#115)
chaksaray Aug 3, 2026
270a263
feat: AVE-2026-00069 -- multimodal image-hidden instructions (SkillCa…
chaksaray Aug 3, 2026
34a692f
feat: AVE-2026-00070 -- distributed cross-agent backdoor fragments (C…
chaksaray Aug 3, 2026
211f71c
Merge remote-tracking branch 'origin/main' into develop
chaksaray Aug 3, 2026
8e7b0e4
docs: collapsible record index (#119)
chaksaray Aug 3, 2026
375e853
Merge remote-tracking branch 'origin/main' into develop
chaksaray Aug 3, 2026
d2e597a
Merge remote-tracking branch 'origin/main' into develop
chaksaray Aug 6, 2026
0f79df3
feat: AVE-2026-00071 -- MCP daemon redirect (container posture) (#128)
chaksaray Aug 6, 2026
ccb716a
feat: AVE-2026-00072 -- MCP server bound to all interfaces (NeighborJ…
chaksaray Aug 6, 2026
66f821e
feat: AVE-2026-00073 -- telemetry/endpoint redirect via static config…
chaksaray Aug 6, 2026
16b459e
Merge remote-tracking branch 'origin/main' into develop
chaksaray Aug 6, 2026
9fa75bb
fix: pytest tests/ (CI's actual invocation) fails to collect tests/te…
chaksaray Aug 6, 2026
dfc9846
Remove 'Bawbel' reference from README (#134)
chaksaray Aug 6, 2026
3032813
feat: AVE-2026-00074 -- reclaimable dead external anchor (SkillJackin…
chaksaray Aug 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ Format: [Semantic Versioning](https://semver.org). Schema versions and record se
## [Unreleased]

### Added
- AVE-2026-00074: reclaimable dead external anchor (SkillJacking) — a
skill references a GitHub owner, package, domain, or cloud subdomain
that was live when authored and has since been deleted or expired,
making it re-registerable by an attacker with no change to the
skill's own content; distinct from AVE-2026-00062 (absence of pinning
at declaration time), this is a previously-valid reference decaying
after the fact. Sourced from repo-forensics' scan_dead_anchors.py and
AIR's SkillJacking disclosure (925 skills / ~134,000 agents on
hijackable dependencies) (HIGH, AIVSS 7.1)
- AVE-2026-00073: telemetry/endpoint redirect via static configuration —
a committed config value (OTEL_EXPORTER_OTLP_ENDPOINT,
ANTHROPIC_BASE_URL/CVE-2026-21852, or a cleartext model/provider base
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Stable IDs, AIVSS scores, and behavioral fingerprints for every way a skill file
MCP server, system prompt, or agent plugin can be weaponized — scored consistently,
mapped to the frameworks security teams already report against.

[![Records](https://img.shields.io/badge/records-73-0f6e56?style=flat-square)](records/)
[![Records](https://img.shields.io/badge/records-74-0f6e56?style=flat-square)](records/)
[![Schema](https://img.shields.io/badge/schema-v1.1.0-0a3024?style=flat-square)](schema/ave-record-1.1.0.schema.json)
[![AIVSS](https://img.shields.io/badge/AIVSS-v0.8-d4a017?style=flat-square)](https://aivss.owasp.org)
[![OWASP MCP](https://img.shields.io/badge/OWASP-MCP%20Top%2010-0a3024?style=flat-square)](https://owasp.org)
Expand Down Expand Up @@ -59,7 +59,7 @@ reference implementation. Any tool can map to it — see the
```
Your CI pipeline scans dependencies for known package vulnerabilities.
It does not scan your SKILL.md for prompt injection.
AVE + Bawbel fixes that.
AVE fixes that.
```

<p align="center">
Expand Down Expand Up @@ -99,7 +99,7 @@ skill file -> in CI / pre-commit -> before deploy

| | |
|---|---|
| Total records | 73 |
| Total records | 74 |
| Schema version | 1.1.0 |
| AIVSS spec | v0.8 |
| CRITICAL (>= 9.0) | 1 |
Expand Down Expand Up @@ -167,7 +167,7 @@ AIVSS = ((8.5 + 7.5) / 2) x 1.0 x 1 = 8.0 -> HIGH
## Record index

<details>
<summary><strong>73 records, click to expand</strong></summary>
<summary><strong>74 records, click to expand</strong></summary>

| AVE ID | Title | AIVSS | Severity |
|---|---|---|---|
Expand Down Expand Up @@ -244,6 +244,7 @@ AIVSS = ((8.5 + 7.5) / 2) x 1.0 x 1 = 8.0 -> HIGH
| [AVE-2026-00071](records/AVE-2026-00071.json) | MCP Daemon Redirect (Container Posture) | 5.6 | MEDIUM |
| [AVE-2026-00072](records/AVE-2026-00072.json) | MCP Server Bound to All Interfaces (NeighborJack) | 5.0 | MEDIUM |
| [AVE-2026-00073](records/AVE-2026-00073.json) | Telemetry/Endpoint Redirect via Static Configuration | 4.1 | MEDIUM |
| [AVE-2026-00074](records/AVE-2026-00074.json) | Reclaimable Dead External Anchor (SkillJacking) | 7.1 | HIGH |

</details>

Expand Down
131 changes: 131 additions & 0 deletions dist/ave-records-latest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2094,6 +2094,137 @@
"credential-exfiltration"
]
},
{
"ave_id": "AVE-2026-00074",
"schema_version": "1.1.0",
"status": "active",
"component_type": "skill",
"title": "Reclaimable dead external anchor (GitHub owner, package, domain, or cloud subdomain) referenced by a skill",
"attack_class": "Supply Chain - Dead Anchor Reclamation (SkillJacking)",
"severity": "HIGH",
"description": "A skill references an external anchor -- a GitHub owner/repo, a package name in an install instruction, a bare domain, or a free-tier cloud subdomain -- that was live and under its original owner's control at the time the skill was authored, but has since been deleted, renamed, or allowed to expire. Because the anchor is now unclaimed, an attacker can register the exact same name and take control of everything the skill points at, without a single byte of the skill's own committed content changing. Distinct from AVE-2026-00062 (unpinned dependency substitution): that record's mechanism is the absence of a pin from the moment a reference was declared, a mutable specifier resolvable to more than one artifact by design. Here the reference may have been fully precise and stable when written -- a specific GitHub username, an exact package name, a specific domain -- pinning it would not have helped, because the vulnerability is not an unresolved reference, it is a previously-resolved one whose target identity changed out from under it after publication. AIR's disclosed SkillJacking research found 925 skills serving roughly 134,000 agents sitting on this exact class of hijackable dependency, including a real takeover: the seedance2-api video-generation skill (11,483 installs, top ~3% of its marketplace) was fully hijacked by re-registering its deleted GitHub owner account, handing the attacker control over what every installing agent would execute with no change to the skill itself.",
"affected_platforms": [
"claude-code",
"cursor",
"codex",
"any-agent-or-skill-referencing-external-github-package-domain-or-cloud-targets"
],
"affected_registries": [
"clawhub.io",
"smithery.ai",
"agentskills.io",
"skills.sh"
],
"aivss_score": 7.1,
"cvss_base_vector": "CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"owasp_mcp": [
"MCP04"
],
"owasp_asi": [
"ASI04"
],
"mitre_atlas": [],
"nist_ai_rmf": [],
"behavioral_fingerprint": "A skill's committed content (documentation, manifest, or install instructions) references an external GitHub owner/repo, installable package name, bare domain, or cloud subdomain that currently returns a not-found, unregistered, or deleted-account state from the relevant authority (GitHub's own user API, a package registry, domain RDAP, or a cloud provider's app-slug check), meaning the anchor is presently re-registerable by any third party even though it was a legitimate, resolvable target when the skill was authored.",
"behavioral_vector": [
"dead-anchor-reclamation",
"repojacking",
"trust-anchor-confusion",
"claimable-external-identity"
],
"provenance_vector": {
"entry_class": "content",
"payload_surface": "a GitHub owner/repo, install-command package name, bare domain, or cloud subdomain referenced in the skill's documentation, manifest, or install instructions, naming an external identity that is presently unclaimed"
},
"trifecta_profile": {
"requires": [
"external_comms"
]
},
"mitigation": {
"strategy": [
"verify_identity",
"pin_integrity"
],
"enforcement_point": "static_scan",
"trifecta_control": "break_external_comms"
},
"example_patterns": [
"SKILL.md: 'Install with: pip install totally-real-helper-lib' -- totally-real-helper-lib returns 404 on PyPI, never published or since removed",
"README.md: 'Maintained by github.com/former-owner, see the full source there' -- github.com/users/former-owner returns 404 (deleted or renamed), the username is free to re-register",
"manifest.json: {\"docs\": \"https://old-project-name.example.com\"} -- old-project-name.example.com is unregistered/expired per RDAP",
"SKILL.md: 'Live demo: https://my-old-app.vercel.app' -- the Vercel app was deleted, the subdomain slug is free to reclaim"
],
"mutation_count": 0,
"detection_methodology": "1. Extract every external anchor referenced anywhere in the skill's committed content: GitHub owner/repo mentions, package names in prose install commands, bare domains, and free-tier cloud subdomains. 2. Probe each anchor's live current state against its authoritative source: GitHub's users API for owners, the relevant package registry (npm, PyPI) for packages, RDAP for domains, and provider-specific fingerprints for cloud subdomains (NXDOMAIN or a 'deleted app' landing page). 3. Classify each anchor as confirmed-claimable (the authoritative check returns not-found/deleted/unregistered), live-and-owned (the anchor resolves normally), or couldn't-check (network failure or ambiguous response) -- only the first tier produces a finding, and a failed check must degrade to silence, never to a false claim of compromise. 4. Re-verify anchors periodically rather than once, since the target class is defined by anchors that were valid when last checked and may decay at any later point.",
"indicators_of_compromise": [
"A referenced GitHub username or organization returning HTTP 404 from api.github.com/users, indicating deletion or rename and re-registerability",
"A package name referenced only in prose install instructions returning a registry 404 (never published, or removed after publication)",
"A referenced bare domain returning an unregistered or expired state via RDAP lookup",
"A referenced cloud-provider subdomain returning NXDOMAIN or a provider's own 'this app has been deleted' landing page",
"The resolved target of a previously-stable external reference differing from what it resolved to at the skill's original publication, with no corresponding change to the skill's own committed content"
],
"remediation": "Do not treat a specific, well-formed external reference as permanently safe once reviewed; periodically re-verify that referenced GitHub owners, packages, domains, and cloud subdomains still resolve to their original, reviewed owner before trusting content fetched or installed from them. Where feasible, pin to a content hash or commit SHA rather than a mutable owner/name, and treat any pre-install or pre-fetch step that resolves an external anchor as a point requiring a fresh trust check, not a one-time review at publication time. Registries hosting skills should periodically re-scan published skills for anchor decay rather than only screening at submission.",
"kill_switch_active": false,
"researcher": "Saray Chak",
"researcher_url": "https://bawbel.io",
"published": "2026-08-07T00:00:00Z",
"last_updated": "2026-08-07T00:00:00Z",
"references": [
{
"tag": "repo-forensics dead-anchor scanner",
"text": "alexgreensh/repo-forensics, skills/repo-forensics/scripts/scan_dead_anchors.py -- extracts every external anchor a skill/repo points at (GitHub owner/repo, prose package-install target, bare domain, free-tier cloud subdomain) and probes whether it is currently confirmed-claimable, live-and-owned, or unverifiable, emitting a CRITICAL/MEDIUM/HIGH finding per anchor type only on a confirmed-claimable verdict (see _handle_github, _handle_anchor).",
"url": "https://github.com/alexgreensh/repo-forensics/blob/main/skills/repo-forensics/scripts/scan_dead_anchors.py"
},
{
"tag": "AIR SkillJacking disclosure",
"text": "Or Nevo, Dor Granat, Eliad Mualem, AIR Security, 'SkillJacking' (2026-07-02). Discloses 925 skills serving ~134,000 agents sitting on instantly hijackable dependencies (deleted GitHub accounts, unregistered packages, expired domains, freed cloud-app slots), including a confirmed takeover of the seedance2-api skill (11,483 installs) via re-registering its deleted GitHub owner account.",
"url": "https://www.air.security/blog-posts/skilljacking"
},
{
"tag": "CWE-829",
"text": "CWE-829: Inclusion of Functionality from Untrusted Control Sphere - MITRE Common Weakness Enumeration",
"url": "https://cwe.mitre.org/data/definitions/829.html"
},
{
"tag": "AVE Registry",
"text": "AVE-2026-00074 - AVE behavioral vulnerability registry",
"url": "https://github.com/aveproject/ave/blob/main/records/AVE-2026-00074.json"
}
],
"aivss": {
"cvss_base": 8.7,
"aarf": {
"autonomy": 1,
"tool_use": 1,
"multi_agent": 0,
"non_determinism": 0.5,
"self_modification": 0,
"dynamic_identity": 1,
"persistent_memory": 0,
"natural_language_input": 0,
"data_access": 1,
"external_dependencies": 1
},
"aars": 5.5,
"thm": 1,
"mitigation_factor": 1,
"aivss_score": 7.1,
"aivss_severity": "HIGH",
"spec_version": "0.8",
"notes": "dynamic_identity scored at genuine maximum (1.0): this class is definitionally trust-anchor confusion, an attacker assumes the exact external identity (GitHub owner, package name, domain, cloud slug) the skill's original review trusted. natural_language_input scored 0: detection and exploitation both turn on live registry/DNS/RDAP state, not on persuading a reader or a model. mitigation_factor left at 1 (no discount): unlike AVE-2026-00062's pinning fix, there is no simple one-time mitigation here, closing this class requires ongoing re-verification of external anchors over time, not a fix applied once at review. mitre_atlas researched and left as an empty array rather than force-fit: AML.T0010.001 (AI Software) names compromising a legitimate package's build/maintainer access, namesquatting, and hallucinated package names as its supply-chain sub-cases, and AML.T0109 (AI Supply Chain Rug Pull) names an original owner deliberately turning malicious; none of these name an attacker legitimately re-registering an identity the original owner abandoned, a genuine, confirmed gap in ATLAS's own taxonomy, not a research shortfall. owasp_asi ASI04 (Supply chain risks) verified against OWASP's own 2026 Top 10 for Agentic Applications list rather than inferred from corpus usage."
},
"evidence_kind_default": "behavioral_pattern",
"detection_stage": "static_detection",
"detection_layer": "content",
"confidence_baseline": 0.85,
"evidence_basis_engines": [
"pattern"
],
"derivable_into": [
"remote-control-chain"
]
},
{
"ave_id": "AVE-2026-00003",
"schema_version": "1.1.0",
Expand Down
4 changes: 2 additions & 2 deletions dist/ave-records-latest.manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema_version": "1.1.0",
"record_count": 73,
"generated_at": "2026-08-06T22:04:28.358Z",
"record_count": 74,
"generated_at": "2026-08-06T23:37:14.101Z",
"source": "https://github.com/aveproject/ave"
}
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,10 @@ packages = []

[tool.pytest.ini_options]
testpaths = ["tests"]
# tests/test_validate_data.py imports "from scripts import validate_records".
# scripts/ has no __init__.py (deliberately, per the packages = [] note above),
# and bare `pytest` (CI's actual invocation, see .github/workflows/tests.yml)
# does not insert the repo root onto sys.path the way `python -m pytest` does.
# Without this, the import resolves under `python -m pytest` locally but
# fails collection under CI's plain `pytest` invocation.
pythonpath = ["."]
Loading
Loading