Menu Search
Jump to the content X X
Smashing Conf Barcelona

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Content Security Policy, Your Future Best Friend

A long time ago, my personal website was attacked. I do not know how it happened, but it happened. Fortunately, the damage from the attack was quite minor: A piece of JavaScript was inserted at the bottom of some pages. I updated the FTP and other credentials, cleaned up some files, and that was that.

One point made me mad: At the time, there was no simple solution that could have informed me there was a problem and — more importantly — that could have protected the website’s visitors from this annoying piece of code.

Further Reading on SmashingMag: Link1

A solution exists now, and it is a technology that succeeds in both roles. Its name is content security policy (CSP).

What Is A CSP? Link

The idea is quite simple: By sending a CSP header from a website, you are telling the browser what it is authorized to execute and what it is authorized to block.

Here is an example with PHP:

<?php
    header("Content-Security-Policy: <your directives>");
?>

Some Directives Link

You may define global rules or define rules related to a type of asset:

default-src 'self' ;
     # self = same port, same domain name, same protocol => OK

The base argument is default-src: If no directive is defined for a type of asset, then the browser will use this value.

script-src 'self' www.google-analytics.com ;
     # JS files on these domains => OK

In this example, we’ve authorized the domain name www.google-analytics.com as a source of JavaScript files to use on our website. We’ve added the keyword 'self'; if we redefined the directive script-src with another rule, it would override default-src rules.

If no scheme or port is specified, then it enforces the same scheme or port from the current page. This prevents mixed content. If the page is https://example.com, then you wouldn’t be able to load http://www.google-analytics.com/file.js because it would be blocked (the scheme wouldn’t match). However, there is an exception to allow a scheme upgrade. If http://example.com tries to load https://www.google-analytics.com/file.js, then the scheme or port would be allowed to change to facilitate the scheme upgrade.

style-src 'self' data: ;
     # Data-Uri in a CSS => OK

In this example, the keyword data: authorizes embedded content in CSS files.

Under the CSP level 1 specification, you may also define rules for the following:

  • img-src
    valid sources of images
  • connect-src
    applies to XMLHttpRequest (AJAX), WebSocket or EventSource
  • font-src
    valid sources of fonts
  • object-src
    valid sources of plugins (for example, <object>, <embed>, <applet>)
  • media-src
    valid sources of <audio> and <video>

CSP level 2 rules include the following:

  • child-src
    valid sources of web workers and elements such as <frame> and <iframe> (this replaces the deprecated frame-src from CSP level 1)
  • form-action
    valid sources that can be used as an HTML <form> action
  • frame-ancestors
    valid sources for embedding the resource using <frame>, <iframe>, <object>, <embed> or <applet>.
  • upgrade-insecure-requests
    instructs user agents to rewrite URL schemes, changing HTTP to HTTPS (for websites with a lot of old URLs that need to be rewritten).

For better backwards-compatibility with deprecated properties, you may simply copy the contents of the actual directive and duplicate them in the deprecated one. For example, you may copy the contents of child-src and duplicate them in frame-src.

CSP 2 allows you to whitelist paths (CSP 1 allows only domains to be whitelisted). So, rather than whitelisting all of www.foo.com, you could whitelist www.foo.com/some/folder to restrict it further. This does require CSP 2 support in the browser, but it is obviously more secure.

An Example Link

I made a simple example for the Paris Web 2015 conference, where I presented a talk entitled “CSP in Action5.”

Without CSP, the page would look like this:

This page without CSP, ugly and defaced6

View large version7

Not very nice. What if we enabled the following CSP directives?

