GitHub - HtmlUnit/htmlunit-csp
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
This is the code repository of the Content Security Policy support used by HtmlUnit.
The library was forked from the salvation project, which is no longer actively maintained.
The code has been adapted to match HtmlUnit's code style rules, and support for editing policies has been removed.
The code is being expanded, restructured and improved primarily to meet the requirements of this project.
❤️ Sponsor
Project News
HtmlUnit@mastodon | HtmlUnit@bsky | HtmlUnit@Twitter
Version 5
Starting with version 5.0.0, JDK 17 or higher is required.
If you are still on JDK 8, see Legacy Support (JDK 8) below.
Latest release Version 5.2.0 / June 20, 2026
Maven
Add to your pom.xml:
<dependency> <groupId>org.htmlunit</groupId> <artifactId>htmlunit-csp</artifactId> <version>5.2.0</version> </dependency>
Gradle
Add to your build.gradle:
implementation group: 'org.htmlunit', name: 'htmlunit-csp', version: '5.2.0'
Projects Using This Library
Beyond HtmlUnit itself, htmlunit-csp is used by various open-source projects for Content Security Policy parsing and validation:
Security Tools
- ZAP (Zed Attack Proxy) - The world's most widely used web application security scanner. ZAP uses htmlunit-csp in its Content Security Policy Scan Rule to analyze and validate CSP headers for security vulnerabilities.
HTML Parsing and Validation
- The Nu Html Checker (vnu) - An HTML conformance checker that uses htmlunit-csp for checking Content Security Policy directives in web documents.
If your project uses HtmlUnit-CSP, feel free to submit a pull request to add it to this list!
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(), URI.parse("http://a"), Optional.empty(), Optional.empty() )); // false System.out.println(policy.allowsExternalScript( Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty() ));
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());
Legacy Support (JDK 8)
If you need to continue using JDK 8, versions 4.x remain available as-is. Ongoing maintenance and fixes for JDK 8 are only available through sponsorship — please contact me via email to discuss options. Sponsorship provides:
- Backporting security and bug fixes to the 4.x branch
- Compatibility maintenance with older Java versions
- Timely releases for critical issues
Without sponsorship, the 4.x branch will not receive further updates.
Last CI build
The latest builds are available from our Jenkins CI build server
If you use maven please add:
<dependency>
<groupId>org.htmlunit</groupId>
<artifactId>htmlunit-csp</artifactId>
<version>5.3.0-SNAPSHOT</version>
</dependency>
You have to add the sonatype-central snapshot repository to your pom repositories section also:
<repositories>
<repository>
<name>Central Portal Snapshots</name>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
Start HtmlUnit - CSP Development
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.
Prerequisites
You need:
- Java 17 or later
- A local Maven installation
Building
Create a local clone of the repository and you are ready to start.
Open a command line window from the root folder of the project and call
Running the tests
Contributing
Pull Requests and all other Community Contributions are essential for open source software. Every contribution - from bug reports to feature requests, typos to full new features - are greatly appreciated.
Deployment and Versioning
This part is intended for committer who are packaging a release.
- Check all your files are checked in
- Execute these mvn commands to be sure all tests are passing and everything is up to data
mvn versions:display-plugin-updates
mvn versions:display-dependency-updates
mvn -U clean test
-
Update the version number in pom.xml and README.md
-
Commit the changes
-
Build and deploy the artifacts
-
Go to Maven Central Portal and process the deploy
- publish the package and wait until it is processed
-
Create the version on Github
- login to Github and open project https://github.com/HtmlUnit/htmlunit-csp
- click Releases > Draft new release
- fill the tag and title field with the release number (e.g. 5.0.0)
- append
- htmlunit-csp-5.x.x.jar
- htmlunit-csp-5.x.x.jar.asc
- htmlunit-csp-5.x.x.pom
- htmlunit-csp-5.x.x.pom.asc
- htmlunit-csp-5.x.x-javadoc.jar
- htmlunit-csp-5.x.x-javadoc.jar.asc
- htmlunit-csp-5.x.x-sources.jar
- htmlunit-csp-5.x.x-sources.jar.asc
- and publish the release
-
Update the version number in pom.xml to start next snapshot development
-
Update the htmlunit pom to use the new release
Authors
- RBRi
- all the contributors to salvation
License
This project is licensed under the Apache 2.0 License
Acknowledgments
Many thanks to all of you contributing to salvation in the past.
Development Tools
Special thanks to:
JetBrains for providing IntelliJ IDEA under their open source development license and