Is it possible for someone to execute a code through a URL for example
http://localhost/page.php?code=echo 'something';
If yes then how can it be done and how can you prevent it from happening?
It's possible if something on the server takes the data in the URL and puts it somewhere where it might be treated as code (e.g. in an eval statement, in an SQL query or in an HTML document).
The defences are all specific to the place where you put the data, but usually involve escaping it.
See also SQL Injection, XSS, and the open web application security project.
After looking around for a while, I found eval which is a function that is capable of executing any php code provided in a GET like my example above, I used the following code to test it.
<?php
$code = $_REQUEST['code'];
eval($code);
?>
Related
This question has been asked many times. See here, here and here
Based on the answers in those questions I did some tests and I'm forced to ask the same question again as none of the answers appear to be correct (at-least to me). Please correct me if my understanding of subject is bad.
I'm working on an API for a web app that outputs JSON response. The server side response is handled by json_encode in PHP. Since, this would be a public API I would want to prevent any XSS due to incorrect client side implementations by a deveopler consuming the API.
For my test I did the following on server side:
header("Content-Type: application/json", true);
$bad = array('bad_key' => 'alert("hi");');
echo json_encode($bad);
On client side I'm using jQuery AJAX that automatically parses the JSON recieved. Initially this did not appear to show any XSS issue. Then I passed response.bad_key to eval().
eval(response.bad_key);
This immediately resulted in execution of string in bad_key. I'm aware that use of eval is bad and should be avoided. However, that's something that I know and cannot ensure the other developer follows the same practice. To avoid such scenarios a solution would be to perform server side encoding. For this let's say I use htmlspecialchars.
header("Content-Type: application/json", true);
$bad = array('bad_key' => htmlspecialchars('alert("hi");'));
echo json_encode($bad);
This, though it does not execute alert("hi"); client-side but breaks the JS code due to presence of &. json_encode with the option JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS as suggested here does not help either.
So how do I prevent XSS in such a scenario?
You do not need to prevent "XSS" in this scenario. If someone is stupid enough to execute some random data you send him as JavaScript there is nothing you can do against it. Actually, if you did escape something to prevent it he would probably unescape it to make it work again.
Note that using eval to parse the JSON string is somewhat safe (assuming you send valid JSON) - even though it's discouraged in any modern browser that has a native JSON.parse().
But in your example you do not use it to parse JSON but to execute some random string of data! When anyone does that it means that he WANTS it to be executed as code - so it's not XSS but "working as intended"!
I got this mysql table with a text field. One of the text entries contains:
<?
if(isset($_GET["id"])) {
include($index.".php");
} else {
include("front.php");
}
?>
How do I output that mysql data as the script is intented to do, when i retrieve mysql data? It just outputs the php in my index file without it doing anything.
Use eval().
See here: PHP Manual - eval()
But you should consider finding another solution to your problem that made you put the code into a mysql table. Most of the time things like that are easy avoidable and considered bad practice.
First all, the code posted above isn't the way to go. This is an example of how not to code in general.
Why
1) You should avoid short PHP tags like, <?, <?= in order to make your code more portable. Because if server has an option like, allow_short_tags disabled, then the web server would simply treat your code as a plain text. (not as PHP script)
2) An error in if isset($_GET...) block, because you're telling the script to include($index.'.php') when $_GET['id'] has any value.Any! You do not even filter the $_GET['id']
And according to your last comments, this is an answer to "why you should not store PHP code in a database".
In order to read the code from database you should (in general)
Connect to SQL server
Run the query
Fetch the result
Evaluate the response via eval() function
But what if your SQL server is busy and does not respond? The script must be halted then.
This is generally considered as a bad practice and you should never code this way.
Why to do all those aforementioned "operations", when you can simply do:
<?php
include('some_codes.php');// or better require()
Another important thing
When you rely on $_GET['some_key'] and going to include some file according to the value of the $_GET key, you should always validate the $_GET['some_key']. A very basic validation would look like this:
<?php
if ( isset($_GET['foo']) ){
if ( file_exists('../path' . $_GET['foo']) ){
// seems like a valid one
// do include then
}
}
Conclusion
1) Do not use short tags, use a full one instead - <?php
2) Do not trust user inputs, i.e never trust values you got from $_GET and $_POST.
3) Keep the code in the files and then do include when needed.
I would like to make something like tryruby.org. I take a line from the user (e.g., echo __FILE__) and I want to execute it in PHP and return the output back to the client.
I tried to do exec('php -r ' . $command, $output), but $output always contains the PHP help section.
How can I implement this feature?
To make php -r you have to have to put the code you want to execute between ' .. your code .. '
Example:
php -r ' $var = 34; print_r($var); '
It looks like your problem is that you aren't wrapping your code to be executed with ' '. You also need to be wary of ' in the code, special characters, escape sequences, etc.
In fact, if you insist on using exec(), it might be better to do this (to completely avoid having to worry about escaping and the such):
$command = base64_encode($command);
exec("php -r 'eval(base64_decode(\"$command\"));'", $output);
You could use eval() instead of what you're posting above.
The main issue here (both with eval() and your exec() code) is that taking PHP code from user input simply isn't safe:
The eval() language construct is very dangerous because it allows execution of arbitrary PHP code. Its use thus is discouraged. If you have carefully verified that there is no other option than to use this construct, pay special attention not to pass any user provided data into it without properly validating it beforehand.
Suggestion
Since you want to return the result of the PHP code, you could potentially do something cool with Ajax, where you pass the PHP code to a script (Base64 encoded, perhaps) as a parameter:
$code = base64_decode($_GET['code']);
// Clean the user input here
eval($code);
Ajax example using jQuery:
// assuming `code` contains the PHP code
var encoded = base64_enc(code);
$.get('execute.php?code=' + encoded, function(data) {
var result = new String(data);
// do something with the result here, such as displaying it
}, dataType='text');
For Base64 encoding in JavaScript, see this.
http://tryruby.org seems have an interactive Ruby shell. That seems to be a good starting point.
Here are two projects that provide such a shell for PHP: php_repl and phpsh.
The other part is the web interface for the interactive shell. For that part, I suggest you have a look at repl.it, which provides this service for many languages (but sadly not PHP). Here's a link to it's source code.
With this combination, you should be able to complete cour project.
Look up 'eval()' and more importantly, why eval() and what you're trying to do is very difficult to achieve in a secure manner. Imaging for example the user who inputs:
echo file_get_contents('/etc/passwd');
You'll need quite a bit of work to make this secure, including watching and filtering all system calls being made from the eval'd process.
Cheers
One guy tried to exploit it using this script
http://www.searchr.us/web-search.phtml?search=%22%3E%3Cscript%3Ealert%28String.fromCharCode%2872%29+String.fromCharCode%28105%29%29;%3C/script%3E
How do i stop it ?
And he also said that it is vulnerable to XSS and LPI...Please help me stop it.
Thanking You,
You need to HTML-encode all user-entered data that you output, including the user's search string.
To be safe, HTML-encode all values that are not explicitly meant to be HTML code.
The quick solution is to:
<?php echo htmlspecialchars($blah); ?>
instead of
<?php echo $blah; ?>
The long solution is to read a book on web site security.
Seeing as how that is a search query string, I'm guessing you're pulling the value directly from the query string and re-displaying it to the user?
Something along the lines of "Your search of 'something' returned 0 results"?
You need to encode any user entered data before displaying it.
I've got PHP and HTML code stored in a database table. When I get this data, I need to echo the HTML and process the PHP. I thought I could use eval() for this, which works, if I do this eval("echo 'dlsj'; ?> EVALED "); I get "dlsjEVALED" printed out.
The problem is, I get a fatal error when I run longer scripts. Things like:
Parse error: syntax error, unexpected '<' in /home/content.php(18) : eval()'d code on line 1
Best advice - never store php and html code in your database. And avoid eval() like the plague.
I can't really tell what's wrong with your code, as you haven't provided enough information. But even if I did have some advice, I don't think I could give it in good conscience.
You should redesign your whole application so that it doesn't require storing such things in the database. I can't imagine why it would be necessary.
just right der...........
eval('?>' . $content .'<?php');
You need to re-open php mode after the EVALED. Apparently you have to do this with <? rather than the full <?php.
As a rule eval is to be avoided. But rules are made to be broken. There's a thread at When is eval evil in php? that gives some less dogmatic advice.
Depending on what you want to do, it might be suitable to use a template file that you source, with text that will vary stored in a local variable prior to sourcing the template.
As for storing code to be executed in the DB... this does happen in some frameworks like Drupal to provide convenient extensibility, but then Drupal is pretty thoroughly scoured for security weaknesses.
Also if you're writing self-modifying code then you need to use eval(). Not sure if anyone has done that in php but it would certainly be interesting.
I would guess that you're trying to eval() something that contains an opening <?php tag. And that leads to the error at hand.
$contents = htmlentities($contents);
echo html_entity_decode(eval($contents));