Skip to content

JS: second-order-command-injection #11013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 4, 2022
Merged

Conversation

erik-krogh
Copy link
Contributor

@erik-krogh erik-krogh commented Oct 27, 2022

CVE-2022-25900: FN (dynamically chosen git cmd).
CVE-2022-24437: TP/TN
CVE-2022-25865: TP/TN
CVE-2022-24066: FN (we don't recognize the source due to very dynamic initialization, and we don't recognize the sink due to some dynamic command construction).
CVE-2022-1440: FN (this is more for js/shell-command-constructed-from-input, but they roll their own shell sanitization, which it doens't track through).
CVE-2022-25766: FN (dynamic construction of the arguments, so we don't recognize the git invocation).
CVE-2022-24433: FN (same project as CVE-2022-24066).


This blog post is a nice introduction to the vulnerability: https://justi.cz/security/2021/04/20/cocoapods-rce.html

The sinks for this query are arguments to e.g. cp.execFile("git", ["clone", <sink>]).

But also functions that just forwards their arguments to a shell executions, because I've seen that pattern in a few CVEs.
E.g.

function indirect(cmd, args) { cp.execFile(cmd, args) }
indirect("git", ["clone", <sink>])

Evaluation was uneventful.

@erik-krogh erik-krogh added the WIP This is a work-in-progress, do not merge yet! label Oct 27, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Oct 27, 2022

QHelp previews:

javascript/ql/src/Security/CWE-078/SecondOrderCommandInjection.qhelp

Second order command injection

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

@erik-krogh erik-krogh marked this pull request as ready for review October 31, 2022 08:31
@erik-krogh erik-krogh requested a review from a team as a code owner October 31, 2022 08:31
@calumgrant calumgrant requested a review from asgerf October 31, 2022 09:25
asgerf
asgerf previously approved these changes Oct 31, 2022
Copy link
Contributor

@asgerf asgerf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just a minor comment in the change note

---
* 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add something about which command names are currently recognized by the query, for example

This currently flags up unsafe invocations of git and hg.

Copy link
Contributor

@asgerf asgerf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just a few more comments.

Co-authored-by: Asger F <asgerf@github.com>
asgerf
asgerf previously approved these changes Nov 1, 2022
Copy link
Contributor

@asgerf asgerf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! LGTM

@erik-krogh
Copy link
Contributor Author

Lets get some eyes from the doc team.

@erik-krogh erik-krogh added ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. and removed WIP This is a work-in-progress, do not merge yet! labels Nov 1, 2022
@lucascosti
Copy link

👋 Docs first responder here! I've put this on our review board for a writer to review

@mchammer01 mchammer01 self-requested a review November 3, 2022 12:06
mchammer01
mchammer01 previously approved these changes Nov 3, 2022
Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@erik-krogh - this LGTM from a Docs perspective ✨
I've made a comment about improving the query description and adding a missing whitespace in the References section. The rest is very minor. Feel free to ignore any comment you don't agree with.

@@ -0,0 +1,25 @@
/**
* @name Second order command injection
* @description Some shell programs allow arbitrary command execution via their command line arguments.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we rewrite this so it follows the preferred syntax for a query description which is "Syntax X causes behavior Y." ?
I think it would be clearer to users if we went straight to the point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rewritten it to: Using user controlled data as arguments to some commands, such as git clone, can allow arbitrary commands to be executed.

<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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing witespace

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

<overview>
<p>
Some shell commands, like <code>git ls-remote</code>, can execute
arbitrary commands if a user provides a malicious URL that can start with
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we simplify here, or isn't it accurate to say this:

Suggested change
arbitrary commands if a user provides a malicious URL that can start with
arbitrary commands if a user provides a malicious URL that starts with

@erik-krogh erik-krogh dismissed stale reviews from mchammer01 and asgerf via 96ec54e November 3, 2022 13:02
mchammer01
mchammer01 previously approved these changes Nov 3, 2022
Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✨
Thanks for the docs updates!

Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
@erik-krogh erik-krogh requested a review from mchammer01 November 3, 2022 15:25
@erik-krogh erik-krogh removed the ready-for-doc-review This PR requires and is ready for review from the GitHub docs team. label Nov 3, 2022
Copy link
Contributor

@mchammer01 mchammer01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@erik-krogh erik-krogh merged commit c82d8cb into github:main Nov 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants