mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Improve command-injection example and provide a fixed version.
This commit is contained in:
@@ -2,43 +2,52 @@
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Code that passes user input directly to
|
||||
<code>require('child_process').exec</code>, or some other library
|
||||
routine that executes a command, allows the user to execute malicious
|
||||
code.</p>
|
||||
|
||||
<p>Code that passes untrusted user input directly to
|
||||
<code>child_process.exec</code> or similar APIs that execute commands by
|
||||
spawning a shell allows the user to execute malicious code.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>If possible, use hard-coded string literals to specify the command to run.
|
||||
Instead of interpreting the user input directly as a shell command, examine the
|
||||
user input and then choose among hard-coded string literals.</p>
|
||||
|
||||
<p>If possible, use hard-coded string literals to specify the command to run
|
||||
or library to load. Instead of passing the user input directly to the
|
||||
process or library function, examine the user input and then choose
|
||||
among hard-coded string literals.</p>
|
||||
|
||||
<p>If the applicable libraries or commands cannot be determined at
|
||||
compile time, then add code to verify that the user input string is
|
||||
safe before using it.</p>
|
||||
<p>If the applicable libraries or commands cannot be determined until runtime,
|
||||
then add code to verify that the user input string is safe before using it.</p>
|
||||
|
||||
<p>If possible, prefer APIs that run the commands directly rather than via a
|
||||
shell, and that accept command arguments as an array of strings rather than a
|
||||
single concatenated string. This is both safer and more portable.</p>
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<p>The following example shows code that takes a shell script that can be changed
|
||||
maliciously by a user, and passes it straight to <code>child_process.exec</code>
|
||||
without examining it first.</p>
|
||||
<example>
|
||||
<p>The following example shows code that extracts a filename from an HTTP query
|
||||
parameter that may contain untrusted data, and then embeds it into a shell
|
||||
command to count its lines without examining it first.</p>
|
||||
|
||||
<sample src="examples/command-injection.js" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
<p>A malicious user can exploit this code to execute arbitrary shell commands by
|
||||
passing a filename like <code>foo.txt; rm -rf .</code>, which will first count
|
||||
the lines in <code>foo.txt</code> and then delete all files in the current
|
||||
directory.</p>
|
||||
|
||||
<p>To avoid this potentially catastrophic loophole, use an API like
|
||||
<code>child_process.execFileSync</code> that does not spawn a shell by
|
||||
default:</p>
|
||||
|
||||
<sample src="examples/command-injection_fixed.js" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
|
||||
</li>
|
||||
|
||||
<!-- LocalWords: CWE untrusted unsanitized Runtime
|
||||
-->
|
||||
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
var cp = require("child_process"),
|
||||
http = require('http'),
|
||||
path = require('path'),
|
||||
url = require('url');
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
let cmd = url.parse(req.url, true).query.path;
|
||||
let file = path.basename(url.parse(req.url, true).query.path);
|
||||
|
||||
cp.exec(cmd); // BAD
|
||||
cp.execSync(`wc -l ${file}`); // BAD
|
||||
});
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
var cp = require("child_process"),
|
||||
http = require('http'),
|
||||
path = require('path'),
|
||||
url = require('url');
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
let file = path.basename(url.parse(req.url, true).query.path);
|
||||
|
||||
cp.execFileSync('wc', ['-l', file]); // GOOD
|
||||
});
|
||||
Reference in New Issue
Block a user