NOT about tl;dr in this blog post we are going to give a look at modern browsers's protection with some hands on example available at https://github.com/asanso/browsers-security and deployed in Heroku . This blog post isabout Same-origin policy

Introduction

In this blog post we are going to give a look at modern browsers's protection. More specifically if you are designing a REST API where the result response is driven by some user input, then why not have some help from the browser rather than brewing some ad hoc protection?

I am going to provide some demo deployed in Heroku

If you prefer running them on your machine you might want to clone https://github.com/asanso/browsers-security and drill down into the specific example.

Mind your content type

Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET . By definition entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of themethod, the media type that would have been sent had the request been a

It turns out that returning the proper Content-Type might save a lot of headache.





INSTANT DEMO: https://mysterious-ocean-4724.herokuapp.com/?name=%3Cscript%3Ealert%28document.domain%29%3C/script%3E

Or from your browsers-security check out:

cd contentType

npm install

node helloWorldJson.js

and with the browser hit http://localhost:9002?name=<script>alert(document.domain)</script>

curl -v -L "https://mysterious-ocean-4724.herokuapp.com/?name=<script>alert(document.domain)</script>"





>

< HTTP/1.1 200 OK

* Server Cowboy is not blacklisted

< Server: Cowboy

< Connection: keep-alive

< X-Powered-By: Express

< Content-Type: text/html; charset=utf-8

< Content-Length: 42

< Etag: W/"2a-QK3v/EQbwe/c0QdPJrXydw"

< Date: Wed, 02 Dec 2015 15:16:31 GMT

< Via: 1.1 vegur

<

{"helloWorld": "<script>alert(

document.domain )</script>"}

As you can see we are returning some JSON payload in the response but using the "wrong" Content-Type (aka text/html ). This in combination with a malicious input provided by an attacker will make the browser to happily execute the provided javascript snippet.

Content-Type ( application/json in this example ) will make the browser displaying the JSON text content as in this example



https://mysterious-ocean-4724.herokuapp.com/?surname=%3Cscript%3Ealert%28document.domain%29%3C/script%3E



curl -v -L "https://mysterious-ocean-4724.herokuapp.com/?surname=<script>alert(document.domain)</script>"

< HTTP/1.1 200 OK

* Server Cowboy is not blacklisted

< Server: Cowboy

< Connection: keep-alive

< X-Powered-By: Express

< Content-Type: application/json; charset=utf-8

< Content-Length: 56

< Etag: W/"38-AEX4mYlsmzOHSw8oOicxiQ"

< Date: Mon, 07 Dec 2015 09:39:53 GMT

< Via: 1.1 vegur

<

{"helloWorld":"<script>alert(document.domain)</script>" }



Bonus Part:

The examples above where targetting a stored XSS. Those are cross browsers and if successful (namley some stored javascript is displayed in some not sanitized output) every browser will happiliy execute the javascript. For reflected XSS (where the input is bounced directly in the output) some browsers (Chrome, Safari, IE ) ship with an XSS filter. E.g. try to hit the follow link with Google Chrome

https://mysterious-ocean-4724.herokuapp.com/?title=%3Cscript%3Ealert%28document.domain%29%3C/script%3E



has the result

The XSS Auditor refused to execute a script in 'https://mysterious-ocean-4724.herokuapp.com/?title=%3Cscript%3Ealert%28document.domain%29%3C/script%3E' because its source code was found within the request.

and the XSS is then stopped by the browser. From the other hand Firefox would still be vulnerable. Now of course output sanitization (this is always good BTW) would have stopped this attack but this would have required some effort. From the other hand just returning the rightin this example ) will make the browser displaying the JSON text content as in this example

Re-mind your content type

As returning a "wrong" content type you might imagine that not returning a Content-Type AT ALL is NOT a so great idea :) Indeed there are some browsers (did I say IE :)?) that trying to be extra clever and try to intelligently interpret the response content in order to guess the right Content-Type . In the netsec jargon this is call sniffing. But let's the example talking on its own, using IE ONLY





curl -v -L "https://protected-garden-1595.herokuapp.com?name=<script>alert(document.domain)</script>"





< HTTP/1.1 200 OK

* Server Cowboy is not blacklisted

< Server: Cowboy

< Connection: keep-alive

< Date: Mon, 07 Dec 2015 10:52:54 GMT

< Content-Length: 51

< Via: 1.1 vegur

<

Hello World <script>alert(document.domain)</script>

Content-Type

TIL: mind you Content-Type

Coming soon...

more about Content-Type

nosniff

X-XSS-Protection

Content-Disposition

Content Security Policy (CSP)

Cross-origin resource sharing (CORS)

HTTP Strict Transport Security (HSTS)

Subresource Integrity (SRI)

So lets dig the response using curl:Again if you prefer running in local then clone https://github.com/asanso/browsers-security/tree/master/noContentType Trying to inspect the response we can see the total lack of content type:The solution is obviously is to return the correcthenceThis concludes the part #1. If you like this stuff you might watch this space for: