The repo's review bot flagged that --dotenv-quote-char's double-quote
mode let a secret containing $(cmd) or a backtick execute code when
the dotenv-export output was sourced by a shell. Investigating further
turned up that this output was never safe to source, independent of
this flag: the default single-quote wrapping didn't escape an embedded
single quote in the value, and the secret's own name was interpolated
completely unescaped, so a secret named e.g. "FOO=bar; touch pwned #"
or one starting with "-" (misread as an export flag, which on dash
dumps the whole environment to stdout) also executed or leaked on
source. A name containing "=" or ending in "+" let a secret silently
overwrite or append to an unrelated variable (PATH, LD_PRELOAD, ...),
since export re-parses NAME=VALUE/NAME+=VALUE after quote removal
regardless of quoting.
dotenv-export now delegates to dotenv-eval's existing posixShellQuote
for the value, and a secret name is only accepted if it matches a
portable shell variable name; anything else aborts the export with an
error instead of producing a partial or unsafe file. --dotenv-quote-char
no longer affects dotenv-export (always wrapped safely) or dotenv-eval
(already was); it still works as before for the plain dotenv format.
Verified each finding by hand: generating the real output and sourcing
it in bash, dash and sh, both before and after the fix. Reviewed
adversarially across several rounds by independent AI models until no
new finding surfaced.
Description 📣
Implements #1103 (possibility to export env-s with different quote character).
infisical exportalways wrapped values in single quotes. Single quoted dotenv values have no escape sequences, so a multiline value (e.g. a PEM private key) can't be represented with a real newline — you'd have to post-process the file afterward.--dotenv-quote-char(default', existing output unchanged), accepting'or"dotenvformat now (see security fix below for whydotenv-exportwas excluded)--templatepathSecurity fix (added after review)
The repo's automated reviewer flagged that double-quote mode combined with
--format=dotenv-exportlet a secret containing$(cmd)execute code when the output was sourced by a shell. Investigating further turned up thatdotenv-export's output was never safe tosource, independent of this PR:'in the value:and/in a secret name, so;,$,=, space are all valid)-(e.g.-p) got read as anexportflag — ondashthis dumps the whole environment to stdout instead of failing=or ending in+let a secret silently overwrite or append to an unrelated variable (PATH,LD_PRELOAD, ...), sinceexportparsesNAME=VALUE/NAME+=VALUEafter quote removal regardless of quotingFix:
dotenv-exportnow delegates todotenv-eval's existingposixShellQuotefor the value, and a secret name is only accepted if it matches a portable shell variable name (^[A-Za-z_][A-Za-z0-9_]*$); anything else aborts the export with an error instead of producing a partial or unsafe file.--dotenv-quote-charno longer applies todotenv-export(always wrapped safely) ordotenv-eval(already was).Breaking change:
dotenv-export/dotenv-evaloutput is nowexport -- KEY='VALUE'(wasexport KEY='VALUE'), and a secret name that isn't a valid shell identifier now fails the whole export instead of producing a line that silently misbehaves onsource. A secret literally named after a shell control variable (PATH,IFS,LD_PRELOAD, ...) is intentionally still allowed — that's the name being used with its expected effect, not smuggling, and isn't something this CLI can safely second-guess.Every finding above was verified by hand (built the real output, sourced it in
bash/dash/sh, confirmed the exploit before the fix and its absence after) and reviewed adversarially across independent rounds by multiple AI models before being folded in here.Type ✨
Tests 🛠️
Ran
go test ./packages/cmd/... -vet=off -count=1(all passing).Verified against the real
dotenvnpm package that double-quoted output round-trips correctly for values with trailing backslashes, embedded quotes, backslash+quote combinations, and multiline private keys:Verified the shell-injection fix by generating
dotenv-export/dotenv-evaloutput for adversarial secrets and sourcing it inbash,dashandsh: