Skip to content

pkgzip: the dotenv leak class is wider than the name rules — envs/prod.env, a root db.env and case-variants all package, and a dropped subtree is never printed #435

Description

@ZacxDev

Follow-up to #420 / PR #433, split out rather than expanded into that PR. #433 closes the directory-shaped half of the leak; this is what is left, all measured through the built binary on that branch, not reasoned about.

1. The rules match NAMES, so these still upload

A synthetic project packaged with app submit --package-only on fix/420-dotenv-shaped-directories:

planted in the bundle?
db.env (project root) packaged — base name does not start with .env
envs/prod.env packaged — neither name is .env-dotted
env/local.env packaged — same
.env-backup/db.env packaged.env-backup is not .env.-dotted
x.ZIP/a.txt packaged — the archive rule is case-sensitive
.ENV.local/b.txt packaged — the dotenv rule is case-sensitive
.env.d/should-drop.env correctly dropped (that is #420's fix working)

envs/ and env/ are at least as conventional as .env.d/, and a bare db.env is what most tooling writes. The README on #433 now documents every row above, so this is a known gap rather than a surprise — but documenting a credential path is not closing it.

Worth considering, in rough order of value-per-risk:

  • case-insensitive matching on both rules (cheap, no plausible collision);
  • a *.env suffix rule for files, which catches db.env / prod.env wherever they sit;
  • envs/ and env/ are NOT safe to add as fixed excludedDirs names — src/env/ is plausible app code. This one probably wants content-sniffing or a warning, not an exclusion.

2. A dropped subtree is invisible

internal/cmd/app_submit.go prints only Packaged %d file(s). isDotenvShaped's own comment names silent subtree removal as the failure mode it is trading against, and nothing mitigates it: measured 8 files → 6 with no message naming what went. A --verbose skipped-path list, or a one-line "skipped N path(s) (…)", would make an over-broad rule self-reporting instead of silent.

3. internal/antipattern keeps a rival exclusion list

internal/antipattern/antipattern.go:198-202 has its own 8-name skipDirs against excludedDirs' 18, and now also lacks the dotenv/archive directory rules — so validate can report findings in files the packager drops. Pre-existing divergence, marginally widened by #420; impact is limited by scannedExts. One predicate, one place.

Found by an adversarial audit of #433. Findings 1 and 2 there were fixed in-PR (7c833d2); these three were judged follow-ups rather than blockers.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions