Skip to content

Parse Content Security Policy headers, warn about policy errors, safely manipulate, render, and optimise policies

License

Notifications You must be signed in to change notification settings

Heeby/salvation

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

salvation

This is a general purpose library for working with Content Security Policy policies.

  • parse CSP policies into an easy-to-use representation
  • ask questions about what a CSP policy allows or restricts
  • warn about nonsensical CSP policies and deprecated or nonstandard features
  • safely create and manipulate CSP policies
  • render CSP policies

cspvalidator.org demonstrates some of the features of Salvation in action.

Install

mvn install

A Note on CSP

The CSP specification is fairly complex even if you only care about the latest version. However, in practice you are likely to care that your policy does the things you intend it to on the browsers you care about, which are likely to implement different and potentially broken subsets of the specification (and potentially additional behavior which is not in the specification). And there are inevitable tradeoffs to be made regarding the size of your policy vs the security it provides.

As such, this project does not attempt to provide a one-size-fits-all way to manipulate a policy purely in terms of its effects - the full set of effects across all browsers is too vast to provide an effective API in general. It can help you build up a policy based on the directives and source-expressions you want, but to ensure your policy is correct, for your own definition of correct, there is no alternative to testing it on the real browsers you care about.

Create a Policy

Parse a policy using either Policy.parseSerializedCSP or Policy.parseSerializedCSPList. The second parameter will be called for each warning or error.

String policyText = "script-src 'none'";
Policy policy = Policy.parseSerializedCSP(policyText, (severity, message, directiveIndex, valueIndex) -> {
  System.err.println(severity.name() + " at directive " + directiveIndex + (valueIndex == -1 ? "" : " at value " + valueIndex) + ": " + message);
});

Query a Policy

The high-level querying methods allow you to specify whatever relevant information you have. The missing information will be assumed to be worst-case - that is, these methods will return true only if any object which matches the provided characteristics would be allowed, regardless of its other characteristics.

Policy policy = Policy.parseSerializedCSP("script-src http://a", Policy.PolicyErrorConsumer.ignored);

// true
System.out.println(policy.allowsExternalScript(
  Optional.empty(),
  Optional.empty(),
  Optional.of(URI.parse("http://a")),
  Optional.empty(),
  Optional.empty()
));

// false
System.out.println(policy.allowsExternalScript(
  Optional.empty(),
  Optional.empty(),
  Optional.empty(),
  Optional.empty(),
  Optional.empty()
));

Note that these methods were correct according to current draft of the CSP specification when this library was written, but no browser implements precisely the current draft, and changes to the specification may also invalidate assumptions this library makes. There is no alternative to testing on the browsers you care about.

Because the Policy objects are rich structures, you can also ask about the presence or absence of specific directives or expressions:

Policy policy = Policy.parseSerializedCSP("script-src 'strict-dynamic'", Policy.PolicyErrorConsumer.ignored);

// Assumes the policy has a `script-src` directive (or else the `get` would throw), and checks if it contains the `'strict-dynamic'` source expression
System.out.println(policy.getFetchDirective(FetchDirectiveKind.ScriptSrc).get().strictDynamic());

Manipulate a Policy

Policy policy = Policy.parseSerializedCSP("", Policy.PolicyErrorConsumer.ignored);

policy.add("sandbox", Collections.emptyList(), Directive.DirectiveErrorConsumer.ignored);

// you can use the provided Java APIs to manipulate values Salvation knows about
policy.sandbox().get().setAllowScripts(true);

// or you can use the lower-level APIs to manipulate values directly 
policy.sandbox().get().addValue("allow-something-new");

// "sandbox allow-scripts allow-something-new"
System.out.println(policy.toString());

Serialize a Policy

policy.toString();

About

Parse Content Security Policy headers, warn about policy errors, safely manipulate, render, and optimise policies

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 100.0%