On my site, I have a PHP script which takes multiple source files (HTML,CSS, and javascript), optimizes them, embeds them into a page, and caches them (basically compiling my website). Recently, I have added jquery-json (a jQuery plugin for encoding JSON into strings), but part of the code contains multiple slashes (used in some sort of a regex):
var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g,
When this line is processed by the script I mentioned earlier one of the backslashes is removed and results in:
var escapeable = /["\\x00-\x1f\x7f-\x9f]/g,
Also, I have setup a short script to make sure the problem is not being caused by something in the way that the javascript is being processed by the PHP script, and that it is in fact a issue with the way that PHP outputs it:
<?php
$string = 'var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g,';
echo($string); //this outputs: var escapeable = /["\\x00-\x1f\x7f-\x9f]/g,
?>
As you can see by the comment, the problem is the same in the simple script too...
I'm not sure if this is relevant, but I have checked to make sure that magic quotes are off. Also, I am aware of 'escapeable' being misspelled but, that's just the way it is in the jquery-json source code.
So, how do I prevent PHP from removing backslashes from the output?
You may use the nowdoc-syntax(requires PHP 5.3.0 ):
$string = <<<'EOD'
var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g,
EOD;
Related
I am working on a BB code system for a content manager and I want to be able to use something like [code=php]<?php echo "Hello World!"; ?>[/code] in my textarea. Using GeSHi (A syntax highlighter) I have made the following function to parse the code:
function parsecode($codetype) {
$source = file_get_contents("file.php");
$language = $codetype;
$geshi = new GeSHi($source, $language);
echo '<code class="num">', implode(range(1,count(file("file.php"))), "<br />"), "</code>";
echo $geshi->parse_code();
}
This works perfectly fine!
Now this is where the BB code comes in. Using preg_replace I made a simple system that finds and replaces bits of code:
$find = array(
"/\[code\=(.+?)\](.+?)\[\/code\]/is"
);
$replace = array(
'<?php parsecode("$1"); ?>'
);
Yes, for now this means it only reads the language and parses the file "file.php" but eventually I will have this work different, but that's not important for now.
What happens, is that the BB code gets executed correctly, and the result is that it does in fact execute the code, but it does NOT execute the function parsecode() . I made a small adjustment to find out where the problem is, and made it save to a file and it turns out the file contained the following: <?php parsecode("php"); ?> . Which is exactly what it should contain. When I write this line of code in the file, it executes.
Anything submitted in the textarea gets stored in a file, which is then read using fopen() and then echo'd on a different page.
My question: Why does the function not execute & parse the code like it should?
Thanks ahead!
There is only one way to get PHP code to execute within PHP code (change code dynamically) and that is with eval().
http://www.php.net/manual/en/function.eval.php
This let's you dynamically make code and execute it
Please remember this quote though:
"If eval() is the answer, you're almost certainly asking the wrong question. -- Rasmus Lerdorf, BDFL of PHP"
eval() is known for security vulnerabilities and being exploited. Highly not recommended.
However, as long as you're not using user generated code IN the eval you will be fine. You could put a return around it to get the result only in the database.
You could instead achieve the same effect by running this in the script but not replacing it before it's run in the entry but on the forum page itself...
<?php
ob_start(function($buffer){
$buffer = preg_replace("/{%(data_.*?)%}/", '<?php echo $data[\'slot_$1\']; ?>', $buffer);
$buffer = preg_replace("/{%menu_(.*?)%}/", '<?php echo insertNav($_data[\'slot_$1\']); ?>', $buffer);
return $buffer;
});
?>
Trying to use the preview code to replace content with php code. Basically, it is for an editor similar to this one on stack overflow where if you type ** strong text ** = strong text except I'm using it to pull data from a database for a particular item. I am using {%data_#%} to get the # and replace it with $data['slot_#'] just for a reference on what I am doing with this.
If I replace <?php echo $data[\'slot_$1\']; ?> with 'Hello' it echoes out Hello. So why isn't it echoing out the php code?
EDIT
I replaced it with $buffer = preg_replace("/{%(data_.*?)%}/", '$1', $buffer); and it echoes out data_1. It isn't getting the # value and placing it into the php code echoed out. The echoed out code appears to be $data['slot_data_#] instead of $data['slot_#']. It is only supposed to get the number when typing in {%data_#%}
EDIT 2
I finally got the number to echo out. Turns out I had a ( in the wrong spot. Here is my new line: $buffer = preg_replace("/{%data_(.*?)%}/", '<?php echo $data[\'slot_$1\']; ?>', $buffer);.... however, it still is leaving everyhting blank. I know that $1 is now echoing out the correct number, but when I put it into the php code, nothing gets echoed out on the page. And I copied and pasted that php code directly in and replaced the number with $1 so that should be right.
<?php
ob_start(function($buffer){
$buffer = preg_replace("/{%data_(.*?)%}/", '?><?php echo $data["slot_$1"]; ?><?php', $buffer);
$buffer = preg_replace("/{%menu_(.*?)%}/", '?><?php echo insertNav($_data["slot_$1"]);?><?php', $buffer);
return eval($buffer);
});
PHP codes within ob_start are not executed in this way, you should work with an evil function: eval()
Over the past few days, I found that using ob_start() to return php code can only be done via eval() and that it is somewhat of an unsafe code as it leaves you open to php injections. Thank you #revo
I have transitioned over and learned how to code a template engine and used a .tpl file so that users cannot put their own php code into the page and everything gets processed using a php page running in the background using functions (template engine). This prevented me from having to use an eval() code as #revo recommended that I stick away from using this without proper validation (which I'm not sure I want to even have to worry about the validation to be honest).
I wanted to inform everyone who viewed this question of what I learned and would suggest working with template engines & functions and avoid using the method I am recommending in my question.
Thank you #revo for working with me on a possible solution and keeping me informed of vulnerabilities.
I am trying to assign values in javascript assigned from PHP and the use document.write() to output them. The problem is when I do this, a complete blank screen shows up but no errors are ever thrown. But if I take the PHP out and put in a value such as 'ABC' it works. And example of my code can be this:
var comment_text="<?php echo $value['comment_text'];?>";
var bodyelement = document.getElementsByTagName('body')[0];
var newdiv = document.createElement('div');
newdiv.style.textAlign = 'center';
newdiv.style.zIndex = 10001;
newdiv.style.left = (<?php echo $comment_x;?>+getPos('browserwindow',"Left")-23) + 'px';
newdiv.style.top = (<?php echo $comment_y;?>+getPos('browserwindow',"Top")-90) + 'px';
newdiv.style.position = 'absolute';
newdiv.innerHTML = comment_text;
bodyelement.appendChild(newdiv);
I do have an PHP error log and no errors are beign thrown either. The values are retrieved from the database, the probem comes with outputting them.
*UPDATE*
Ok, I had this problem before.
Basically a newline is created like this:
var comment_text="cool Beans
";
I have tried to remove the newline with string replace but doesn't seem to work. Why would a new line like this cause this error?
Your issue is cleary in the output from PHP. If you get a blank page, means you most likely have a PHP issue that is HALTING the processing of said page.
As PHP is parsed before anything is sent to the viewer, this will result in a blank / error page.
When you substitute your $value['comment_text'] for ABC you remove the location that causes the error.
I am going to assume that $value['comment_text'] is either a result of a function, or a Database query, try just outputting the $value['comment_text'] first, then worry about sticking it in JS (which will work if your PHP code works).
As I don't see any of your PHP code, I cannot help you further.
Use
var comment_text=String(<?php echo json_encode($value['comment_text']);?>);
instead of
var comment_text="<?php echo $value['comment_text'];?>";
This will protect you from cross-site-scripting attacks by escaping all special characters like backslashes, quotes or line feeds.
The String(...) ensures that comment_text has type String and is not interpreted as a number (if $value['comment_text'] is has a number type).
If PHP is causing an error (sounds like it is) you can turn on your error reporting to see the issues
error_reporting(E_ALL)
The solution was just using trim.
echo trim($value['comment_text']);
I recommend you use a heredoc for the javascript code with %s in the js. and use sprintf to substitute the variables.
What im trying to do, is use php include within a jquery append attribute. something like this:
$('a.popup[href^=#]').click(function() {
$('body').append('<div id="content" class="popup_block"><?php include( SITE_URL . 'activity/popup.php' ) ?></div>');
My script is in a php file, server side, so that i could accomplish this, but im not sure how to go about it. When it comes to html, css etc. I can combine it and php within the php file, but when it comes to javascript, its the quotes that confuses me, and when and how to use the brackets. This might sound confusing lol. Anyways, does CDATA have anything to do with it? I've never used it before, but I should atleast learn it's use.
The PHP interpreter will only look for <?php and ?> tags and try to evaluate anything in between. It doesn't care about surrounding quotes. You need to make sure though that the result of whatever PHP does is valid Javascript.
var foo = '<?php include 'foo.php'; ?>';
becomes
var foo = 'This is the content of foo.php.';
after PHP is done with it.
If there are any quotes in foo.php, it may become this:
var foo = 'This is the 'content' of foo.php.';
which is invalid Javascript syntax. You'll need to escape any character of foo.php that may cause such invalid syntax, for example with addslashes. This can be quite cumbersome though, so I'd advise to look for an alternative this to begin with.
You can encode the value using JSON, which is definitely syntax safe:
var foo = <?php echo json_encode("Some string with 'quotes'."); ?>;
Generating code in code is always tricky, try to not do it and stick to language neutral data interchange formats like JSON or XML.
If you are 100% sure you don't have any single quotes in your include, there should be no problems with how you have it.
If you want to visualize it, copy all of your generated code from the included php file and paste it right into the main page inside of the append(). See how it looks. This will give you a good idea of what the browser will end up with.
I have a string that has HTML & PHP in it, when I pull the string from the database, it is echo'd to screen, but the PHP code doesn't display. The string looks like this:
$string = 'Hello <?php echo 'World';?>';
echo $string;
Output
Hello
Source Code
Hello <?php echo 'World';?>
When I look in the source code, I can see the php line there. So what I need to do is eval() just the php segment that is in the string.
One thing to consider is that the PHP could be located anywhere in the string at any given time.
* Just to clarify, my PHP config is correct, this is a case of some PHP being dumped from the database and not rendering, because I am echo'ing a variable with the PHP code in it, it fails to run. *
Thanks again for any help I may receive.
$str = "Hello
<?php echo 'World';?>";
$matches = array();
preg_match('/<\?php (.+) \?>/x', $str, $matches);
eval($matches[1]);
This will work, but like others have and will suggest, this is a terrible idea. Your application architecture should never revolve around storing code in the database.
Most simply, if you have pages that always need to display strings, store those strings in the database, not code to produce them. Real world data is more complicated than this, but must always be properly modelled in the database.
Edit: Would need adapting with preg_replace_callback to remove the source/interpolate correctly.
You shouldn't eval the php code, just run it. It's need to be php interpreter installed, and apache+php properly configured. Then this .php file should output Hello World.
Answer to the edit:
Use preg_replace_callback to get the php part, eval it, replace the input to the output, then echo it.
But. If you should eval things come from database, i'm almost sure, it's a design error.
eval() should work fine, as long as the code is proper PHP and ends with a semicolon. How about you strip off the php tag first, then eval it.
The following example was tested and works:
<?php
$db_result = "<?php echo 'World';?>";
$stripped_code = str_replace('?>', '', str_replace('<?php', '', $db_result));
eval($stripped_code);
?>
Just make sure that whatever you retrieve from the db has been properly sanitized first, since you're essentially allowing anyone who can get content into the db, to execute code.