Second order command injection — CodeQL query help documentation
CodeQL docs
Second order command injection
ID: js/second-order-command-line-injection
Kind: path-problem
Security severity: 7.0
Severity: error
Precision: high
Tags:
- correctness
- security
- external/cwe/cwe-078
- external/cwe/cwe-088
Query suites:
- javascript-code-scanning.qls
- javascript-security-extended.qls
- javascript-security-and-quality.qls
Click to see the query in the CodeQL repository
Some shell commands, like git ls-remote, can execute arbitrary commands if a user provides a malicious URL that starts with --upload-pack. This can be used to execute arbitrary code on the server.
Recommendation
Sanitize user input before passing it to the shell command. For example, ensure that URLs are valid and do not contain malicious commands.
Example
The following example shows code that executes git ls-remote on a URL that can be controlled by a malicious user.
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
});
The problem has been fixed in the snippet below, where the URL is validated before being passed to the shell command.
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
});
References