@@ -491,6 +491,13 @@ BUILDKITE_AGENT_JWKS_KEY_ID`
491491 }
492492
493493 for key , value := range env {
494+ // Note that the value below is %q-quoted, and not shell-escaped.
495+ // Env files are designed to be validated by the pre-bootstrap hook.
496+ // Because the job env may contain untrusted or even dangerous env
497+ // vars, the pre-bootstrap hook should do this validation *without*
498+ // sourcing the file. (If the job env was universally safe, then
499+ // we wouldn't bother using a file - we'd load it straight into
500+ // the subprocess env.)
494501 if _ , err := fmt .Fprintf (r .envShellFile , "%s=%q\n " , key , value ); err != nil {
495502 return nil , err
496503 }
@@ -500,6 +507,8 @@ BUILDKITE_AGENT_JWKS_KEY_ID`
500507 }
501508 }
502509 if r .envJSONFile != nil {
510+ // key="value" format can be difficult to parse in some circumstances,
511+ // so we also have a JSON formatted env file.
503512 if err := json .NewEncoder (r .envJSONFile ).Encode (env ); err != nil {
504513 return nil , err
505514 }
@@ -775,7 +784,11 @@ func (r *JobRunner) executePreBootstrapHook(ctx context.Context, hook string) (b
775784
776785 // This (plus inherited) is the only ENV that should be exposed
777786 // to the pre-bootstrap hook.
778- // - Env files are designed to be validated by the pre-bootstrap hook
787+ // - Env files are designed to be validated by the pre-bootstrap hook.
788+ // Because the job env may contain untrusted or even dangerous env vars,
789+ // the pre-bootstrap hook should do this validation *without* sourcing the
790+ // file. (If the job env was universally safe to source, then we would
791+ // just pre-populate this env with it.)
779792 // - The pre-bootstrap hook may want to create annotations, so it can also
780793 // have a few necessary and global args as env vars.
781794 environ := envutil .New ()
0 commit comments