Content Security Policy

As a full-stack dev, I try my best to keep up on front and back end technologies, methods, and techniques. One of the many ways I do this is by utilizing my time through reading, watching, and listening. I have, at any time, 3-5 books I’m reading, a slew of videos on my watch list, […]

From By Kravietz - Own work, CC BY-SA 4.0,

Posted October 17, 2016
Filed Under: blog

As a full-stack dev, I try my best to keep up on front and back end technologies,
methods, and techniques. One of the many ways I do this is by utilizing my time
through reading, watching, and listening. I have, at any time, 3-5 books I’m reading,
a slew of videos on my watch list, and a myriad of podcasts that I listen to which
help me stay aware of the numerous things that are relevant to me as a web dev.

One of the podcasts I listen to is Shop Talk Show. Aside from the various tips,
tricks, and information that I’ve absorbed from the podcast, I’ve also learned
how to talk about what I do through Chris and Dave. They constantly get
interesting questions and go down rabbit holes. In the” target=’_blank’>Last episode (#273), they get
into Content Security Policies. It’s something that I don’t hear people talk about
often and though it’s something I’ve always used and been aware of, I don’t think
I’ve ever written or posted about it. So I wanted to offer up a blog post.

The goal of a Content Security Policy (CSP) is to prevent Cross-Site Scripting
There are a lot of ways it does this, which we’ll get into. How it works
is by directing the browser to enforce the policies set forth through HTTP directives.
The CSP sets a whitelist of content sources which the browser understands will be
the endpoint of requests made from the page. The browser uses this whitelist to
block requests made to content sources outside of the whitelist. Keep in mind that
CSP is not meant to be the only defense against XSS, just another tool in the
box. You should utilize other tools (like input sanitization) in addition to a
CSP to prevent XSS

How It works

When a browser makes a request to your website, the CSP should be provided with
the HTML as an http-header. It’s part of the header because it’s hard to forge.
The policy itself is a set of directives which instructs the browser to only
render or execute content from the whitelisted sources.

What A CSP Contains

CSPs contain source directives, or, a list of sources for specific content types.
Here’s the list of those:

  • default-src: the default source of all content types. This is used when a source
    type is not defined. When a more specific source type is defined, it overrides the
    default source.
  • base-uri: sets the URLs that can appear in the <base> element.
  • child-src: sets the URLs for workers and embedded frame contents. For example:
    child-src would allow embedding videos from YouTube but
    not from other origins. This should be used instead of the deprecated
    frame-src directive.
  • connect-src: sets the endpoints to which the page can connect via XHR, WebSockets,
    and EventSource.
  • font-src: sets the origins that can serve fonts.
  • form-action: sets the endpoints for <form> submissions.
  • frame-ancestors: sets the sources that can embed the current page. This applies
    to <iframe>, <frame>, <embed>, and <applet> tags. It can’t be used in
    <meta> tags and applies only to non-HTML resources.
  • img-src: sets the origins from which images can be loaded.
  • media-src: sets the origins from which video and audio can be loaded.
  • object-src: sets control over Flash and other plug-ins.
  • plugin-types: sets the types of plug-ins pages may invoke.
  • report-uri: specifies a URL where a browser will send reports when a security
    policy is violated. This can’t be used in <meta> tags.
  • style-src: sets the origins from which stylesheets can be loaded.
  • script-src: sets the origins from which scripts can be loaded.
  • upgrade-insecure-requests: instructs browsers to rewrite URL schemes, changing
    HTTP to HTTPS. This is for websites with large amounts of old URLS that need to
    be rewritten.

Why It’s Needed

By default, directives are open, meaning that all sources and endpoints are
allowed. It’s important to restrict the sources and endpoints because attackers
can use unknown sources to perform XSS.

How To Implement

To specify sources, there are a few valid values:

  • *: All origins/endpoints are valid
  • data:: Allows data: URIs to be used as a content source. This is insecure.
    An attacker can inject arbitrary data: URIs. This should be used sparingly and definitely not
    for scripts.
  • All domains of using the http:// OR https://
    schemas are valid.
  • All domains of using ONLY the https://
    schema are valid.
  • http://* All subdomains of using the http://
    OR https:// schema are valid.
  • https://* All subdomains of using ONLY the https://
    schema are valid.
  • All attempts to access port 433 on are valid.

Keywords are also used. When using keywords, single quotes are required.

  • 'none': An empty set. No URLs are allowed.
  • 'self': The origin from which the originating document is served, including the
    same URL scheme and port number.
  • 'unsafe-inline': Allows the use of inline resources (i.e. <script> elements or javascript: URLs)
  • 'unsafe-eval': Allows the use of eval() and similar methods for creating
    code from strings.

Notes on the Above:
http:// can redirect to https://, but https:// will not redirect to http://.
If a port number isn’t specified, the default port will be used. If no schema is
specified, the same on used to access the originating document is assumed. Allowing
a domain does not include it’s subdomains, but does allow extensions (i.e. will
allow to be used but not

Setting the CSP HTTP Header

The CSP’s best delivery method is through HTTP headers. Here are some examples how:

Apache config

Header set Content-Security-Policy "default-src 'self';"

# IIS Web.config
      <add name="Content-Security-Policy" value="default-src 'self;'" />
# nginx conf file
add_header Content-Security-Policy "default-src 'self';"

A lot of languages and frameworks support adding the headers programmatically, such
as PHP or Node.js.

header("Content-Security-Policy", "default-src 'self'");
# node-js
request.setHeader("Content-Security-Policy", "default-src 'self'");

CSP <meta> tag

There is also an HTML5 <meta> tag.

<meta name='Content-Security-Policy' content="default-src 'self'; script-src 'self'; ...; ...;" />

This tag goes in the <head> of the page.


When setting directives, you should always include multiple URLs in one directive
(if multiple URLs are necessary). For example, if you want to allow images from AND, setting it across two directives would render
whichever came first useless because the latter would override the former.


The second directive overrides the first directive.

Instead, multiple URLs should be declared in one directive, i.e.


Specific directories are not allowed, i.e. If you want
to use a specific directory, just use the web root (i.e.

Other Resources

I use a lot of resources to write my articles and make sure everything is up to snuff.
Here are some great articles/documentation:
Level 2 Spec on W3C
SitePoint article
Mozilla Dev Article
HTML5Rocks Article

In Conclusion

We reviewed Content Security Policies, what they are, why they’re needed, what
they do, how to implement them, and the syntax.


Leave a Reply

Your email address will not be published. Required fields are marked *