<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
	<p>

		Dynamically constructing a shell command with values from the
		local environment, such as file paths, may inadvertently
		change the meaning of the shell command.

		Such changes can occur when an environment value contains
		characters that the shell interprets in a special way, for instance
		quotes and spaces.

		This can result in the shell command misbehaving, or even
		allowing a malicious user to execute arbitrary commands on the system.

	</p>


</overview>
<recommendation>

	<p>

		If possible, use hard-coded string literals to specify the
		shell command to run, and provide the dynamic arguments to the shell
		command separately to avoid interpretation by the shell.

	</p>

	<p>

		Alternatively, if the shell command must be constructed
		dynamically, then add code to ensure that special characters in
		environment values do not alter the shell command unexpectedly.

	</p>

</recommendation>
<example>

	<p>

		The following example shows a dynamically constructed shell
		command that recursively removes a temporary directory that is located
		next to the currently executing JavaScript file. Such utilities are
		often found in custom build scripts.

	</p>

	<sample src="examples/shell-command-injection-from-environment.js" />

	<p>

		The shell command will, however, fail to work as intended if the
		absolute path of the script's directory contains spaces. In that
		case, the shell command will interpret the absolute path as multiple
		paths, instead of a single path.
	</p>

	<p>

		For instance, if the absolute path of
		the temporary directory is <code>/home/username/important
		project/temp</code>, then the shell command will recursively delete
		<code>/home/username/important</code> and <code>project/temp</code>,
		where the latter path gets resolved relative to the working directory
		of the JavaScript process.

	</p>


	<p>

		Even worse, although less likely, a malicious user could
		provide the path <code>/home/username/; cat /etc/passwd #/important
		project/temp</code> in order to execute the command <code>cat
		/etc/passwd</code>.

	</p>

	<p>

		To avoid such potentially catastrophic behaviors, provide the
		directory as an argument that does not get interpreted by a
		shell:

	</p>

	<sample src="examples/shell-command-injection-from-environment_fixed.js" />

</example>
<references>

	<li>
		OWASP:
		<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
	</li>

</references>
</qhelp>
