If you discover a security vulnerability, please report it responsibly by emailing matthewcgetz@gmail.com. Do not open a public issue.
You should receive a response within 72 hours. If accepted, a fix will be developed privately and released as a patch version.
This package defaults to safe behavior to mitigate denial-of-service and accidental misuse:
- Variable-expansion cycles in
expand-tagged values are detected and rejected withErrCyclerather than overflowing the stack. fromFilereads read the named file's contents into the field. Only fields you explicitly tagfromFileare eligible; keep the path under your control (don't derive it from untrusted input, e.g. pointed at/dev/zero).- No subshell execution. The package never invokes
$(command)or any shell substitution form. - No
os.Setenvfrom inside the library (with the single exception of theunsettag option, which is opt-in per field). All "writes" operate on in-memorySourcechains or*atomic.Pointer[T]snapshots so the package never collides with libcsetenv/getenvthread-safety on cgo paths. .envparsing is not part of this package — it lives in go-rotini/dotenv, which has its own DoS guards (max file size, max line length, expansion depth, cycle detection). See that package'sSECURITY.md.
Fields tagged secret are redacted in:
Describe/PrintUsage/Markdownoutput- Error messages (replaced with
<redacted: N bytes>) Encodeoutput (replaced with***unlessWithEncodeIncludeSecrets(true)is explicitly set)
The Secret[T] wrapper threads redaction through fmt.Stringer, fmt.GoStringer, and slog.LogValuer so secret values do not leak through user-side logging.