Xss Filtering Function in PHP

XSS filtering function in PHP

Simple way? Use strip_tags():

$str = strip_tags($input);

You can also use filter_var() for that:

$str = filter_var($input, FILTER_SANITIZE_STRING);

The advantage of filter_var() is that you can control the behaviour by, for example, stripping or encoding low and high characters.

Here is a list of sanitizing filters.

Secure XSS cleaning function (updated regularly)

To answer the bold question: Yes, there is. It's called htmlspecialchars.

It needs to be updated regularly to
counter new attacks.

The right way to prevent XSS attacks is not countering specific attacks, filtering/sanitizing data, but proper encoding, everywhere.

htmlspecialchars (or htmlentities) in conjunction with a reasonable decision of character encoding (i.e. UTF-8) and explicit specification of character encoding is sufficient to prevent against all XSS attacks. Fortunately, calling htmlspecialchars without explicit encoding(it then assumes ISO-8859-1) happens to work out for UTF-8, too. If you want to make that explicit, create a helper function:

// Don't forget to specify UTF-8 as the document's encoding
function htmlEncode($s) {
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}

Oh, and to address the form worries: Don't try to detect encodings, it's bound to fail. Instead, give out the form in UTF-8. Every browser will send user inputs in UTF-8 then.

Addressing specific concerns:

(...) you're supposed to use
htmlentities because htmlspecialchars
is vulnerable to UTF-7 XSS exploit.

The UTF-7 XSS exploit can only be applied if the browser thinks a document is encoded in UTF-7. Specifying the document encoding as UTF-8 (in the HTTP header/a meta tag right after <head>) prevents this.

Also if I don't detect the encoding,
what's to stop an attacker downloading
the html file, then altering it to
UTF-7 or some other encoding, then
submitting the POST request back to my
server from the altered html page?

This attack scenario is unnecessarily complex. The attacker could just craft a UTF-7 string, no need to download anything.

If you accept the attacker's POST (i.e. you're accepting anonymous public user input), your server will just interpret the UTF-7 string as a weird UTF-8 one. That is not a problem, the attacker's post will just show garbled. The attacker could achieve the same effect (sending strange text) by submitting "grfnlk" a hundred times.

If my method only works for UTF-8 then the XSS attack will get through, no?

No, it won't. Encodings are not magic. An encoding is just a way to interpret a binary string. For example, the string "ö" is encoded as (hexadecimal) 2B 41 50 59 in UTF-7 (and C3 B6 in UTF-8). Decoding 2B 41 50 59 as UTF-8 yields "+APY" - harmless, seemingly randomly characters.

Also how does htmlentities protect against HEX or other XSS attacks?

Hexadecimal data will be outputted as just that. An attacker sending "3C" will post a message "3C". "3C" can only become < if you actively try to interpret hexadecimal inputs otherwise, for example actively map them into unicode code points and then output them. That just means if you're accepting data in something but plain UTF-8 (for example base32-encoded UTF-8), you'll first have to unpack your encoding, and then use htmlspecialchars before including it between HTML code.

Should I XSS filter all input data?

It should work for making your application very secure, as no user input (besides the user editable $_FILE, $_SERVER) would be susceptible to XSS unless there was a glitch in your library. However, it may adversely affect your servers performance if many people are attempting to access your application. I would write a better function like this:

public function post($key, $validate = true){
if(isset($_POST[$key])){
if($validate===true) {
return validate($_POST[$key]);
} else {
return $_POST[$key]
}else{
return false;
}
}

That way you can choose which post variables you want to validate. It reduces the overall security of your application, but if you use it correctly, you can minimize the impact.

xss filtering for callback functions

//Filtered as well?
$textarea_content = $this->input->post('textarea_content');

No, you didn't set a "prepping" rule in your form validation. In fact, you haven't validated the textarea_content field at all.

Besides that, you haven't run the form validation at the time you set the rules, so passing any POST data into a callback function will be the original data.

Passing post data like that into a callback here, where the rules are just strings, is very dangerous and likely to break your script. Consider:

$_POST['textarea_content'] = ']|var_dump|exit|some_nonsense[';

$this->form_validation->set_rules(
'text_url',
'Website link',
'callback_minimum_fields[' . $this->input->post('textarea_content') . ']'
);

// Produces this rule:
// callback_minimum_fields[]|var_dump|exit|some_nonsense[]

Those "rules" would be injected into your form validation rules, since in this context, it's just a string. It might be better to have your callback read the postdata directly or to take another approach, but this is very unsafe. Even if you xss_clean it first, it doesn't matter.

Once again, I urge you to spend more time understanding what XSS is and then decide if it makes any sense to worry about in this situation. XSS only occurs on output.

XSS filtering on CodeIgniter form

First of all set $config['global_xss_filtering'] = FALSE; You don't need or want this on all the time. This config setting is officially deprecated. It will likely disapear in the future.

Second, if you are using version 3.0.x then remove ‘xss_clean’ from your validation rules. It is not on the officially supported list of form validation rules.

The place where you can employ XSS filtering is when using the Input Class to fetch data from POST, GET, COOKIE or SERVER. Most of the input methods have a second param that enables running the data through xss_clean(). Example: $this->input->post('some_data', TRUE); Will get the value of $_POST['some_data']and run it through xss_clean(). If the second param is FALSE (or omitted) xss_clean() will not be used.



Related Topics



Leave a reply



Submit