|
2 | 2 | "-//Semmle//qhelp//EN"
|
3 | 3 | "qhelp.dtd">
|
4 | 4 | <qhelp>
|
5 |
| -<overview> |
6 |
| -<p>Code that passes user input directly to |
7 |
| -<code>require('child_process').exec</code>, or some other library |
8 |
| -routine that executes a command, allows the user to execute malicious |
9 |
| -code.</p> |
10 | 5 |
|
| 6 | +<overview> |
| 7 | +<p>Code that passes untrusted user input directly to |
| 8 | +<code>child_process.exec</code> or similar APIs that execute commands by |
| 9 | +spawning a shell allows the user to execute malicious code.</p> |
11 | 10 | </overview>
|
12 |
| -<recommendation> |
13 | 11 |
|
14 |
| -<p>If possible, use hard-coded string literals to specify the command to run |
15 |
| -or library to load. Instead of passing the user input directly to the |
16 |
| -process or library function, examine the user input and then choose |
17 |
| -among hard-coded string literals.</p> |
| 12 | +<recommendation> |
| 13 | +<p>If possible, use hard-coded string literals to specify the command to run. |
| 14 | +Instead of interpreting the user input directly as a shell command, examine the |
| 15 | +user input and then choose among hard-coded string literals.</p> |
18 | 16 |
|
19 |
| -<p>If the applicable libraries or commands cannot be determined at |
20 |
| -compile time, then add code to verify that the user input string is |
21 |
| -safe before using it.</p> |
| 17 | +<p>If the applicable libraries or commands cannot be determined until runtime, |
| 18 | +then add code to verify that the user input string is safe before using it.</p> |
22 | 19 |
|
| 20 | +<p>If possible, prefer APIs that run the commands directly rather than via a |
| 21 | +shell, and that accept command arguments as an array of strings rather than a |
| 22 | +single concatenated string. This is both safer and more portable.</p> |
23 | 23 | </recommendation>
|
24 |
| -<example> |
25 | 24 |
|
26 |
| -<p>The following example shows code that takes a shell script that can be changed |
27 |
| -maliciously by a user, and passes it straight to <code>child_process.exec</code> |
28 |
| -without examining it first.</p> |
| 25 | +<example> |
| 26 | +<p>The following example shows code that extracts a filename from an HTTP query |
| 27 | +parameter that may contain untrusted data, and then embeds it into a shell |
| 28 | +command to count its lines without examining it first.</p> |
29 | 29 |
|
30 | 30 | <sample src="examples/command-injection.js" />
|
31 | 31 |
|
| 32 | +<p>A malicious user can exploit this code to execute arbitrary shell commands by |
| 33 | +passing a filename like <code>foo.txt; rm -rf .</code>, which will first count |
| 34 | +the lines in <code>foo.txt</code> and then delete all files in the current |
| 35 | +directory.</p> |
| 36 | + |
| 37 | +<p>To avoid this potentially catastrophic loophole, use an API like |
| 38 | +<code>child_process.execFileSync</code> that does not spawn a shell by |
| 39 | +default:</p> |
| 40 | + |
| 41 | +<sample src="examples/command-injection_fixed.js" /> |
32 | 42 | </example>
|
33 |
| -<references> |
34 | 43 |
|
| 44 | +<references> |
35 | 45 | <li>
|
36 | 46 | OWASP:
|
37 | 47 | <a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
|
38 | 48 | </li>
|
39 |
| - |
40 | 49 | <!-- LocalWords: CWE untrusted unsanitized Runtime
|
41 | 50 | -->
|
42 |
| - |
43 | 51 | </references>
|
| 52 | + |
44 | 53 | </qhelp>
|
0 commit comments