Welcome Guest, Not a member yet? Register   Sign In
how to prevent XSS when $_POST['foo'] contains html?
#1

[eluser]davdtm[/eluser]
I have a variable $_POST['foo'] which should be sent to output but contains html tags (html inputs). How can I prevent XSS in such case? I cannot use xss_clean, nor htmlspecialchars because they would print the html as strings instead of inputs by coding the html tags (or stripping them out).
Do I have to provide a white list with the allowed tags? Which is the practical way to do this? Are there better solutions?

As example, let's assume the variable is something like

$_POST['foo']="<input type="text" name="user_name" />";

and my (unfiltered) view looks like:

print("Please, tell me your name: ".$_POST['foo']);

Thanks, best regards

Davide
#2

[eluser]gRoberts[/eluser]
You can use $_POST although you should really use $this->input->post('foo') instead.

You can pass a second parameter to post() that determines whether to XSS clean the value before handing it back and if you pass false or omit it, it should return your posted HTML code without being filtered.

This assumes you have Global XSS filtering turned off and using $this->input->post('foo', true) on all other fields to XSS filter before using it.
#3

[eluser]Matalina[/eluser]
You could just decode them again. http://us.php.net/manual/en/function.htm...decode.php

I would still specify which tags are allowed. If you decode harmful html/php you are still in trouble.
#4

[eluser]davdtm[/eluser]

gRoberts, thanks for replying. However, besides the fact that using $this->input->post('something') returns null when the key 'something' does not exist instead of trowing an error, I don't see many other reasons to use it. Ok, if I also need xss cleaning I can exploit the second optional parameter but this seems more a shortcut of $this->security->xss_clean($_POST['something']); than a true gain, i.e. another way to get the same result (maybe just more readable).
Anyway, my question was different. If my posted variable does contain some html which should be kept on output, how can I enforce XSS security (or there's a way to enforce or strengthen it)? I ran some test and it seems that xss_clean does more or less the same job as htmlspecialchars, as far as the final output is concerned, thus if I pass html inputs through pages via POST (or GET) I must not filter/encode them (no xss_cleaning/no htmlspecialchars) to get them working within the target view.

Thanks

Dav
#5

[eluser]davdtm[/eluser]
Matalina, I think what you suggest is potentially dangerous, for the reasons you already pointed out. I was looking for some "best practice" to follow in these cases, I think it's something very popular. Many forums, chat rooms, rss feeds, and so on allow html on output, often coming from users. What is the standard strategy to enforce XSS security in such cases? Is there something already available within codegniter I can exploit?

Thanks

Dav
#6

[eluser]Matalina[/eluser]
Every forum software I've maintained has html tags in their configuration admin panels. You can use a, i, b, strong, em etc... a set of defaults that can be changed by the admin user.

It is also why they introduced bbcode as well.
#7

[eluser]davdtm[/eluser]
So, if I've well understood, there's nothing better than a whitelist which allows only some predefined tags? It's not trivial in my case, because my $_POST['foo'] variable may contain html like the following:


<input type="text" name="XXX" id="YYY" class="class1 class2 ..." ... />

thus inputs with, in principle, any kind of attribute (also inputs of different type). It's more complicate than just allowing <em> or <strong> tags. I hoped there was something already done in this sense, maybe within codeigniter, but from your words it seems not.

Thanks anyway

Dav
#8

[eluser]aquary[/eluser]
The problem here is you didn't follow the "best practice" from the start. The "error" you would like to see is something should never be seen, else, you aren't doing it in a good way.

Your code here,
Code:
// NEVER get a POST array direcyly without checking
$something=$this->security->xss_clean($_POST['something']);
// CHECK before
if(isset($_POST['something']))
    $something=$this->security->xss_clean($_POST['something']);
// BUT it's better have to make a default value so you don't have to do it after
else
    $something=NULLl; // or FALSE or whatever similar

Now imagine you have 20 values to use, you have to repeat it like this for 80 lines. That's why CI do it for you. They check it inside and return FALSE when there is nothing to be returned. Then it's YOUR duty to determine what to do when such thing happen.

Back to the topic, it seems what you are looking for is not about xss. xss cleaning IS NOT ONLY about removing HTML tags. It's to prevent elements that could be used to exploited XSS, which is not what you want. You'd need to xss_clean to remove exploitable part, and use a whitelist on strip_tags() too allow some tags before displaying them. Strip_tags will not remove any attributes inside those allowed tags.

Code:
// All javascript, script, applet, embbed, etc, gone.
$something=$this->input->post('something', TRUE);
// Remove all HTML, but allow anything in the whitelist
echo strip_tags($something, "<p><a>&lt;input&gt;&lt;img>");
#9

[eluser]davdtm[/eluser]
aquary, thanks for your explanations but I already know how $this->input->post('something', TRUE) works. The useful feature of returning a null value when the variable is not set is not crucial for me (I mean, in this special case), I'm sure my variables are set and they contain valid html inputs. Let's assume this is true and let's star from here.

The question is: how can I pass a valid html input through post being reasonably sure that someone else cannot inject some evil code? Well, someone can always inject it, but if he does I'd like to have some strategy to strip it out within the target view, before outputting it. I cannot use the plain xss_clean function, as you suggest, because within such function there are lines which act somehow like htmlspecialchars(), those having this comment on the top:

* Sanitize naughty HTML elements
*
* If a tag containing any of the words in the list
* below is found, the tag gets converted to entities.
*
* So this: &lt;blink&gt;
* Becomes: &amp;lt;blink&amp;gt;

in my case, &lt;input&gt; becomes &amp;lt;input&amp;gt;

xss_clean does not accept any whitelist to skip this check for given html tags, so I'm stuck. No xss_clean, no htmlspecialchars/htmlentities can be used if I want my inputs working. There's just your last suggestion which may be helpful, even if it sounds "weak" (but better than nothing), that is using strip_tags which does accept a whitelist. The final question is: is there anything more I can do? Another question might be: wouldn't be useful to add some optional parameter to xss_clean to accept whitelists?

thanks, best regards

Dav




Theme © iAndrew 2016 - Forum software by © MyBB