Why doesn't CodeIgniter's XSS filter clean all? - codeigniter

Why does CodeIgniter's XSS filter only react through regular expressions on specific things instead of sanitizing all input in the first place regardless if the content is tainted or not? Also, why is this done during input and not on output (like it's supposed to be?)

Why does CodeIgniter's XSS filter only react through regular expressions on specific things instead of sanitizing all input in the first place regardless if the content is tainted or not?
This doesn't make much sense. How are we to tell whether or not something is "tainted" without checking it first?
By the definition of CI's xss_clean(), we don't always want to sanitize input. As you mentioned, it's the output that matters - and that's where we need to be mindful of XSS atacks. If we always "sanitize" input with CI's xss_clean(), then how would I, for one example, be able to post javascript or PHP code examples on my blog, or let users do it in the comments? It would end up getting [removed].
Also, why is this done during input and not on output (like it's supposed to be?)
You do have the option to enable the global xss filter in your CI config, which will run xss_clean() on $_POST, $_GET, and $_COOKIE data automatically before you can get your hands on it. This is the lowest level possible to protect you from yourself, bu the option is always available to instead clean the data explicitly. For example:
// With the Input class on $_POST data
$this->input->post('username', TRUE); // Second parameter runs xss_clean
// Using the Security class on any data
$this->security->xss_clean($username);
// Using the Form Validation class to automatically clean the input
$this->form_validation->set_rules('username', '', 'xss_clean');
Since you could still simply use $_POST['username'] instead, by enabling the global filter it will already be xss_cleaned for you. This is the lazy way to do it, and unfortunately once those globals are cleaned, there's no way to undo it.
If you are already aware of when and where XSS attacks can happen - you have the function easily available to use if you wish. Keep in mind that this does not magically make all data "safe", it merely prevents some of the more malicious code injection. Something more harmless like </div> will get past this filter. You should always be sanitizing input explicitly in an appropriate way for the context in which it is used.

Related

Symfony2 validation filters

In my Symfony 2 application I need to filter input before passing it on to validation [1], however, I can't seem to find any system within Symfony to do this.
The type of filtering I looking for is e.g. to be able to filter a dash out of a specific field before validating it. E.g. users can enter 123-123 but the only accepted value is 123123. Just as I can set up validation rules with constraints, I'm looking for something similar for filters.
[1] http://symfony.com/doc/current/book/validation.html
Nifr's answer is good but is missing of an important alternative that, if I understand correctly your question, seems to fit perfectly your needs.
You can use a hook that is pretty much an event listener: if something happens or is going to happen, it intercepts the event and redirect it to your function.
In this case, you need a PRE_BIND hook (is deprecated since 2.3 version, now it's called PRE_SUBMIT)
Read this if you need help about
Either write your own Validation Assert to filter and then proxy the other validators for this purpose ...
... or one or multiple Regex Asserts.
... or use a DataTransformer to transform/filter the input.
With the DataTransformer involved you could aswell consider creating a new FieldType which renders two inputs with a seperator like the date form-field does. ( if not not used with widget => single_text )

Caching with codeigniter and twig

I'm trying to cache my output. I'm using Codeigniter's built-in feature $this->output->cache() but it doesn't work. My guess is because I'm using twig. Any ideas?
I found the answer, may it be useful for whoever pass here.
$output = $this->twig->render('template.html'); // use render instead of display
$this->output->set_output($output); // use CI's output (autoloaded by default) manually
$this->output->cache(5); // cache for 5 minutes, doesn't matter where this line is in the function.
As you discovered yourself, you should map output to the Output class via one of the appropriate methods in order to take advantage of its built-in caching features. Note that CI 3.0 currently in development on Github has some updates that you may like (gzipped cache files that retain all output headers, for example).
You could extend the Loader library with a customized view() method, and perform the logic there as well, rather than needing 2+ lines in each controller (if you wanted to load multiple files, you'd have to call render() then append_output() every time).
I did exactly that with the Smarty template library. Should be able to do something similar with Twig. (I've been meaning to port it over as well, but haven't had the time.)

How can I validate HTML input to prevent XSS?

For example, StackExchange whitelists a subset of HTML:
https://meta.stackexchange.com/questions/1777/what-html-tags-are-allowed-on-stack-exchange-sites
How could you do that in your controller to make sure user input is safe?
This approach is not identical to StackExchange, but I found the AntiXSS 4.x library to a simple way to sanitize the input to allow "safe" HTML.
http://www.microsoft.com/en-us/download/details.aspx?id=28589 You can download a version here, but I linked it for the useful DOCX file. My preferred method is to use the NuGet package manager to get the latest AntiXSS package.
You can use the HtmlSanitizationLibrary assembly found in the 4.x AntiXss library. Note that GetSafeHtml() is in the HtmlSanitizationLibrary, under Microsoft.Security.Application.Sanitizer.
content = Sanitizer.GetSafeHtml(userInput);
This can be done before saving to the database. The advantage is removing malicious content immediately, and not having to worry about it when you output it. The disadvantage is that it won't handle any existing database content, and you do have to apply this any time you're making database updates.
The alternate approach is to use this method every time you output content.
I'd love to hear what the preferred approach is.
You can try JSoup parser which along with sanitizing your HTML input will also provide many functionalities out of the box.
You can visit http://jsoup.org/ for more details on the JSoup and download the binary from there.
It provides DOM method to traverse through your HTML tree and get desired elements.
Although sanitizing your HTML generated code to prevent XSS attack is a goodd practice, but I would strongly advise to avoid using any parser to avoid XSS attach by sanitizing your HTML input.
If your HTML tree is very big then the response time would increase manifold.Instaed of sanitizing your HTML tree you should ensure that whatever user is entering in the FORM is proper and as per the expected value.
You can visit www.owasp.org to know more about how to avoid XSS attack.The site provides you possible cheat sheets to ensure your HTML tree is free from any XSS attack.
ASP.NET HttpUtility.Htmlencode() makes it for you.
But if you want to block dangerous scripts, first DO NOT insert it to your database. First, clean the HTML Text before inserting to database.
I found a class that do it for you: http://eksith.wordpress.com/2012/02/13/antixss-4-2-breaks-everything/
It works fine and you can add new tags and attributes to custom whitelist of the Sanitizer.
Note: Microsoft Sanitizer and Anti-XSS Library was not useful for me. May be you can also try them.

CI uri_string() Validation required?

I use codeigniter as my framework and in the top of my controllers I am going to add a line of code that will send the uri_string (the last page the user requested) to a library which will send it into the users session and possibly eventually into a database.
My question is whether or not I need to validate this uri_string() at all or whether it is safe as is?
Simple answer, if in doubt validate it.
For the short time it will take you to code it you will have peace of mind.
Also, if this is going to happen for all you controllers may I suggest that you either add the function call to the construct of each controller or extend the core controller to include the call in its construct.
Keep in mind that the 'permitted_uri_chars' item in config.php will automatically prohibit any URL that contains non-permitted characters. So, as long as you haven't modified that to include potentially malicious characters, you should be ok. From the comments in config.php:
By default only these are allowed: a-z 0-9~%.:_-
However, as Rooneyl mentions, it probably wouldn't hurt anything to sanitize it anyway.

xss protection and html purifier

I am currently using the CodeIgniter framework, and looking to strengthen the XSS protection by using HTMLPurifier (http://htmlpurifier.org/).
Is my understanding correct that you want to 'clean' data on post, so that its purified before its inserted into the Database? Or do I run it before displaying in the view?
If so, do I want to run HTMLPurifier on every single post that takes place? Since the app contains a lot of forms, I'd hate to have to selectively choose what gets cleaned and what doesnt - assuming that I can intercept all posts, is this the way to go? Of course, I validate some fields anyway (like email addresses, numeric numbers, etc)
Use $this->input->post() to get $_POST data. Codeigniter filters it automatically if global xss filter is set to true.
See the docs: http://codeigniter.com/user_guide/libraries/input.html
Edit: to clarify
Yes you should filter before inserting into the DB and yes you should filter all user input.
A quick google search, http://www.google.com/search?q=codeigniter+htmlpurifier, led to this page: http://codeigniter.com/wiki/htmlpurifier which is a helper for htmlpurifier. Regarding catching all $_POST data: you have to do something with the data, right? In your models, when you're doing that something, just make purify() part of that process:
$postdata = purify($_POST);

Resources