PHP: How to mass replace $_POST[...] with strip_tags($_POST[...])
Asked Answered
M

5

5

I'm currently recovering from a nasty XSS attack, and realized I never sanitized inputs on several of the forms on my site. I used Notepad++'s Find In Files feature to search for $_POST in all my PHP files, and got almost 5,000 results. Now, I really don't want to go and manually add strip_tags to every one of those results, but a replace-all wouldn't do the trick... and I'm a total noob when it comes to things like regular expressions.

Is there any way to make this a little less tedious?

Mir answered 25/8, 2010 at 4:35 Comment(0)
B
18

Just use array_map().

$Clean = array_map('strip_tags', $_POST);

Or if you want it to go back to the $_POST variable:

$_POST = array_map('strip_tags', $_POST);

It's probably a better idea though to use a different variable and change all occurrence of $_POST to $Clean in your files.

Bordelaise answered 25/8, 2010 at 4:59 Comment(0)
C
8

Hmm, I think array_walk_recursive would do the trick:

function custom_strip(&$val, $index) {
   $val = strip_tags($val);
}
array_walk_recursive($_POST, 'custom_strip');
Crypt answered 25/8, 2010 at 4:46 Comment(1)
This method worked for my case, where I had some form fields passed as arrays. Thanks!Ramsgate
J
2

you can put this in a file (e.g safe.php)

foreach ($_POST as $key => $value) {
  $_POST[$key] = is_array($key) ? $_POST[$key]: strip_tags($_POST[$key]);
}

Then put require_once("safe.php"); in every each of your php files (or a file that all of your php file already included )
It's an ugly hack.. but it may save your time.

Jungle answered 25/8, 2010 at 4:45 Comment(2)
This will fail to protect from XSS when there are form fields whith names like foo[bar] or foo[] which PHP automatically converts to arrays.Whidah
@Tgr: yeah, this will absolutely fail like you said, but I think he got the idea to customize according to what he needJungle
F
0

Very simple. Put this on top of your every file OR in a common header file which gets called in the very beginning every time:

function mystriptag(&$item)
{
    $item = strip_tags($item);
}

array_walk($_POST, mystriptag);
Filing answered 25/8, 2010 at 4:51 Comment(1)
This will fail to protect from XSS when there are form fields whith names like foo[bar] or foo[] which PHP automatically converts to arrays.Whidah
W
0

You could just array_map strip_tags to $_POST, but it is much nicer to write a custom function for obtaining data from it:

function post_data($name) {
    global $post_cache;
    if (in_array($name, $post_cache)) {
        return $post_cache[$name];
    }
    $val = $_POST[$name];
    if (is_string($val)) {
        $val = strip_tags($val);
    } else if (is_array($val)) {
        $val = array_map('strip_tags', $val);
    }
    $post_cache[$name] = $val;
    return $val;
}

This will make your code more readable (others looking into it will generally assume that $_POST['foo'] is the data in form field foo, not somethin you have already preprocessed), won't cause you problems with plugins or libraries which try to access $_POST directly, makes it easy to add more logic to $_POST preprocessing (unescape when magic quotes are enabled is a common one) without hunting down all the places in your code where you have used POST data, and saves you from huge headaches when you realize there are a few POST fields where you do need HTML tags. Generally, it is a really bad idea to directly change any of the superglobals.

Also, it is better to sanitize data on output, not on input. Different uses will require different methods, for example, if you use

<div class="user_photo">
   <img src="<?php echo photo_path($user_id) ?>" alt="<?php echo $user_name ?>" />
</div>

then $user_name is an XSS attack vector, and strip_tags does not help against it at all; you would need htmlspecialchars. If user data is used as an URL, you would need yet another method to defend against javascript: URLs and so on.

Whidah answered 25/8, 2010 at 5:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.