Web Application Security

Web Application Security

Best practices

Appliance (OVF)

Content Security Policy (default Nginx)

Basic security is taken into nginx and mod_security. Nginx adds a header for content security policy.
You can change this headers to your needs to create a whitelist of trusted sources so that browser only executes trusted scripts. Also its possible to add these header in your TrustBuilder response. This should be looked at while implementing TrustBuilder.

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; img-src 'self'";

Example adding apis.google.com scripts header

Content-Security-Policy: script-src 'self' https://apis.google.com

You can use different kind of sources : * connect-src : limits the origins to which you can connect (via XHR, WebSockets, and EventSource) * font-src : specifies the origins that can serve web fonts. Google's Web Fonts could be enabled * frame-src : lists the origins that can be embedded as frames * img-src : defines the origins from which images can be loaded. * media-src : restricts the origins allowed to deliver video and audio. * object-src : allows control over Flash and other plugins. * style-src : is script-src's counterpart for stylesheets.

By default, directives are wide open. If you don't set a specific policy for a directive, let's say font-src, then that directive behaves by default as though you'd specified * as the valid source (e.g. you could load fonts from everywhere, without restriction). You can override this default behavior by specifying a default-src directive. This directive, as you might suspect, will define the defaults for any directive you leave unspecified.

Regardless of the header you use, policy is defined on a page-by-page basis: you'll need to send the HTTP header along with every response that you'd like to ensure is protected
The source list in each directive is fairly flexible. You can specify sources by scheme (data:, https:), or ranging in specificity from hostname-only (example.com, which matches any origin on that host: any scheme, any port) to a fully qualified URI (https://example.com:443, which matches only HTTPS, only example.com, and only port 443). Wildcards are accepted, but only as a scheme, a port, or in the leftmost position of the hostname:*://*.example.com:* would match all subdomains of example.com (but not example.com itself), using any scheme, on any port.

Four keywords are also accepted in the source list: * 'none', as you might expect, matches nothing. * 'self' matches the current origin, but not its subdomains. * 'unsafe-inline' allows inline JavaScript and CSS * 'unsafe-eval' allows text-to-JavaScript mechanisms like eval

These keywords require single-quotes. script-src 'self' authorizes the execution of JavaScript from the current host. script-src self allows JavaScript from a server named "self" (and not from the current host), which probably isn't what you meant. It should be clear that CSP is based on whitelisting origins, as that's an unambiguous way of instructing the browser to treat specific sets of resources as acceptable and to reject the rest. Origin-based whitelisting doesn't, however, solve the biggest threat posed by XSS attacks: inline script injection. If an attacker can inject a script tag that directly contains some malicious payload

<script>sendMyDataToEvilDotCom();</script>

The browser has no mechanism by which to distinguish it from a legitimate inline script tag. CSP solves this problem by banning inline script entirely. You'll need to move the content ofscript tags into an external file, and replace javascript: URLs and with appropriate addEventListener calls.

Example : 
<script>
  function doAmazingThings() {
    alert('YOU AM AMAZING!');
  }
</script><button onclick='doAmazingThings();'>Am I amazing?</button>

You must change the script to :

<!-- amazing.html --><script src='amazing.js'></script><button id='amazing'>Am I amazing?</button>

and put the javascript seperate 

amazing.js
function doAmazingThings() {
  alert('YOU AM AMAZING!');
}
document.addEventListener('DOMContentReady', function () {
  document.getElementById('amazing')
          .addEventListener('click', doAmazingThings);
});

The rewritten code has a number of advantages above and beyond working well with CSP; it's already best practice, regardless of your use of CSP. Inline JavaScript mixes structure and behavior in exactly the way you shouldn't. External resources are easier for browsers to cache, more understandable for developers, and conducive to compilation and minification. You'll write better code if you do the work to move code into external resources. If you really, absolutely must have inline script and style, you can enable it by adding 'unsafe-inline' as an allowed source in a script-src or style-srcdirective.

Reporting

CSP's ability to block untrusted resources client-side is a huge win for your users, but it would be quite helpful indeed to get some sort of notification sent back to the server so that you can identify and squash any bugs that allow malicious injection in the first place. To this end, you can instruct the browser toPOST JSON-formatted violation reports to a location specified in a report-uri directive.

Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;

Those reports will look something like the following:

{
  "csp-report": {
    "document-uri": "http://example.org/page.html",
    "referrer": "http://evil.example.com/",
    "blocked-uri": "http://evil.example.com/evil.js",
    "violated-directive": "script-src 'self' https://apis.google.com",
    "original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
  }
}

It contains a good chunk of information that will help you track down the specific cause of the violation, including the page on which the violation occurred (document-uri), that page's referrer (referrer, note that the key is notmisspelled), the resource that violated the page's policy (blocked-uri), the specific directive it violated (violated-directive), and the page's complete policy (original-policy). CSP is quite usable in Chrome 16+, Safari 6+, and Firefox 4+, and has (very) limited support in IE 10.

Use Case Assume for a moment that you run a banking site, and want to make very sure that only those resources you've written yourself can be loaded. In this scenario, start with a default policy that blocks absolutely everything (default-src 'none'), and build up from there. Let's say the bank loads all images, style, and script from a CDN at https://cdn.mybank.net, and connects via XHR to https://api.mybank.com/ to pull various bits of data down. Frames are used, but only for pages local to the site (no third-party origins). There's no Flash on the site, no fonts, no nothing. The most restrictive CSP header that we could send in this scenario is: Content-Security-Policy: default-src 'none'; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; frame-src 'self'

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.