Skip to content

RB: add second-order-command-injection #11236

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

erik-krogh
Copy link
Contributor

I also did some drive-by refactorizations in the first commit.
I noticed an override DataFlow::Node getAnArgument in classes that extends DataFlow::CallNode.
That is just a foot-gun waiting to happen if DataFlow::CallNode gets an getAnArgument predicate, so I changed those classes to instanceof DataFlow::CallNode.


@erik-krogh erik-krogh added WIP This is a work-in-progress, do not merge yet! Ruby labels Nov 11, 2022
@github-actions
Copy link
Contributor

QHelp previews:

ruby/ql/src/queries/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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Ruby WIP This is a work-in-progress, do not merge yet!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy