Skip to content

deepsec config show prints API key in plaintext with no redaction (regression from legacy CLI) #7

Description

@hollis-png

Summary

deepsec config show prints the entire ~/.deepsec/config.yaml file verbatim, including llm.api_key in plaintext, with no redaction. Anyone running this command (or piping its output anywhere — logs, screen sharing, an AI coding assistant executing it on the user's behalf) gets the raw API key printed to stdout.

Root cause

This looks like a regression from the CLI rewrite. The current implementation in deepsec/cli/app.py:

@config_app.command("show")
def config_show() -> None:
    path = config_path()
    if not path.exists():
        console.print(f"No DeepSec config at {path}. Run `deepsec config init`.")
        return
    console.print(path.read_text(encoding="utf-8"))

(deepsec/cli/app.py:342-348) just does a raw read_text() of the config file and prints it — no field filtering at all.

The legacy CLI (deepsec/spear/legacy_cli/main.py) had proper masking for secret-looking keys, e.g. in config_get (line ~2134-2146):

if isinstance(value, str) and ("key" in key.lower() or "pass" in key.lower()):
    value = value[:8] + "..." if len(value) > 8 else "***"

and even config_set's confirmation message masks the echoed value:

f"[+] Set {key} = {'***' if 'key' in key.lower() or 'pass' in key.lower() else value}"

The new deepsec config subcommand set (init/set/show) doesn't carry this masking logic forward. deepsec/config/cli_constants.py (help text for the old vulnclaw config get) still documents "Secret-looking keys are masked" — but that command/behavior doesn't exist in the current deepsec CLI's show.

Repro

deepsec config set llm.provider anthropic
deepsec config set llm.api_key sk-ant-xxxxxxxx...
deepsec config show
# api_key: sk-ant-xxxxxxxx...   <- full plaintext key printed

Suggested fix

Port the masking logic from the legacy config_get/config_set into the current show command — mask any key whose dotted path contains key, pass, token, secret, etc. before printing, e.g. sk-ant-xx... instead of the full value. Ideally add a test asserting config show output never contains a full-length secret string when one is configured.

Impact

Anyone running deepsec config show — including AI coding assistants executing shell commands on a user's behalf — gets the raw API key in their output/logs/transcript. This is a real-world footgun for a security-focused tool.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions