I’m working on a website witch allows users to submit blog posts, however, there seems to be a little problem. I’m using global_xss_filtering (TRUE) so everything will be filtered out.
But, when I’m using xss_filtering HTML tags like etc is being removed. If I set the global_xss_filtering to FALSE everything works great.
But how can I make this work with global_xss_filtering set to TRUE and secure at the same time? Any suggestions?
……………………………………..
The issue is this:
When you have global xss_clean on, all $_GET, $_POST, and $_COOKIE data is cleaned by the Input class constructor via _sanitize_globals().
This happens too early in CI execution for you to do anything about it later. Once the data has been xss_cleaned, it’s impossible to un-clean it.
You have two options:
Use a pre-system hook
Disable the global xss_clean
I don’t have any advice on using a hook for this, but I do recommend simply disabling the global xss_clean for a few reasons:
Obvious: It won’t alter the data, and puts you in control, encouraging you to be mindful of when and where XSS attacks can actually occur.
The xss_clean function is pretty heavy and aggressive, and most of the time you don’t need it. Running it on every post, get, and cookie item eats up execution time.
It’s quite easy to add xss_clean as a form validation rule, or use $this->security->xss_clean()
As a best practice, you should still be sanitizing your data and HTML output anyways, instead of trusting the global filter and forgetting about it.
I needed to allow
Short version: You can't.
Long version: Filtering HTML to remove evil things is a tricky business. It's not enough to blacklist tag types to prevent tags like script or frame, because HTML is constantly changing. Even if you did keep track of all new tag types, attackers can attach Javascript to image onload calls. Even if you managed to filter out all tag attributes that call Javascript without removing useful stuff like src or href or height (which is near impossible, because there's a billion of them), you're still not secure. You can't be sure that every browser implements every tag correctly. Further, you can't be sure that current implementations will never change. New bugs may be introduced.
Trust me, using something like markdown or rst or BBCode is a thousand times easier to secure.
............................................
Before you apply the XSS validation you could htmlentities() and then when you fetch it from the db you could html_entity_decode().