In OWASP among
top ten serious issue XSS holds a prominent position. Though this article is not
about explaining “what an XSS attack is”, but
at the same time I feel like to explain it in brief so that we can understand
the importance of implementation protection against it. No doubt XSS can be
found to a lot of sites.
What is cross-site scripting?
Cross-site scripting is a client side attack
vector. If web application is not properly sanitizing the user input before it is outputted to the browser, then site might be susceptible
for a XSS attack.
One of the most common ways to detect if a site is
infected with this kind of vulnerability;
// Paste this into an input-field shown over the
website
<Script>alert ('XSS is here');</script>
On posting the above string to the web
application , if browser greeting you with an alert popup, then it is clear that
we’ve successfully injected a piece of JavaScript into the page
There’s generally three types of XSS attacks.
- The first is a persistent vulnerability or a stored XSS, where the server saves the input in server side database and renders it out to other users who visit that URL.
For example a forum where the posts aren’t properly sanitized, if you
write a post containing the payload, each and every one of the users who will
read that post are going to evaluate that piece of JavaScript.
Look at the screenshot it is blog (where I have injected my comment as
below)
Payload:
<a href=’http://evil.com’>click here</a>
Now let us look at the database whether injection is there or not? So we
can see that injection is stored in database of website without any
sanitization of input.
So now when a visitor will click on my comments he will be redirected to
evil.com or similarly attacker controlled website (This also covers kind of web
attack on the line of XSS: html injection)
- The second type is a non-persistent XSS vulnerability (known as a reflective injection). This is something you usually find in search forms/input boxes, when you search for something the page will render out the result, but will also write out the exact search-term that you used. If the search-term isn’t sanitized you’ll be able to exploit it.
// Example of a malicious URL
http://www.example.com/search/<script>alert
('xss') ;</script>"
Look at the picture below where web page provided us hostname/ip to
look, but instead a valid input, if attacker inject a malicious JavaScript then
page will reflect back the user input
3. The third, and probably one of the hardest to
exploit is known as DOM injection. Where a user can inject a payload during
runtime and get the script to be evaluated.
For example
if you have an input field, where the user can enter something, and when the user
clicks on the button the input field data is entered into a DOM element. If the
user inputs a script-tag, and the application doesn’t sanitize the data, the
script tag will be evaluated by the browser once it’s written out in the DOM
element.
The below screenshot of one of DOM based XSS which
I have found in MediaFire.com
To study more about XSS please refer OWASP
site.
So far you must be thinking what is the big deal
about it ,I mean who cares if somebody gets a popup or not .
So here is word of caution that XSS are not only
meant for client side attack, but at the same it can lead to critical web based
vulnerability.
Suppose I crafted a payload that can read all the
cookies from your browser and then sends those cookies to my server. Once I
have those cookies I could potentially hi-jack your session and gain
administrative rights of your account.
So How to protect against XSS?
In order to protect your website, and your users we
can do following things:-
·
Sanitize all the data before that is rendered out
to the browser. There are so many anit-XSS functions are available as per the
framework you are using.
Suppose if
you’re using PHP, strip_tags will probably be the easiest way to handle the
data. The biggest problem with strip_tags is that it removes every tag that it
finds.
A generally
nicer solution is to pass everything through htmlentities, which translates all
special characters to their html entity equivalent (i.e. the character < becomes
<).
This means
that everything the user enters will come out, but because it’s been converted
to the html characters the browser won’t try to (and frankly, can’t) evaluate
it.
1. /* sanitizing user generated content.*/
2. echo htmlentities('<script>alert("xss is
here ");</script>');
3. // This will output;
4. // &lt;script&gt;alert(&quot;xss
is here &quot;);&lt;/script&gt;
But because a code base can become humongous, and
you might need rely on third party libraries or frameworks, making sure that
everything is cleaned properly is going to be pretty cumbersome.
So what can we do here?
allowed to parse inline styles or run inline JavaScript
(which an XSS attack essentially is).
Now keep in mind, before I go any further, that content security policy is not a free card, you’ll still need to sanitize everything, you should treat this header as the last line of defence, kind of insurance policy
Content security policy.
CSP defines
the
Content-Security-Policy
HTTP header
that allows you to create a whitelist of trusted content, and instructs the
browser to only execute or render resources from trusted sources. Therefore if
an attacker has found a hole through which he can inject script, the script
won’t match the whitelist, and therefore won’t be executed.
However CSP
is pretty strict .One of the key features with CSP is that we can tell the
browser to invalidate all inline JavaScript, this has the side effect of not
allowing you to add any of your own JS in the DOM tree (because the browser has
no way of differentiate between your scripts and maliciously injected scripts).
You can turn off this feature, but by doing so
the whole point of CSP will be lost, and no extra protection will be given.
We can also
add different domains that are allowed to load content to your page by default
no content is allowed to be loaded at all.
The code
below will allow the default src of loading script is :self or domain itself
// Set the default source to the own domain.
Content-Security-Policy: default-src 'self';
If
you are using PHP then we can set a header like this
Header ("X-Content-Security-Policy:
allow 'self'");
Apart from above that we can also set the policy for images, stylesheets videos, scripts etc
As the
possible combinations and needs are endless, therefore implementation will
largely depends on the requirement of admin:
You can have
look at the link below to see all possible combination:
http://www.html5rocks.com/en/tutorials/security/content-security-policy/
How to implement this?
There are
two ways to implement the header depending on how you need to use it.
As we have already mentioned earlier
that CSP is sent an HTTP header. Setting HTTP headers can be done directly on
the server in your server's configuration file.
1. So the first way to implement it
to add in your webserver config files.
# Apache config
Header set Content-Security-Policy
"default-src 'self';"
# IIS Web.config
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="default-src
'self';" />
</customHeaders>
</httpProtocol>
</system.webServer>
# nginx conf file
add_header Content-Security-Policy
"default-src 'self';";
This means
that the header will be sent no matter what.
Alternatively,
many programming languages / frameworks support adding HTTP headers
programmatically—such as PHP's header, or Node's setHeader—so you
could use these to set your CSP header:
# PHP example
header("Content-Security-Policy: default-src 'self'");
# Node.js example
request.setHeader("Content-Security-Policy", "default-src 'self'")
It’s
important to note that in some kind of platform like WordPress, magneto, Drupal
etc. we can’t generally control the admin area, so implementation of CSP headers
requires a different approach which I will discuss in my next article
Signing off for Now....
0 comments:
Post a Comment