<?php
    header("Content-Security-Policy: 
      default-src 'self' ;
      script-src 'self' www.google-analytics.com stats.g.doubleclick.net ; 
      style-src 'self' data: ;
      img-src 'self' www.google-analytics.com stats.g.doubleclick.net data: ;
      frame-src 'self' ;");
?>

What would the browser do? It would (very strictly) apply these directives under the primary rule of CSP, which is that anything not authorized in a CSP directive will be blocked (“blocked” meaning not executed, not displayed and not used by the website).

By default in CSP, inline scripts and styles are not authorized, which means that every <script>, onclick or style attribute will be blocked. You could authorize inline CSS with style-src 'unsafe-inline' ;.

In a modern browser with CSP support, the example would look like this:

This page with CSP, really better8

View large version9

What happened? The browser applied the directives and rejected anything that was not authorized. It sent these notifications to the console:

CSP notifications10

View large version11

If you’re still not convinced of the value of CSP, have a look at Aaron Gustafson’s article “More Proof We Don’t Control Our Web Pages12.”

Of course, you may use stricter directives than the ones in the example provided above:

  • set default-src to 'none',
  • specify what you need for each rule,
  • specify the exact paths of required files,
  • etc.

More Information On CSP Link

Support Link

CSP is not a nightly feature requiring three flags to be activated in order for it to work. CSP levels 1 and 2 are candidate recommendations! Browser support for CSP level 113 is excellent.

CSP Level 1 support on Can I Use14

View large version15

The level 2 specification is more recent16, so it is a bit less supported.

CSP Level 2 support on Can I Use17

View large version18

CSP level 3 is an early draft now, so it is not yet supported, but you can already do great things with levels 1 and 2.

Other Considerations Link

CSP has been designed to reduce cross-site scripting (XSS) risks, which is why enabling inline scripts in script-src directives is not recommended. Firefox illustrates this issue very nicely: In the browser, hit Shift + F2 and type security csp, and it will show you directives and advice. For example, here it is used on Twitter’s website:

CSP display on Firefox19

View large version20

Another possibility for inline scripts or inline styles, if you really have to use them, is to create a hash value. For example, suppose you need to have this inline script:

<script>alert('Hello, world.');</script>

You might add 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng=' as a valid source in your script-src directives. The hash generated is the result of this in PHP:

<?php
    echo base64_encode(hash('sha256', "alert('Hello, world.');", true));
?>

I said earlier that CSP is designed to reduce XSS risks — I could have added, “… and reduce the risks of unsolicited content.” With CSP, you have to know where your sources of content are and what they are doing on your front end (inline styles, etc.). CSP can also help you force contributors, developers and others to respect your rules about sources of content!

Now your question is, “OK, this is great, but how do we use it in a production environment?”

How To Use It In The Real World Link

The easiest way to get discouraged with using CSP the first time is to test it in a live environment, thinking, “This will be easy. My code is bad ass and perfectly clean.” Don’t do this. I did it. It’s stupid, trust me.

As I explained, CSP directives are activated with a CSP header — there is no middle ground. You are the weak link here. You might forget to authorize something or forget a piece of code on your website. CSP will not forgive your oversight. However, two features of CSP greatly simplify this problem.

report-uri Link

Remember the notifications that CSP sends to the console? The directive report-uri can be used to tell the browser to send them to the specified address. Reports are sent in JSON format.

report-uri /csp-parser.php ;

So, in the csp-parser.php file, we can process the data sent by the browser. Here is the most basic example in PHP:

$data = file_get_contents('php://input');

    if ($data = json_decode($data, true)) {
     $data = json_encode(
      $data,
      JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
      );
     mail(EMAIL, SUBJECT, $data);
    }

This notification will be transformed into an email. During development, you might not need anything more complex than this.

For a production environment (or a more visited development environment), you’d better use a way other than email to collect information, because there is no auth or rate limiting on the endpoint, and CSP can be very noisy. Just imagine a page that generates 100 CSP notifications (for example, a script that display images from an unauthorized source) and that is viewed 100 times a day — you could get 10,000 notifications a day!

A service such as report-uri.io21 can be used to simplify the management of reporting. You can see other simple examples for report-uri22 (with a database, with some optimizations, etc.) on GitHub.

report-only Link

As we have seen, the biggest issue is that there is no middle ground between CSP being enabled and disabled. However, a feature named report-only sends a slightly different header:

<?php
    header("Content-Security-Policy-Report-Only: <your directives>");
?>

Basically, this tells the browser, “Act as if these CSP directives were being applied, but do not block anything. Just send me the notifications.” It is a great way to test directives without the risk of blocking any required assets.

With report-only and report-uri, you can test CSP directives with no risk, and you can monitor in real time everything CSP-related on a website. These two features are really powerful for deploying and maintaining CSP!

Conclusion Link

Why CSP Is Cool Link

CSP is most important for your users: They don’t have to suffer any unsolicited scripts or content or XSS vulnerabilities on your website.

The most important advantage of CSP for website maintainers is awareness. If you’ve set strict rules for image sources, and a script kiddie attempts to insert an image on your website from an unauthorized source, that image will be blocked, and you will be notified instantly.

Developers, meanwhile, need to know exactly what their front-end code does, and CSP helps them master that. They will be prompted to refactor parts of their code (avoiding inline functions and styles, etc.) and to follow best practices.

How CSP Could Be Even Cooler Link

Ironically, CSP is too efficient in some browsers — it creates bugs with bookmarklets. So, do not update your CSP directives to allow bookmarklets. We can’t blame any one browser in particular; all of them have issues:

Most of the time, the bugs are false positives in blocked notifications. All browser vendors are working on these issues, so we can expect fixes soon. Anyway, this should not stop you from using CSP.

Other Resources And Articles Link

General Information Link

Dropbox’s Series on Its CSP Policies Link

GitHub’s CSP policies Link

Other Companies Link

About Reporting Link

Examples of Directives Link

The Future of CSP Link

(ds, il, al)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/2010/01/web-security-primer-are-you-part-of-the-problem/#further-reading-on-smashingmag
  2. 2 https://www.smashingmagazine.com/2010/06/10-ways-to-beef-up-your-websites-security/
  3. 3 https://www.smashingmagazine.com/2010/10/common-security-mistakes-in-web-applications/
  4. 4 https://www.smashingmagazine.com/2010/01/web-security-primer-are-you-part-of-the-problem/
  5. 5 https://rocssti.net/en/example-csp-paris-web2015
  6. 6 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing1b.jpg
  7. 7 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing1b.jpg
  8. 8 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing5.jpg
  9. 9 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing5.jpg
  10. 10 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing2.jpg
  11. 11 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing2.jpg
  12. 12 https://www.aaron-gustafson.com/notebook/more-proof-we-dont-control-our-web-pages/
  13. 13 http://caniuse.com/#feat=contentsecuritypolicy
  14. 14 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing3.jpg
  15. 15 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing3.jpg
  16. 16 http://caniuse.com/#feat=contentsecuritypolicy2
  17. 17 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing4.jpg
  18. 18 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing4.jpg
  19. 19 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing6b.jpg
  20. 20 https://www.smashingmagazine.com/wp-content/uploads/2016/09/csp_smashing6b.jpg
  21. 21 https://report-uri.io/
  22. 22 https://github.com/nico3333fr/CSP-useful/tree/master/report-uri
  23. 23 https://bugzilla.mozilla.org/show_bug.cgi?id=866522
  24. 24 https://bugs.chromium.org/p/chromium/issues/detail?id=233903
  25. 25 https://bugs.webkit.org/show_bug.cgi?id=149000
  26. 26 http://content-security-policy.com/
  27. 27 http://www.w3.org/TR/CSP/
  28. 28 http://www.html5rocks.com/en/tutorials/security/content-security-policy/
  29. 29 https://securityheaders.io/
  30. 30 https://github.com/nico3333fr/CSP-useful
  31. 31 https://cspvalidator.org/
  32. 32 https://www.w3.org/TR/upgrade-insecure-requests/
  33. 33 https://scotthelme.co.uk/csp-cheat-sheet/
  34. 34 https://blogs.dropbox.com/tech/2015/09/on-csp-reporting-and-filtering/
  35. 35 https://blogs.dropbox.com/tech/2015/09/unsafe-inline-and-nonce-deployment/
  36. 36 https://blogs.dropbox.com/tech/2015/09/csp-the-unexpected-eval/
  37. 37 https://blogs.dropbox.com/tech/2015/09/csp-third-party-integrations-and-privilege-separation/
  38. 38 http://githubengineering.com/githubs-csp-journey/
  39. 39 https://www.wired.com/2016/05/wired-first-big-https-rollout-snag/
  40. 40 https://corner.squareup.com/2016/05/content-security-policy-single-page-app.html
  41. 41 https://oreoshake.github.io/csp/twitter/2014/07/25/twitters-csp-report-collector-design.html
  42. 42 https://github.com/nico3333fr/CSP-useful/tree/master/csp-for-third-party-services
  43. 43 https://speakerdeck.com/mikispag/making-csp-great-again-michele-spagnuolo-and-lukas-weichselbaum
  44. 44 https://www.w3.org/TR/CSP3/
  45. 45 https://github.com/w3c/webappsec-csp/

↑ Back to top Tweet itShare on Facebook

Nicolas is a front-end developer working in Switzerland for more than 10 years, in love with accessibility, progressive enhancement, Opquast (OPen Quality Standards), Open Web, CSP, CSS and everything related to web quality. He has developped several accessible plugins and a CSS microframework named Röcssti. You can find Nicolas on Twitter.

  1. 1

    The end of externally hosted bookmarklets then?

    0
  2. 3

    That’s a bug in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=866522

    Chrome is fine IIRC.

    0
  3. 4

    I recently have been working on implementing CSP on my website. But I had to struggle a lot because I have implemented Google Adsense and Amazon Ads on my WordPress website. Because of the iFrames, CSS, JS and Images loaded by them, I had to put a lot of sources in the header. Though I was able to fix this, but I have heard that the Google Ads’ URLs could be region specific.
    What is your take on this?

    0
    • 5

      Hi Rahul,

      honestly, I never had to manage this case, maybe you should contact them to see if they could provide CSP directives (or test with *.domain.tld using report-only). You got one point: not many services are providing CSP directives (even Google Analytics provided me surprised while retro-ingeniering what was needed as CSP directives), this could be a nice next-step to do for CSP.

      Or maybe nounce attribute could do the job?

      0
  4. 6

    I tested the inline scripts in script-src directives but nothing happened — what’s wrong ?

    Here is my code:

    header("Content-Security-Policy: 
          default-src 'self' ;
          script-src 'self' 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng=';
          style-src 'self' data: ;
          img-src 'self' ;
          frame-src 'self' ;");
    0
    • 7

      Hi, it seems ok. On which browser did you test? It seems it works perfectly on Chrome, but not (yet) on Firefox (?).

      I’ve tested, Firefox seems to be ok with nounce (number used once), a possibility I didn’t mention in the article :

      script-src 'self' 'nonce-wozaaaaa'

      And put this on your inline script:

      alert('Hello');

      Of course, a nounce should be generated each time, and be unique each time.

      2
    • 8

      EDIT: Sorry, the comment has removed some caracters.

      Hi, your directives seems ok to me. On which browser did you test? It seems it works perfectly on Chrome, but not (yet) on Firefox (?).

      I’ve tested, Firefox seems to be ok with nounce (number used once), a possibility I didn’t mention in the article :

      script-src 'self' 'nonce-wozaaaaa'

      And put this on your inline script:

      <script nonce="wozaaaaa">alert('Hello');</script>

      Of course, a nounce should be generated each time, and be unique each time.

      1
  5. 10

    smashingmagazine

    September 13, 2016 2:38 pm

    Issues to Consider Before You Purchase a Server Hosting Plan
    Businesses and individuals looking to get online often cannot decide on the best hosting service to fit their need. There are lots of hosting companies out there offering good plans, guaranteeing over 99% uptime and additional benefits that make it easy for someone with basic computer skills to launch a website.
    However, it’s still going to be difficult for you to choose the appropriate webhost if you do not have enough information on hosting services, especially as regard common issues.
    It’s not when things are running smoothly that one knows a good web host but when there are issues.
    The truth is that if you use a hosting service long enough, some issues will crop up. It’s how those issues are addressed and the measures that are taken to prevent them that separate the best hosting service providers from the rest.
    Below are some of the common web hosting service issues you need to take into account before choosing a web hosting service.
    Poor Website Navigation and Loading Speed
    Your web visitors need to be able to navigate your website easily and quickly if you want to keep them coming back. Good user experience is also important to Google, and loading speed is considered when sites are ranked. If the navigation and loading speed of your website is poor, it will affect your ranking and organic traffic. 75% of web users won’t revisit a website that took more than 4 seconds to load, while 88% of users are less likely to revisit a website after a poor experience.
    The web hosting service you choose plays a big role in your website loading time. If most of your users will be from a particular region or country, check the location of the data center of your host and see how close it is to your users. The closer the data center, the faster the speed.
    Ask your web host about the steps they take to reduce network latency. Network latency affects your website navigation speed. The better the quality of hardware your web host uses, the less network latency you will experience.
    Price of Web Hosting
    It may sound clichéd, but with web hosting you get what you pay for. If the price is below industry price, that may be a red flag that the web hosting service may not be robust enough to handle your website, especially if you are expecting heavy traffic in future.
    Other times, a low service price may just be used to lure you in, but you may have to pay for tools you normally get for free with another web host. Also, make sure that the web host you choose allows you to upgrade easily if your need expand.
    Solving Web Hosting Issues
    How fast your web host responds to issues or problems is important. It’s commonly said that the best service providers are those you don’t have to worry about. However, when a problem crops up or your website is down, you need a web host that will respond to the issue fast.
    You can email the support or call them before you sign up and see how fast and professional they are in responding to your queries. It’s preferable that you choose a service that offers round-the-clock support service all year round, such as the server service @ Umbrellar.
    Some companies have a large FAQ section on their website and expect you to solve issues yourself. If you are not IT savvy, it’s always preferable to use a service that allows you to reach their support easily via the phone or email.
    Web Host Security
    The security of your website and server is important. Ask your web host how they protect their servers from malicious codes, virus, and sophisticated hijacking attempts.
    Also, ensure your web host protects your servers with physical security. Ask how they protect the server from unauthorized access.
    You also need to ask the web host how often they check for server intrusions.
    Finally, ask the web host their plan of action if your website gets compromised. How they answer these questions is a good indication of the professionalism of the web hosting service.
    Limitations of Your Web Hosting Plans
    Depending on the web hosting plan you choose, you are likely going to have some limitations. No hosting plan is perfect, however, it is important that you know the limitations of your plan. A lot of web hosting services do not disclose these limitations.
    For example, while cloud hosting service is very good for a website that gets large traffic spikes, it has data privacy limitations.
    If you’re not sure of the limitations of your plan, call your web host and discuss it with them.
    In conclusion, ensure the core needs of your website are fully catered for before you sign up to a web hosting service.

    Vsmashingmagazine

    ,

    -30

↑ Back to top