It depends by the command, echo is idempotent for example. There should be some checking like
$cmdname = split(' ', $_GET['command']);
if(!in_array(IDEMPOTENT_COMMANDS, $cmdname))
echo '<h1>Your request is not guaranteed to be idempotent. Please use a POST.</h1>';
else
exec($_GET['command'] ...
As a simple call, yes. But there are many shell tricks (redirection, command substitution, process substitution) that can make an echo call have significant side effects - so if you were daft enough to be considering this you'd need to do much more checking before submitting the provided instruction to your shell, and those checks would need to know which shell you were targeting (in fact you'd probably want to force the issue by exec()ing a specific shell instead of just using the default for the user the code is running as).
I think the problem here is the fact that tainted variables (user input) are used to execute shell commands. it doesn't matter if that's $_POST or $_GET, both of these are user input and therefore these are huge vulnerabilities.
Which points out that the context has to considered as well. E.g., if it's a personal intranet or password protected page, this may not be vulnerability.
It would still be vulnerable to a CSRF attack. The attacker can just get a logged-in user to launch their exploit, through a vulnerable site they frequent or even a link or image in an email.
Theoretically, building CSRF protection in isn't mutually exclusive with passing unsanitised variables to a shell. Although sure, most people who do the latter won't do the former.
What if a hacker would have access to a user of said personal intranet, or would find a way to bypass the password protected page. Then he'd be able to execute anything on the server, even stuff the user he hacked shouldn't be able to access. So no, this is always a vulnerability.
Maybe not unintended, but definitely full access, and the world is almost certainly full of outdated/non whitelist access/weakly passworded panels.
Also, on a a sufficiently misconfigured server, you could always use \! (mysql's shell_exec, etc.) with phpmyadmin etc. to open a remote shell somewhere, then work from there.
As a theoretical aside, I wonder if it'd be possible to have a typesystem based solution to these kinds of problems - where variables coming from the user (or from another program) are considered 'unsafe' and the compiler refuses to let exec() or whatever use them until they've been through a cleaner/tester of some kind... (OK, I know PHP doesn't have a compiler as such - but a static checker of some kind could work the same...)
But of course we just laugh about Perl and pat ourself on our backs with our safe new languages because we clearly know much more than those anachronistic neckbeards.
But of course we just laugh about Perl and pat ourself on our backs with our safe new languages
And there is some justification for that: if those "safe new languages" are doing the type checking at compile time, that is better than only finding out you have a safety issue when you fail at run time.
Ah, "Taint" was the missing magic word I couldn't figure out to aid my google-fu (well, duckduckgofu...). Thanks for that - there is a lot of interesting stuff out there. :-)
On the practical side, Ruby (MRI specifically) has such a system ($SAFE), that taints certain objects (e.g. those gained by IO) and only allows you to use them in certain fashions (e.g. only after explicit handling).
It's leaky as hell, because all components have to get the marking right. Also, not all Objects have equal trust levels. Objects created due to a HTTP request (GET-Parameters) should certainly be tainted, but how about Object read through IO - do we trust out filesystem? Do we trust the database? Thats more of an architectural decision.
In the end, the problem comes down to this: you have to whitelist the world and everything you miss is an error.
Then people notice that exec($_GET['foo']) doesn't work, but some smart cookie figures out that exec(untaint($_GET['foo'])) (or whatever the syntax is for removing the taint from an input variable) does, posts it online, and everyone copies that instead without thinking about the consequences.
There is Argos[0] which is a research project at my university, it's a qemu-based emulator that tracks tainted data coming from the network and other compromised sources and makes sure it doesn't tamper with memory or filesystem locations than it shouldn't. It's a bit overkill,especially for this, but it's interesting to check out :)
Different languages (SQL, JS, HTML, Shell, Plaintext, etc.) are treated as different types. Language-specific functions only accept arguments of the relevant type (eg. shell_exec takes Shell, db_query takes SQL, etc.). User input is Plaintext (usually; sometimes it might be something more specific like BASE64).
Different languages can't be combined (eg. SQL can't be concatenated with Plaintext), but they can be converted down to Plaintext and Plaintext can be converted to any language via escaping functions. This avoids injection attacks, since the only way to please the type-checker is by escaping properly.
I really, really, really want to post on their issue tracker, but maybe I shouldn't. There's no guarantee the person grading the project will care, either.
Directly passing user data to the command line is highly dangerous.It allows an attacker to execute arbitrary commands on the command line [0].
escapehellarg [1] has to be used to Escape a string to be used as a shell argument
Directly doing anything with attacker supplied data is generally a no-no.
Everything that may come from a user must be filtered, escaped or generally treated as hostile.
As an example on an IRC channel someone once made their chan bot log the channel to the web, all it took was pasting javascript into an IRC window, and typing "LOL look at this! http://stupidbot.com/ircweblog". Channel pwned.
I remember reading about something like this and Github their response was that the guy should stop according to their ToS. Their ToS blocks stuff like this to prevent spamming.
I thought about doing the exact same thing. But I wonder about the: limiting of the issue creation API on github and false positives. [The variable has been sanitized prior to being executed]
I don't like Issue bots, but it could actually be a huge value-add for GitHub to integrate these kinds of checks (as well as hardcoded credentials, etc) for their users.
After looking at the search result i can see that most of the results have legit reasons.
Instead of half-assing the problem, please dedicate 10 minute of your life to look in, analyze & report one or two of the problems you find.
Also explain why you think this is an security issue.
You will:
* help someone out by pointing out an issue
* hopefully educate the person how to write better code
* educate yourself in reading and understanding others spaghetti code
As a side note, this is how many SQL injection attacks happen too. You almost never want unfiltered user input to directly interact with your system. A while back, I did an episode on how SQL injection can lead to code execution by using unfiltered user input on a LAMP stack. See it @ http://sysadmincasts.com/episodes/21-anatomy-of-a-sql-inject...
I think you're giving him too much credit. The input was not sanitized. Now its no one programmers fault. It was a long living bug many had a chance to see it and correct it for a long time. It was rooted in the same carelessness as exec(GET)
Sadly, there's cases where exec() is impossible to avoid - for example, every kind of tool that doesn't have a proper library and language bindings. See git and the grit library for an example.
True, but there is a lot of software out there where people don't do that. Might be interesting to find vulnerabilities that are slightly less obvious.
Thats not the point. Of course "rm -rf /" won't work, but what about downloading and installing a backdoor? Or modifying the website scripts itself? Or dumping a database? Or...
Removing all the files from a filesystem is something only a script kiddy would do, and it's probably a "best case scenario" for the owner of the server, because the impact of that is relatively small (just re-install the server and restore the backups). But once the attacker starts injecting mallware, stealing customer information (credit card numbers anyone?) or anything else nasty they can think of that they would benefit from, then you are in a whole lot more trouble...
True, but once you have <foo; $any_command_with_user_privilege> you can start executing any user commands. So you do a </dev/null; mkdir ~/www/nefarious; cp ~/www/AdminSettings.php ~/www/nefarious/settingns.txt;> (without the index file you can just view the file as plain text, which probably contains the database username and password. Then you can go on and download a database dump. The attacker probably does not give a damn about root in this scenario.
It would actually be a nice to build an optional warning feature into `git` itself. You could download some known common issues and the script would generate warnings if you checked in corresponding code. E.g.
git add id_rsa
WARNING: You may have just staged a private key.
or better
echo '{"password": "mypassword"}' > config.json
git add config.json
WARNING: You may have just staged a password.
Fortunately?? More often than we all care to admit, these things are exposed to the internet. (because it's so cool when I can turn on the coffee machine from my smartphone halfway home from work)
It is executing shell commands based on what you pass in through a request parameter. Since there is no filtering going on, you could, I suppose, pass in an entire bash script and have a good ol' time.
Its mean to show all the projects on Github that are vulnerable to injection attacks. An attack can maliciously create a GET request that escapes out the current command and then execute arbitrary commands.
Did someone else notice that that github search returns mostly results where exec is completely disconnected by $_GET? And that, i'd say, the last 20 pages contain the same thumbnail script that contains simply the "exec" string and multiple uses $_Get somewhere?
Maybe it's still an asinine error somewhat common, but i wouldn't take that search results as proof of how common it is...
Paul's Security Weekly (a security podcast) had their blog owned after inadvertently removing the .htaccess (the password protection in your example) from their admin directory.
I already have a thing called "all seeing eye" that picks up on things like this on a pre-commit script in SVN and tells people to go away if they do something stupid. It's done some wonderful work so far.