tags:

views:

682

answers:

5

In php, is there any way to clear/remove all previously echoed or printed items?

For example:

<?php

echo 'a';
print 'b';

// some statement that removes all printed/echoed items

echo 'c';

// the final output should be equal to 'c', not 'abc'

?>

My script uses the include function. The included files are not supposed to echo anything. Just in case someone (ex = hacker) tries, I need a way to remove.

+12  A: 
<?php

ob_start();
echo 'a';
print 'b';

// some statement that removes all printed/echoed items
ob_end_clean();

echo 'c';

// the final output is equal to 'c', not 'abc'

?>

Output buffering functions

The output buffering functions are also useful in hackery to coerce functions that only print to return strings, ie.

<?php
ob_start();
var_dump($myVar);
$data = ob_get_clean();
// do whatever with $data
?>
Matthew Scharley
A: 

Ideally, you shouldn't output anything that you don't ultimately want printed. Keep your logic separate from your presentation for less frustration.

That being said, you can consult the Output Buffering options within PHP.

Jonathan Sampson
+2  A: 

while @monoxide is right, its better to find more intuitive ways of doing the same. e.g.:

<?php
$val_to_print = $a;
if( $need_to_change==true ) 
    $val_to_print = $b;
// when you are sure you won't have to change again...
echo $val_to_print;
?>

Cheers,

jrh

Here Be Wolves
He's concerned about someone changing files on him that he doesn't control, so while you're right, you're not addressing what he's concerned about.
Matthew Scharley
Also, sometimes people overlook EOL's at the end of include files, causing potential havoc if you need to send a header() later...
Matthew Scharley
@monoxide At the risk of going completely off-topic, you can omit the last closing PHP tag at the end of a file which is a good way to eliminate that problem completely.
Josh
A: 

If it is debug output and program status information you are worried about maybe trigger_error may be nearer to what you need, such as:

trigger_error ("Attempting to load report #{$report_id}.", E_USER_NOTICE);

When your script is in production it wont show up any errors as generally they are disabled or logged. It's also best to do fatal errors this way with E_USER_ERROR rather than using die ().

ob_start ();
require ($filename);
$html = ob_get_clean ();

The above will also include a file and give you its contents as a string.

Caveat: Ditching the buffer will also ditch any error messages thrown up, making debugging (potentially) a nightmare.

Meep3D
Or, potentially much better if you use the $html you got from get_clean() and put it in the body of your page instead of screwing up the headers and positioning of most of your page.
Matthew Scharley
A: 

If a hacker let's say has access to your PHP file, he will also be able to remove the statement clearing the output buffer.

If you are doing this because you are letting your users upload PHP scripts, let me tell you that this is an extremely bad idea.

In both cases, doing what you are asking for adds 0 security.

Andrew Moore
I have an ajax function that delivers the file name/location of a file to be included to my php document.I'm using the parse_url function to disallow any values that are absolute paths (before the file is included).The included file is supposed to contain only any array. I wrapped the array in ob_start and ob_end_clean to remove any echoed content.Do you see any potential security issues with that?
Plenty actually. It means your attacker can execute any given php file on your system. You are better of having one php file per array, and call up that file directly.
Andrew Moore
Thanks for the input. For the program to work, the user must be able to add his own array values.In addition to the above, I've also now required that the included file must contain a sub string.For example, the string must contain "bar". "foo.php" cannot be included. "foo_bar.php" can be included. So, as long as there are no other files in the system containing "foo", the program should be secure. Is this right? Thanks again for your help. Much appreciated.
Let's see... "../bar/../../delete_all.php": still will be called. There is simply no way of protecting yourself. Why not store the serialized values into the database and fetch them by id? So you could have "foobar.php?id=20" which is way more secure than foobar.php?file=someArbPath
Andrew Moore
Or another way of going about it is to completely disable pathing elements like '..', that can solve alot of these sorts of security issues.
Matthew Scharley
@monoxide: There are thousand of ways to cleverly mask those...
Andrew Moore
I can't store pre-made values in a database because the script is a JQuery plugin. Users need to be able to enter any relative path. I changed the logic of my script so that the path must be relative (not absolute), the last part of the path must contain "foo" and the file name of the file being included must contain "foo". Will that work?
@ed: The are always ways to escape out of path restrictions. I don't see how jQuery is stopping you from getting data out of the database. It is PHP who will do the work, not jQuery... All you need to do is point jQuery to that PHP file with a proper query string.And if the plugin is really hardcoded in such way that it's impossible to customize it, maybe you should modify the plugin.
Andrew Moore
Here's a related question: http://stackoverflow.com/questions/1066930/sending-variables-for-php-filesystem-functions-with-form-submission