Skip to content

[SECURITY] apc mcp sync writes resolved secrets to plaintext tool config files #32

@FZ2000

Description

@FZ2000

Severity: P3

Summary

While apc collect correctly redacts secrets from the APC cache and stores them in the OS keychain, apc mcp sync resolves those secrets and writes them back to disk in plaintext inside tool-specific config files (e.g. ~/.claude.json, ~/.cursor/mcp.json). This is functionally necessary, but the security implication is undocumented and may surprise users.

Affected Code

src/appliers/claude.py — apply_mcp_servers():

env = server.get("env", {}).copy()
for key, value in env.items():
    if isinstance(value, str) and value.startswith("${"): 
        secret_name = value[2:-1]
        if secret_name in secrets:
            env[key] = secrets[secret_name]   # plaintext secret injected

mcp_servers[name] = { ... "env": env }       # written to ~/.claude.json
_claude_json().write_text(json.dumps(data, indent=2), ...)

Security Model Gap

Stage Secret state
apc collect Redacted to ${PLACEHOLDER} in APC cache; stored in OS keychain
apc mcp sync Resolved from keychain → written in plaintext to tool config
apc export Read from keychain → age-encrypted in export archive

The keychain protection is bypassed after every sync. If the tool's config file is:

  • Included in a git commit by accident
  • Readable by other processes/users
  • Backed up to iCloud/Dropbox without encryption

...the secrets are exposed.

Recommended Mitigations

  1. Document this behavior clearly in apc mcp sync help text and README
  2. Warn the user during sync that secrets will be written plaintext:
    ⚠ Resolving 3 secrets from keychain → writing to ~/.claude.json (plaintext)
    
  3. Long-term: Explore if tools support referencing environment variables so secrets stay out of config files entirely
  4. Add a note to the export command that the export encrypts secrets, but the on-disk tool configs do not

References

  • CWE-312: Cleartext Storage of Sensitive Information

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity vulnerability

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions