You know this sudo stuff:

Defaults env_reset

which makes environment injection impossible. I was wandering if this functionality can be obtained from bash script directly, 'from inside'?

At least part of it can, that is for sure. Example:

#!/usr/bin/env php

// sanitizes $PATH

// unsets $LD_LIBRARY_PATH, as it should be in Ubuntu

Can we do env_reset in running script like sudo does and how?


I'm not looking for the way to do it 'from outside' like env -i command but from inside of script itself. My intention is to ensure security no matter who (what user) and how(under which circumstances, i.e. env variables) runs it.

  • Possible duplicate of How to run a program in a clean environment in bash?
    – Kusalananda
    Commented Feb 2, 2017 at 14:45
  • @Kusalananda why duplicate? I'm not after empty environment nor the way to do it 'from outside' like env -i. Commented Feb 2, 2017 at 14:50
  • the php script might be a little distracting, if you're asking about bash; the syntax for clearing an environment will differ among scripting languages. For reference, sudo's environment handling
    – Jeff Schaller
    Commented Feb 2, 2017 at 15:00
  • What are the security concerns? If you want to be sure of getting a clean environment, then env -i bash --norc --noprofile will give you that. Apart from that, just list the environment variables and unset them, one by one.
    – Kusalananda
    Commented Feb 2, 2017 at 15:14

2 Answers 2


bash itself uses some environment variables. By the time bash is started and ready to interpret its first command, it's already too late, a malicious environment can have had bash do damage already.

You need the environment to have been sanitized before bash is called. You can wipe the environment with the clearenv() C function on most systems or you could just call execve() on your script and pass an empty list in the envp parameter.

Even with a script that contains:

#! /bin/bash -

(: being a special builtin), if the environment contains SHELLOPTS=xtrace PS4='$(reboot)', the reboot command will be invoked upon :.

If bash is dynamically linked, LD_PRELOAD/LD_LIBRARY_PATH can make bash run arbitrary code as soon as it's invoked.

bash also honours the locale's charset for its parsing, so with LOCPATH and LC_* variables, you can have even the #! /bin/bash - line invoke arbitrary code (by making #!/bina characters blanks for instance).

See also:

env SHELLOPTS=noexec any-bash-script

That stops bash from doing anything.

Those are just a few examples.

Also note that the environment variables are not the only things that a command inherits on startup and that may affect its behaviour (like arguments, umask, limits, current working directory, open file descriptors, signal disposition, controlling terminal...).


You can find your exports with export -p or simply export, and replace the declare -x with declare +x on each line to unexport it:

eval "$(export|sed s/-/+/)"

If you put this at the beginning of your script, then no environment variables will be passed through to the programs it executes unless you explicitly export them yourself. You'll probably want to export locale and TZ variables, and TERM, and more...

  • No, even eval "$(export)" is an arbitrary command injection vulnerability. Try env -i '$(reboot)=x' bash -c export for instance. Commented Feb 2, 2017 at 17:49
  • That part was fixed in bash-4.4 though. Commented Feb 2, 2017 at 17:55
  • My bash correctly quotes its declare -x output, so that's not an issue. I do like the PS4 attack in your answer, @Stéphane - very clever! Commented Feb 2, 2017 at 18:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .