I have been playing with this library, and see what you mean about it having a very focused API. It can't use it to fetch CSP from an HTTP endpoint, it can't find all the policies from headers and meta tags, and it can't union/intersect any policies for you. Despite it being very focused, I did not find it hard to fill this gap. I won't go into fetching and parsing HTML documents over HTTP, but the merging and eval part went something like this:
First, I wanted to track the source of the serialized polices (headers and meta). I did this using a little data class:
record SerializedCspValues(Collection<String> headers, Collection<String> meta)
{
}
After fetching the HTML into an instance of the above record, I would process the results like this:
private static SerializedCspValues process(SerializedCspValues unprocessedSerializedCspValues)
{
// Cf. https://html.spec.whatwg.org/#attr-meta-http-equiv-content-security-policy step 4
var meta = unprocessedSerializedCspValues.meta().stream()
.filter(PolicyValidator::removeDisallowedDirectives)
.collect(Collectors.toList());
SerializedCspValues serializedCspValues = new SerializedCspValues(unprocessedSerializedCspValues.headers(), meta);
return serializedCspValues;
}
Later, I would deserialize these into a Salvation Policy like this:
public Collection<Policy> deserialize(SerializedCspValues serializedCspValues)
{
var policies = Stream.concat(serializedCspValues.meta().stream(),
serializedCspValues.headers()
.stream())
.map(it -> Policy.parseSerializedCSP(it, _policyStatusCollector))
.collect(Collectors.toList());
return policies;
}
Then, I would process them all against a set of rules:
public boolean validate(Rules rules)
{
// _policies is a Collection<Policy> type obtained
// from the deserializer shown above
return _policies.stream().allMatch(rules::match);
}
If any of these rules didn't match, I'd print the warnings/errors obtained from the Policy.PolicyErrorConsumer object (shown above as _policyStatusCollector).
From this, I think it's a small and straightforward job to update ZAP to support CSP in meta tags. If you send a branch, repo, etc., Sathya or I can help with this. If a complete example of what I did would be more useful, I can post that online somewhere. Just let us know what we can do to help.