Skip to content

Hardening: refuse to serve credential-bearing files (wp-config backups, .env, root SQL dumps) — reject them at POST /extractions validation #21

Description

@TBarregren

Summary

Security hardening (defence in depth): the Extractor will currently package and serve any in-scope file the caller selects — including credential-bearing files. On the live smoke test (2026-07-23), the production install root contained wp-config.php.bak-20260717-212309 and wp-config.php.bak-redis-20260718-074109, each holding the full secret family in clear text (DB_PASSWORD, DB_USER/NAME/HOST, AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY, all four salts — 24–25 defines each). Both were packaged into the sealed container and landed on the client machine.

This defeats the plugin's own safety posture: GET /environment deliberately masks the secret-define family server-side ("the secrets that never come down"), but the file layer hands the same secrets over anyway, via config backups. Leaving a .bak next to wp-config.php after an edit is extremely common in the wild.

The primary fix lives in the client (kntnt-wp-skills must always-exclude credential patterns from its selection — tracked there), but the server should not rely on every client getting its exclusion set right. The Extractor is the last line of defence for the site's secrets.

Proposed behaviour

Introduce a shared deny-list of credential-bearing path patterns and reject extraction jobs that select a matching file at POST /extractions validation time — fail fast with an explicit error listing the offending paths, so a misconfigured client learns its selection is wrong instead of silently receiving (or silently missing) secrets.

Suggested pattern family (install-root-relative, case-insensitive):

  • wp-config.php and any sibling variant: wp-config.php.* (.bak*, .save, .orig, .old, ~, editor swap files), wp-config-*.php — with wp-config-sample.php allowed (no secrets).
  • .env, .env.* anywhere in the tree.
  • Root-level database dumps: *.sql, *.sql.gz, *.sql.zip directly in the install root.
  • Auth/key material: *.pem, *.key, id_rsa* directly in the install root.

Decisions folded into this proposal (adjust if the maintainer disagrees):

  • Reject at job creation rather than silently skipping at packaging time — silent skips would desynchronise the client's manifest/baseline accounting and hide the misconfiguration.
  • GET /files keeps listing these paths (the manifest stays truthful; clients need to see them to exclude them and to diff baselines). Optionally annotate matching entries (e.g. "restricted": true) so clients can build their exclusion sets from the server's own verdict.
  • The deny-list must be a single shared code constant with unit tests — not prose — and documented in the REST contract.

Acceptance criteria

  • POST /extractions with a selection containing e.g. wp-config.php.bak-x returns a 4xx naming the offending path(s); no job is created.
  • wp-config-sample.php is not blocked.
  • The pattern list lives in one constant, covered by tests for each pattern class (positive and negative cases).
  • GET /files behaviour documented (unchanged listing, plus the optional restricted annotation if adopted).

References

  • Observed in the field: two wp-config.php.bak-* files with full production secrets transferred in clear inside the sealed container (smoke test 2026-07-23).
  • Complements the /environment secret-define masking; closes the same hole at the file layer.
  • Client-side primary fix: kntnt-wp-skills exclusion-set assembler (tracked in that repo).

Filed from the second live smoke test of the kntnt-wp-skills ⇄ kntnt-extractor cutover, 2026-07-23.

Activity

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

    enhancementNew feature or requestready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions