I do not agree that running an "external command" is "inherently" less secure than calling an "internal function". And I've no idea what you mean by "global environment".
By global environment
, I was referring to environment variables
(e.g. PATH, IFS, CDPATH, ENV, BASH_ENV, SHELL, TZ, LD_LIBRARY_PATH)
and other elements of the execution environment
(e.g. umask, inherited file descriptors, temporary files) that
are a common source of exploits by malicious attackers.
Certainly, executing an external program securely is not trivial:
there are many, many security exploits to consider and guard against.
That's why I stated that calling an internal function was inherently more
secure -- because all these many and varied exploits need not be considered.
To give a specific example, most shell scripts tend to use the
(potentially insecure) $HOME and $SHELL environment variables to
ascertain a user's home directory and shell, while a Perl script
can get this information via the more secure (and more reliable)
getpwnam internal function.
That shell scripts tend to be insecure is widely known and acknowledged;
see, for example,
FAQ: How can I get setuid shell scripts to work?
which opens with:
Unlike most command line
shells, which are based on multiple substitution passes on each line of the
script, Perl uses a more conventional evaluation scheme with fewer hidden snags.
Additionally, because the language has more builtin functionality, it can rely
less upon external (and possibly untrustworthy) programs to accomplish its purposes.