Skip to content

[sec-check] Credential denylist misses *_KEY, *_PWD, *_PAT, webhook URLs and DATABASE_URL-style values — repo templates still expand them into prompts and the builder UI #119

Closed

Description

@hivecommons-hive

Security Finding

Severity: medium
Type: secret-exposure (unsafe-pattern — incomplete denylist)

#46/#47 stopped repo-controlled templates from implicitly expanding credential env vars ({{GITHUB_TOKEN}}) into prompt output and the builder UI. The guard is a name-only denylist, SENSITIVE_ENV_PATTERN in src/autodetect.ts:

/TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|API_?KEY|ACCESS_KEY|PRIVATE_KEY|BEARER|COOKIE|(^|_)AUTH(_|$)/i

It misses several very common credential naming conventions, and README line 304 over-promises what it covers ("anything matching ... KEY ..."), when only API_KEY / ACCESS_KEY / PRIVATE_KEY are matched.

Reproduced at 41c7bbd:

$ env -i PATH="$PATH" HOME=/tmp \
    DATABASE_URL='postgres://app:p@db.internal/app' MYSQL_PWD='p' OPENAI_KEY='sk-...' \
    SIGNING_KEY='s' SLACK_WEBHOOK_URL='https://hooks.slack.com/services/T/B/x' GITHUB_PAT='ghp_...' \
  node dist/cli.js 'db={{DATABASE_URL}} pwd={{MYSQL_PWD}} oa={{OPENAI_KEY}} sig={{SIGNING_KEY}} hook={{SLACK_WEBHOOK_URL}} pat={{GITHUB_PAT}}' --no-interactive
db=postgres://app:p@db.internal/app pwd=p oa=sk-... sig=s hook=https://hooks.slack.com/services/T/B/x pat=ghp_...

Every one of those expanded. The same isSensitiveEnvName() gate is what collectEnvVars() in src/ui.ts uses, so the builder UI's "Show terminal env" list embeds the same values in the served page.

Classes that get through:

  • *_KEY without API_/ACCESS_/PRIVATE_ prefix: OPENAI_KEY, STRIPE_KEY, SIGNING_KEY, ENCRYPTION_KEY, MASTER_KEY, HIVE_HEARTBEAT_KEY, LICENSE_KEY
  • *_PWD: MYSQL_PWD, ORACLE_PWD
  • *_PAT: GITHUB_PAT, AZURE_DEVOPS_PAT
  • *WEBHOOK*: Slack/Discord/Teams webhook URLs are bearer secrets
  • *_DSN, *CONNECTION_STRING*, *_URL/*_URI with userinfo: DATABASE_URL, REDIS_URL, MONGO_URI, SENTRY_DSN — the password is embedded in the value, and no name rule can catch every one of these
  • JWT*, *HMAC*, *OAUTH* (when not also _TOKEN/_SECRET)

Impact

A cloned repository's checked-in .prompts/*.md template (or a template a user is handed to paste inline) can name any of the above and silently exfiltrate the value into the generated prompt — which is then sent to a hosted AI model or pasted into a chat. The user sees only the finished prompt text and has no indication a variable came from the environment rather than a default. Database passwords (DATABASE_URL) and PATs are the highest-value cases.

Recommendation

Defense in depth, in src/autodetect.ts and reused by src/ui.ts — the implicit env fallback and the UI env listing only; explicit --flag=value stays untouched:

  1. Widen the name pattern to also match (^|_)KEYS?(_|$), _PWD(_|$), (^|_)PAT(_|$), WEBHOOK, (^|_)DSN(_|$), CONN(ECTION)?_?STR(ING)?, (^|_)PASS(_|$), PASSPHRASE, JWT, HMAC, OAUTH (keeping PATH, KEYBOARD, PWD, AUTHOR non-matching).
  2. Add a value-shape check isSensitiveEnvValue(value) so name-agnostic secrets are still refused: URL userinfo with a password (scheme://user:pass@), PEM blocks (-----BEGIN), JWTs (eyJ…​.eyJ…​.), and well-known token prefixes (ghp_/gho_/ghu_/ghs_/ghr_/github_pat_, glpat-, sk-/sk_live_/sk_test_, xox[abprs]-, AKIA…, AIza…, npm_…, hvs.).
  3. Fix README line 304 to describe the actual rule.
  4. Add tests for each class above to src/autodetect.test.ts and src/ui.test.ts.

Longer-term the implicit process.env fallback could be made opt-in (allowlist or --env flag), which removes the class entirely; that is a product decision and is out of scope for this issue.

  • name pattern widened
  • value-shape check applied to env fallback and UI env listing
  • README corrected
  • tests

Filed by sec-check agent (ACMM L6 — full mode)


🐝 Hive Agent: security | Instance: hosted-available-oke-11-placeholder-r05x | SHA: 41c7bbd

— hive: agent=sec-check backend=copilot model=claude-fable-5.1 copilot=1.0.88

Activity

  1. added
    help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
    on Oct 3, 2026
  2. added
    hive/covered-by-prHive verified that an open PR references or claims this issue; still actionable until confirmed
    on Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/sec-checkCreated by Hive for agent-filed issue provenancehelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.hive/covered-by-prHive verified that an open PR references or claims this issue; still actionable until confirmedhive/hosted-available-oke-11-placeholder-r05xCreated by Hive for agent-filed issue provenancesecurityCreated by Hive for agent-filed issue provenance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions