Skip to content
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

Can I find a function have arguments, which assigning from any user-supply #39

Open
lowk3v opened this issue Apr 14, 2020 · 2 comments
Open

Comments

@lowk3v
Copy link

lowk3v commented Apr 14, 2020

<?php
$input = $_GET["src"];
echo file_get_contents($input);

How to build a rule match with above situation?

@quasilyte
Copy link
Owner

quasilyte commented Apr 14, 2020

This type of checks is better handled by more sophisticated tools that understand the data flow.

That being said, I think you can do something like this:

phpgrep hello.php '$x = ${"y:var"}[$_]; ${"*"}; echo $sink(${"*"}, $x, ${"*"});' 'y=$_GET'

The pattern above:

  • $x = ${"y:var"}[$_];
    Matches the assignment to something (we name it $x). RHS should contain any indexing expression over a

  • ${"*"}
    skips uninteresting things in between.

  • $sink(${"*"}, $x, ${"*"})
    Matches any call-expr (method/func/etc) that consumes $x as its argument (at any position).

  • y=$_GET
    A filter that restricts $y RHS to $_GET variable.

Problems:

  1. Multi-statement patterns are either unimplemented yet or they don't work from the CLI. Can be fixed during this week. Not a fundamental restriction.
  2. If $x is used in other contexts, we won't find it. The pattern above is bound to call expressions.
  3. It only scans through the current lexical block. Related to Recursive block search #33

So, when (1) is fixed, it can find $_GET usage in this code:

$input = $_GET["src"];
$unrelated = $foo['blah'];

function f() {
}
f();

echo file_get_contents($input); // <- matched
echo file_get_contents($unrelated);

But it will not find anything here:

$input = $_GET["src"];
if ($whatever) {
  echo file_get_contents($input);
}

Maybe we can figure out what syntax/CLI options would be used to achieve that, but I still think that this is a task for things similar to CodeQL (although I don't think it supports PHP).

@lowk3v
Copy link
Author

lowk3v commented Apr 16, 2020

file_get_contents( '../server_side/' . $_POST['src'] . '.php');

What is pattern for detect the code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants