Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save YLChen-007/caf38652afeccbbd53a9d77152b6198d to your computer and use it in GitHub Desktop.

Select an option

Save YLChen-007/caf38652afeccbbd53a9d77152b6198d to your computer and use it in GitHub Desktop.
Authentication Bypass via Insecure Credential Pool Synchronization during Anthropic Exhaustion

Advisory Details

Title: Authentication Bypass via Insecure Credential Pool Synchronization during Anthropic Exhaustion

Description:

Summary

An authorization bypass vulnerability exists in the CredentialPool of the hermes-agent caused by insecure synchronization with a global credentials file (~/.claude/.credentials.json). When the agent encounters a rate limit (HTTP 429) using Anthropic claude_code credentials, it marks the current entry as exhausted. During the subsequent rotation to select a new token, the pool automatically checks if exhausted tokens have updated credentials in the local .claude config file. Because this applies to any exhausted token from the claude_code source regardless of user boundary, the singleton credentials file will overwrite every distinct pool entry as they each face exhaustion, causing all isolated accounts to merge into a single identity. This breaks multi-account credential pooling and leads to rate limit cascading across all pool credentials, similar to a previous Codex vulnerability (#11364).

Details

The vulnerability lies within agent/credential_pool.py. When multiple Anthropic accounts are configured in auth.json with source: claude_code to distribute loads and circumvent rate limits, the token pool manager attempts to track them securely. However, if a token encounters an exhaustion error (e.g. HTTP 429), mark_exhausted_and_rotate() marks the current token as exhausted and clears the active selection. When the system selects the next credential by calling self._available_entries(), the method includes an insecure syncing mechanism for exhausted credentials:

if (self.provider == "anthropic" and entry.source == "claude_code"
        and entry.last_status == STATUS_EXHAUSTED):
    synced = self._sync_anthropic_entry_from_credentials_file(entry)

The method _sync_anthropic_entry_from_credentials_file() blind-reads the global ~/.claude/.credentials.json and overrides the pool entry if the refreshToken differs. Since this happens symmetrically for all entries in the pool as they individually encounter exhaustion, every single distinct account token in the pool will gradually be clobbered by whatever token is currently sitting in ~/.claude/.credentials.json.

PoC

Prerequisites

  • Python 3.10+
  • The poc_anthropic_sync.py script downloaded.
  • Tested locally by mimicking the CLI's handling of auth.json rotation and selection cycles.

Reproduction Steps

  1. Download the PoC server script from: https://gist.github.com/YLChen-007/5fcaf1ee5120a6f04c11addb1e3ff4c5

  2. Set the script to target a local installation of the hermes-agent framework by ensuring sys.path.insert(0, "/root/llm-agent-project/hermes-agent") references paths correctly.

  3. Run the PoC: python poc_anthropic_sync.py

  4. The PoC spins up a fake multi-credential auth.json containing token-acc-1, token-acc-2, and token-acc-3, and injects a single HACKED_SINGLE_ACCESS_TOKEN into the mocked .claude/.credentials.json.

  5. The PoC runs 10 cycles of pool.select() followed by an exhaustion event pool.mark_exhausted_and_rotate(status_code=429) to mimic the rate-limit failure of each token.

  6. The exploit verifies the resulting tokens in the auth.json.

Log of Evidence

[*] Verifying pre-exploit state.
[*] Pre-exploit tokens: ['token-acc-1', 'token-acc-2', 'token-acc-3']
[*] Triggering pool rotation (exhaustion mock).
[!] Access Tokens in pool: ['HACKED_SINGLE_ACCESS_TOKEN', 'HACKED_SINGLE_ACCESS_TOKEN', 'HACKED_SINGLE_ACCESS_TOKEN']
[SUCCESS] All pool entries were overwritten with the singleton token!

Impact

  • Type: Information Leakage / Authentication Bypass (via Session Overwrite)
  • Impact Flow: By overwriting the multi-tenant or multi-account credentials pooled in auth.json with the singleton file contents from ~/.claude/.credentials.json, isolated authorization boundaries are breached. This completely negates the failover and rate-limit bypassing functions, creating an Authorization Bypass variant where operations expected to be executed across diverse authorized sessions collapse into a single identity representation.

Affected products

  • Ecosystem: python
  • Package name: hermes-agent
  • Affected versions: <= v2026.4.23
  • Patched versions:

Severity

  • Severity: High
  • Vector string: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L

Weaknesses

  • CWE: CWE-287: Improper Authentication
  • CWE: CWE-668: Exposure of Resource to Wrong Sphere

Occurrences

Permalink Description
https://github.com/NousResearch/hermes-agent/blob/main/agent/credential_pool.py#L512-L544 The vulnerable _sync_anthropic_entry_from_credentials_file method reading from a single shared configuration rather than scoped multi-tenant secrets.
https://github.com/NousResearch/hermes-agent/blob/main/agent/credential_pool.py#L559-L564 The method evaluation point in _available_entries dynamically overwriting internal records during status checks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment