Merge pull request #11013 from erik-krogh/sndCmd

JS: second-order-command-injection
This commit is contained in:
Erik Krogh Kristensen
2022-11-04 10:58:50 +01:00
committed by GitHub
48 changed files with 469 additions and 70 deletions

View File

@@ -0,0 +1,46 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
Some shell commands, like <code>git ls-remote</code>, can execute
arbitrary commands if a user provides a malicious URL that starts with
<code>--upload-pack</code>. This can be used to execute arbitrary code on
the server.
</p>
</overview>
<recommendation>
<p>
Sanitize user input before passing it to the shell command. For example,
ensure that URLs are valid and do not contain malicious commands.
</p>
</recommendation>
<example>
<p>
The following example shows code that executes <code>git ls-remote</code> on a
URL that can be controlled by a malicious user.
</p>
<sample src="examples/second-order-command-injection.js" />
<p>
The problem has been fixed in the snippet below, where the URL is validated before
being passed to the shell command.
</p>
<sample src="examples/second-order-command-injection-fixed.js" />
</example>
<references>
<li>Max Justicz: <a href="https://justi.cz/security/2021/04/20/cocoapods-rce.html">Hacking 3,000,000 apps at once through CocoaPods</a>.</li>
<li>Git: <a href="https://git-scm.com/docs/git-ls-remote/2.22.0#Documentation/git-ls-remote.txt---upload-packltexecgt">Git - git-ls-remote Documentation</a>.</li>
<li>OWASP: <a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,25 @@
/**
* @name Second order command injection
* @description Using user-controlled data as arguments to some commands, such as git clone,
* can allow arbitrary commands to be executed.
* @kind path-problem
* @problem.severity error
* @security-severity 7.0
* @precision high
* @id js/second-order-command-line-injection
* @tags correctness
* security
* external/cwe/cwe-078
* external/cwe/cwe-088
*/
import javascript
import DataFlow::PathGraph
import semmle.javascript.security.dataflow.SecondOrderCommandInjectionQuery
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Sink sinkNode
where cfg.hasFlowPath(source, sink) and sinkNode = sink.getNode()
select sink.getNode(), source, sink,
"Command line argument that depends on $@ can execute an arbitrary command if " +
sinkNode.getVulnerableArgumentExample() + " is used with " + sinkNode.getCommand() + ".",
source.getNode(), source.getNode().(Source).describe()

View File

@@ -0,0 +1,12 @@
const express = require("express");
const app = express();
const cp = require("child_process");
app.get("/ls-remote", (req, res) => {
const remote = req.query.remote;
if (!(remote.startsWith("git@") || remote.startsWith("https://"))) {
throw new Error("Invalid remote: " + remote);
}
cp.execFile("git", ["ls-remote", remote]); // OK
});

View File

@@ -0,0 +1,9 @@
const express = require("express");
const app = express();
const cp = require("child_process");
app.get("/ls-remote", (req, res) => {
const remote = req.query.remote;
cp.execFile("git", ["ls-remote", remote]); // NOT OK
});

View File

@@ -0,0 +1,7 @@
---
category: newQuery
---
* Added a new query, `js/second-order-command-line-injection`, to detect shell
commands that may execute arbitrary code when the user has control over
the arguments to a command-line program.
This currently flags up unsafe invocations of git and hg.