Storing PHP snippets in MySQL - php

I am storing PHP snippets in a MySQL database, I am using mysql_real_escape_string and all is well unless there is a & in the php code and then I get a MySQL error. Is there another why I should try and store this information?
Thanks

#Peter : unless you're building a website for helping developers, you have no reason to put php code into your database, it's a warning : this is gonna be a big nightmare to maintain/debug. Can't you link your pages to some parameters and then in your code use these parameters to build each request ?
it may seems a simple design solution at the beginning "how god I can do whatever I want in all my pages" but it might be the worse you're taking on your poject.
I don't know how to say this but you should really try to consider an other solution. And i'm not speaing about security : if you have an SQL Injection the guy can execute SQL AND php so he can really take all your system/server down, or even attack bigger site with yours (and then you'll be responsible).
I'm really surprised everyone is fine with it.

Use base64_encode when you save snippet into the database and base64_decode when you retreive it.

First, I am going to go on record and say I wholeheartedly agree with remi bourgarel. This is likely a bad idea.
But, from a technical standpoint here's how I'd do this IF I NEEDED TO:
$php_code = '
<?php
$var = "this is a string";
$var = strtoupper($var);
echo $var;
?>
';
$php_code = bin2hex($php_code);
$db->query("INSERT INTO php_code_snips (text_code) VALUES(x'{$php_code}')");
bin2hex will transform the string $php_code from a binary string to a hex string, and the x'{$php_code}' tells mysql to expect a hex string.
This means the string is stored as a string in the DB, and is fully searchable. But, since all chars are encoded as hex during the INSERT the special chars won't cause a problem.
Documentation:
bin2hex
Mysql Hex Values

Related

How to detect if a string contains PHP code? PHP

I am keeping record of every request made to my website. I am very aware of the security measurements that need to be taken before executing any MySQL query that contains data coming from query strings. I clean it as much as possible from injections and so far all tests have been successful using:
htmlspecialchars, strip_tags, mysqli_real_escape_string.
But on the logs of pages visited I find query strings of failed hack attempts that contain a lot of php code:
?1=%40ini_set%28"display_errors"%2C"0"%29%3B%40set_time_limit%280%29%3B%40set_magic_quotes_runtime%280%29%3Becho%20%27->%7C%27%3Bfile_put_contents%28%24_SERVER%5B%27DOCUMENT_ROOT%27%5D.%27/webconfig.txt.php%27%2Cbase64_decode%28%27PD9waHAgZXZhb
In the previous example we can see:
display_errors, set_time_limit, set_magic_quotes_runtime, file_put_contents
Another example:
/?s=/index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=ctlpy.php&vars[1][]=<?php #assert($_REQUEST["ysy"]);?>ysydjsjxbei37$
This one is worst, there is even some <?php and $_REQUEST["ysy"] stuff in there. Although I am able to sanitize it, strip tags and encode < or > when I decode the string I can see the type of requests that are being sent.
Is there any way to detect a string that contains php code like:
filter_var($var, FILTER_SANITIZE_PHP);
FYI: This is not a real function, I am trying to give an idea of what I am looking for.
or some sort of function:
function findCode($var){
return ($var contains PHP) ? true : false
}
Again, not real
No need to sanitize, that has been taken care of, just to detect PHP code in a string. I need this because I want to detect them and save them in other logs.
NOTE: NEVER EXECUTE OR EVAL CODE COMING FROM QUERY STRINGS
After reading lots of comments #KIKO Software came up with an ingenious idea by using PHP tokenizer, but it ended up being extremely difficult because the string that is to be analyzed needed to have almost prefect syntax or it would fail.
So the best solution that I came up with is a simple function that tries to find commonly used PHP statements, In my case, especially on query strings with code injection. Another advantage of this solution is that we can modify and add to the list as many PHP statements as we want. Keep in mind that making the list bigger will considerably slow down your script. this functions uses strpos instead of preg_match (regex ) as its proven to perform faster.
This will not find 100% PHP code inside a string, but you can customize it to find as much as is required, never include terms that could be used in regular English, like 'echo' or 'if'
function findInStr($string, $findarray){
$found=false;
for($i=0;$i<sizeof($findarray);$i++){
$res=strpos($string,$findarray[$i]);
if($res !== false){
$found=true;
break;
}
}
return $found;
}
Simply use:
$search_line=array(
'file_put_contents',
'<?=',
'<?php',
'?>',
'eval(',
'$_REQUEST',
'$_POST',
'$_GET',
'$_SESSION',
'$_SERVER',
'exec(',
'shell_exec(',
'invokefunction',
'call_user_func_array',
'display_errors',
'ini_set',
'set_time_limit',
'set_magic_quotes_runtime',
'DOCUMENT_ROOT',
'include(',
'include_once(',
'require(',
'require_once(',
'base64_decode',
'file_get_contents',
'sizeof',
'array('
);
if(findInStr("this has some <?php echo 'PHP CODE' ?>",$search_line)){
echo "PHP found";
}

Is it possible to hack a website which use unfiltered GET parameter this way

Is there a way to execute some code on my website, with the following code:
$a = $_GET['a'];
$b = 'abc' . $a;
$c = $a;
And, let's say, there will be no more usage of $a, $b and $c variables in the code - just an assignment and, for example, concatenation. Is it possible to execute some malicious code in this place? (actually I think the answer is no, because then no sanitation would ever be possible at all).
And how about this one (I'm pretty sure, it is vulnerable, if we put some characters into $a, that will be unescaped to commas during some internal http and php proccessing):
$a = $_GET['a'];
$b = "abc $a";
Sorry, I know, this is the basics and silly question, and I should just use some good sanitizer library and don't worry. But I want to be sure, and start with very basics, and I can't say, that the site is 100% secure while it's not getting hacked, I just can say that it is unsecure when one day it occasionally get hacked.
ADDED: Any example of hacking any of this two scripts would be greatly appreciated, I want to hack my own website, which contains code like posted above, to clearly understand, that "in this place, if you program this way, your site will be vulnerable, so you should program it this (another) way.
And, let's say, there will be no more usage of $a, $b and $c variables in the code - just an assignment and, for example, concatenation. Is it possible to execute some malicious code in this place?
No. You have to put the data somewhere where it will be treated as code rather than plain data for there to be a vulnerability. (At least in this context since you don't have to worry about buffer overflows).
And how about this one (I'm pretty sure, it is vulnerable, if we put some characters into $a, that will be unescaped to commas during some internal http and php proccessing):
Again, no. The URL decoding routines themselves don't have any known vulnerabilities, and you aren't putting the data anywhere that a comma will have any significant meaning. Interpolating a string variable into another string is entirely safe. (You might later do something with the resulting string which is unsafe, but that's out of the scope of your question.).
Yes or no, dependant of what is done with this data later.
Yes, if this data is stored, displayed or sent to another systems, because of possible abusing these services (store to SQL could be susceptible to SQLi, display to XSS, etc.). Example:
print($a); // Someone see this in browser or console?
$sqlConnection->insert($a); // Is insert() sanitizing input or not?
No, when You do not use above data processing, and just using it internally like Your examples.
Again, if You output this string even to console or log, it could abuse them and do something undesirable. Better strip unneeded characters from input variables (or take another sanitizing route) and be safe, than sorry after.

PHP - evaluating param

I have following code:
<?php
$param = $_GET['param'];
echo $param;
?>
when I use it like:
mysite.com/test.php?param=2+2
or
mysite.com/test.php?param="2+2"
it prints
2 2
not
4
I tried also eval - neither worked
+ is encoded as a space in query strings. To have an actual addition sign in your string, you should use %2B.
However, it should be noted this will not perform the actual addition. I do not believe it is possible to perform actual addition inside the query string.
Now. I would like to stress to avoid using eval as if it's your answer, you're asking the wrong question. It's a very dangerous piece of work. It can create more problems than it's worth, as per the manual specifications on this function:
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.
So, everything that you wish to pass into eval should be screened against a very.. Very strict criteria, stripping out other function calls and other possible malicious calls & ensure that 100% that what you are passing into eval is exactly as you need it. No more, no less.
A very basic scenario for your problem would be:
if (!isset($_GET['Param'])){
$Append = urlencode("2+2");
header("Location: index.php?Param=".$Append);
}
$Code_To_Eval = '$Result = '.$_GET['Param'].';';
eval($Code_To_Eval);
echo $Result;
The first lines 1 through to 4 are only showing how to correctly pass a character such a plus symbol, the other lines of code are working with the data string. & as #andreiP stated:
Unless I'm not mistaking the "+" is used for URL encoding, so it would
be translated to a %, which further translates to a white space.
That's why you're getting 2 2
This is correct. It explains why you are getting your current output & please note using:
echo urldecode($_GET['Param']);
after encoding it will bring you back to your original output to which you want to avoid.
I would highly suggest looking into an alternative before using what i've posted

PHP making a string useable but not readable

So I am not sure if this is possible,but here we go. I want to be able to create a string that functions as normal ,but is not readable. For example:
$password = "//312(!##()";
then I could go something like.
if($input == $password) {
}
Is there anyway I can possibly do this? I may be talking through a hole in my head, but any help on the subject would help.
You can hash the String:
$pw_hash = "098f6bcd4621d373cade4e832627b4f6" //is the hash of "test"
if ($pw_hash == md5($variable)){
//now you know, the variable is "test",
//without writing it plaintext in the sourcecode.
}
But search for hashes. There are better options than md5. Also google for "salt" and get aware of what's the difference between "hashing" and "encrypting".
From your comments, I believe that you want to hide your php source code when deploy the application. I see many developer usually use the base64_encode encode the original PHP code to be a single string and use eval(base64_decode($str)) in their deployed package.
However, that way can only useful with normal user, we can always use an online tool like http://perishablepress.com/tools/decoder/ (or write your own function) to get the original source :)

What would be a better way of doing the following

if(get_magic_quotes_gpc())
{
$location_name = trim(mysql_real_escape_string(trim(stripslashes($_GET['location_name']))));
}
else
{
$location_name = trim(mysql_real_escape_string(trim($_GET['location_name'])));
}
That's the code I have so far. seems to me this code is fundamentally ... OK. Do you think I can safely remove the inner trim(). Please try not a spam me with endless version of this, I want to try to learn how to do this better.
UPDATE
So after reading some of the responses, I think I have come to understand a good method for safely getting data from a user, storing it and then displaying it back.
When you first load the page
$foo = trim($_GET['foo']);
if(get_magic_quotes_gpc())
{
$foo = stripslashes($foo);
}
Then when you come to use this variable as part of a SQL string, even if not storing the data in the database, you should escape it.
mysql_real_escape_string($foo);
And finally, if reading data from the database and wanting to display it as HTML, such a post on a blog or forum, you should pass the variable using htmlspecialchars
echo(htmlspecialchars($bar));
Would any one like to suggest a better set of functions to use? other then obviously wrapping these functions to make them simpler to call.
Here:
$location_name = trim($_GET['location_name']);
if(get_magic_quotes_gpc()) $location_name=stripslashes($location_name);
Then there is also the SQL injection protection, but don't do this until the very last moment before sticking this var in an SQL query. And even then don't apply the changes to the var itself, but rather a copy. You might want to show $location_name to the user afterwards (for example if the form fails). So
$sql="UPDATE whatever(location) VALUES('" . mysql_real_escape_string($location_name) . "')"
I'm assuming of course that $location_name will end up in the database; otherwise you don't need mysql_real_escape_string.
Finally you want to use htmlspecialchars if you're going to display $location_name on your page somewhere.
Edit: You want to use htmlspecialchars() just before displaying the data (definately don't save data that has already been transformed via htmlspecialchars in your database). In general you want to use escaping functions at the last moment and then on a copy of your var. That way you know that at any point during the script the var is the original one and is not carrying some random escape characters from a transformation that happened somewhere before.
You also know where your escape functions are/should be. sql escaping is near/at your sql query. XSS escaping (htmlspecialchars) is near the part where you display data in a web page.
Finally once you get the grip of things, you could always forego SQL escaping by using PHP's PDO functions. Also in the future you might want to take at look at this: Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?
I am sorry to say but everything in your question is wrong.
First, it has nothing to do with performance, by any means. these functions never become a bottleneck and never cause any performance issue.
Next, You've choose wrong place to get rid of magic quotes. Magic quotes is input data related, not database related. It it is better to make a distinct function and place it in your configuration file, being included into every script. You can use one from here
So, the code become like this:
$location_name = mysql_real_escape_string(trim($_GET['location_name']));
But i strongly advise you not to mix database escaping with anything else, as anything else is optional while database escaping is strict and unconditional.

Categories