Spring Content Security
Policy Guide: What It Is
and How to Enable It

stackhawk

StackHawk|October 15, 2021

In this article, we will learn how developers can configure spring content security policy to configure HTTP headers in the Spring web application.

The Content Security Policy (CSP) is a security standard that helps protect and mitigate content injection attacks such as cross-site scripting (XSS), clickjacking, and more. You can use it to protect your Spring web applications by enabling specific HTTP headers. These headers enable web browsers to prevent attackers from injecting malicious code into the input data of a form, including URL parameters, field values, and other components.

Cross-site scripting (XSS) is the most common type of content injection attack. It occurs when a website accepts user data without adequate validation, filtering, or sanitizing. Attackers may use users' input to execute harmful scripts. XSS attacks rely on flaws in web applications' capabilities to gain access to usernames, passwords, and sensitive information.

Every developer should know how to protect against XSS attacks, as they have become very common these days. In this post, I'll explain how developers can configure spring-security csp to configure the HTTP header in the Spring Boot application using Apache Maven build management system. But before jumping into the details of implementing CSP in Spring Security, let's first understand some of the key concepts related to security.

Content Security Policy

As I said earlier, CSP is a security standard. The W3C introduced it to counter content injection attacks. In addition to using HTTP headers to prevent such attacks, CSP allows site owners to reduce risk exposure by declaring certain content types (e.g., scripts, stylesheets, and fonts) and data sources (e.g., external scripts) as disallowed for the page. It also offers more fine-grained control over where your web application loads resources from. For example, you can disallow inline JavaScript. If an attacker successfully injects some malicious script into the browser, CSP will block the injected scripts.

A policy is simply some configuration applied to Spring Security that will activate your web application when Spring has completed bootstrapping. Let's first understand the same-origin policy that browsers apply by default.

Same-Origin Policy

We can define an origin as a combination of URI scheme, hostname, and port number. Let's take the example of http://example.com/folder/index.html:

  • http://example.com is the host.

  • /folder/index.html is the path.

Both http://example.com/folder1/index.html and http://example.com/folder2/index.html belong to the same origin, as they share the same domain or host. A browser doesn't allow a resource from one origin to access data belonging to another origin without a special mechanism known as cross-origin resource sharing (CORS). By default, a browser applies the same-origin policy. When you load a resource from a website, it's allowed to access only data from the same origin.

Security Policy Directives

A security policy directive is an instruction to the client web browser on handling content that originates from outside of the domain. Security policy directives enforce a set of rules to be followed by the client when downloading any content. These directives restrict what can be executed, loaded, and parsed to prevent various possible attacks by exploiting web browser vulnerabilities. CSP establishes a whitelist of trusted sources that refer to scripts, style sheets, fonts, or frames. Any content loaded by the browser must originate from one of those sources.

How Does CSP Protect Against XSS?

CSP enhances the browser's built-in protection against XSS attacks by prescribing what resources the webpage may load and from where. For example, CSP can specify that the browser shouldn't load any images or scripts from a different domain. The following policy will block the loading of all scripts from any other domain:

script-src "self"

How to Enable Spring Content Security Policy?

The Spring framework provides a CSP implementation that your Spring Boot application can use. By default, Spring Security doesn't have spring-security csp enabled in Spring Boot, so we must explicitly enable it.

Luckily, it's pretty simple to enable Spring Security's CSP. All you need to do is add spring-boot-starter-security to your dependencies in your pom.xml and then configure Spring Security to use a configuration that enables CSP.

Many security configurations, including the annotations used as Spring Security filters to allow CSP support, are provided by spring-boot-starter-security dependency. In addition, it requires spring-security-web to add support for CSP via specific HTTP headers so that browsers can enforce these policies.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

When the application calls the controller servlet, a Spring Security CSPFilter object filters the content of the request. It checks the origin of the resource, type of resource, and other custom headers. The spring-security-csp then sets the CSP headers based on the Spring Security configuration.

You can enable CSP in Spring by including any one of the following HTTP headers in the response:

  • Content-Security-Policy, which the browser uses for both blocking and reporting violations in loading a resource based on the policy directives

  • Content-Security-Policy-Report-Only, which the browser usesfor reporting violations in loading a resource based on its policy directives. It's used primarily for experimental purposes, as it only reports, but doesn't block, violations.

The following are some of the important security policy directives:

  • connect-src

  • font-src

  • img-src

  • media-src

  • object-src

  • plugin-types

  • frame-options

  • script-src

To learn about each of these directives in detail, kindly refer to this article.

You can define Spring Security configuration using a Spring Security XML configuration with <content-security-policy> or a Java configuration class. Most developers nowadays prefer to use Java to create the policy, but I'll show you both ways.

Enabling Content Security Policy

Let's now look into how we can enable Spring CSP using both the above methods.

Consider a scenario where we need to create a security policy to block all scripts not originating from our page or a trusted location, https://javascripts.example.com.

If the application attempts to load a script from a source different from the domains specified in the header, the browser will block it. In addition, the browser will send a violation report in the form of JSON data to a URI specified in the directive report-uri. You can learn more about violation reports and their JSON structure for the reported data here.

XML

You can enable the CSP header by using Spring Security XML configuration. To enable CSP, you need to add the <content-security-policy> tag as in the code below:

<!-- ... -->
<headers>
<content-security-policy policy-directives="script-src 'self'
https://javascripts.example.com; report-uri /csp-report-endpoint/"/>
</headers>

script-src defines the valid sources of JavaScript, self refers to the application's domain, and report-uri instructs the browser to POST reports of policy failures in the specified URI.

Spring Content Security Policy Guide - Picture 1 image

Java

To enable CSP using Java configuration, you first need to create a new class, WebSecurityConfig (you can name it anything). It needs to be annotated using @EnableWebSecurity and extend WebSecurityConfigurerAdapter class.

The WebSecurityConfigurerAdapter class is a predefined class that contains many methods, but to configure CSP headers, we would need to override the configure(HttpSecuirty http) method; this will override the default web security configuration. You can specify our additional policies directives within this method by calling special method headers().contentSecurityPolicy() as in the code snippet below.

import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
// ...
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers()
.contentSecurityPolicy("script-src 'self' https://javascripts.example.com; report-uri /csp-report-endpoint/");
}
}

Find and Fix Application Security Vulnerabilities with Automated Testing

Conclusion

We learned how you might use CSP in Spring to prevent and address a variety of content injection attacks. Then, we went over XSS security vulnerabilities. We saw how an attacker might misuse such vulnerabilities to gain access to valuable information. Finally, we saw how to implement CSP using both the XML and Java settings.

This post was written by Tarun Telang. Tarun is a software engineering leader with over 16 years of experience in the software industry with some of the world’s most renowned software development firms like Microsoft, Oracle, BlackBerry, and SAP. His areas of expertise include Java, web, mobile, and cloud. He’s also experienced in managing software projects using Agile and Test Driven Development methodologies.


StackHawk  |  October 15, 2021