Skip to content

Instantly share code, notes, and snippets.

@jonathanKingston
Last active July 28, 2020 21:55
Show Gist options
  • Save jonathanKingston/5699b440f608960dc089 to your computer and use it in GitHub Desktop.
Save jonathanKingston/5699b440f608960dc089 to your computer and use it in GitHub Desktop.
JSON CSP

JSON CSP

CSP is the de facto way to filter a sites exploitable surface areas. The current problem that needs some thought is being able to share your policy for others to be able to consume.

The easiest way for this to be made possible is to provide a JSON representation of CSP so that libraries can publish their polices. Tools can be then made available to merge policies together easily and ultimately then allow a smoother transition to a secure internet.

This may for example look like:

{
  "default-src": ["'self'", "domain.com"],
  "script-src": ["'self'"]
}

Schema

security policy directive name will be used as a hash key in the CSP policy. security policy directive value will be used as a hash value in the CSP policy:

  • The value will be used to be split into an array:
    • in the case of a 'source list' this will be split into an array of each 'source-expression' strings
    • in a 'media list' this will be an array of each 'media-type' strings
    • for a 'ancestor source list' this will be an array of each 'ancestor-source' strings or be the string 'none'
    • 'sandbox' this will be an array of 'sandbox-token' strings
    • 'report-uri' this will be an array of 'uri-reference' strings

Merging policies together

When merging policies it is important that the strictest settings are taken first, until such time that the setting collides with another setting.

For example:

{
  "default-src": ["'none'"],
  "sandbox": ["allow-forms"]
}

and:

{
  "script-src": ["'self'"]
}

Would result in:

{
  "default-src": ["'none'"],
  "sandbox": ["allow-forms", "allow-scripts"],
  "script-src": ["'self'"]
}

Merging the two policies together opened up allow-scripts as script-src required scripts to execute.

default-src

Merging a policy that has "default-src": ["'none'"] should always maintain this strict settings and any default-src parameters should be evenly distributed to all directives.

Where a 'default-src' is omitted in one or more policy being merged it should be assumed this policy has only default-src set to 'none'.

Duplicate values

Where a source list contains two sources that cancel each other out the least restrictive is omitted from the merge. This includes where asterisk is used to wild card parts of the source. So "*.example.com" and "www.example.com" would result in "*.example.com" being added to the source list.

Considerations

  • Because of the limited scope of ambiguity would it be worth simplifying the structure to remove the double quoting for keywords?
    • A urn could be used instead also "script-src": ["urn:cspjson:self"]
  • For non src directives with no arguments i.e. sandbox should the value be true or []
  • Would violation reports benefit from JSON output structure listed here?
@Strik3Eagle
Copy link

I found this very interesting, I have been doing some research on the CSP implementation. However, I would like to get your take on how to properly implement CSP if the API the application is calling are JSON responses. My understanding is that CSP as http header wont have any impact because the API endpoint serves nothing but JSON responses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment