Adding CSP Header- Allowing inline script using 'nonce' - Java example.
How to add nonce in Content Security Policy header dynamically to inline scripts in a Java/J2EE application with Spring framework.
To add a nonce to the Content Security Policy (CSP) header dynamically for inline scripts using Java J2EE and the Spring framework, you need to follow these steps:
*The provided code snippets are for reference only. Developers should implement their own solutions based on their application's existing design.
1. Generate a Unique Nonce and add it to the header using a Custom Filter.
Generate a unique nonce for each HTTP request. This nonce should be included in the CSP header and made available to your views.
Example Filter to Generate Nonce in Spring:
First, create a filter to generate the nonce and add it to the response headers.
import org.springframework.stereotype.Component;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Base64;
@Component
public class ContentSecurityPolicyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String nonce = generateNonce();
httpServletRequest.setAttribute("cspNonce", nonce);
httpServletResponse.setHeader("Content-Security-Policy", "script-src 'self' 'nonce-" + nonce + "';");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
private String generateNonce() {
SecureRandom secureRandom = new SecureRandom();
byte[] nonceBytes = new byte[16];
secureRandom.nextBytes(nonceBytes);
return Base64.getEncoder().encodeToString(nonceBytes);
}
}
2. Configure the Filter in Spring
Register the filter in your Spring configuration.
Example Configuration:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean<ContentSecurityPolicyFilter> cspFilter() {
FilterRegistrationBean<ContentSecurityPolicyFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new ContentSecurityPolicyFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
3. Pass the Nonce to the View
Pass the nonce to your views so it can be used in inline scripts. This can be done in the controller.
Example Controller:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class HomeController {
@GetMapping("/")
public String index(HttpServletRequest request, Model model) {
String nonce = (String) request.getAttribute("cspNonce");
model.addAttribute("nonce", nonce);
return "index";
}
}
4. Use the Nonce in the View
In your view, use the nonce in your inline scripts and dynamically added scripts.
Example: index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="csp-nonce" content="${nonce}">
</head>
<body>
<script>
// Make the nonce available to all scripts
window.cspNonce = document.querySelector('meta[name="csp-nonce"]').getAttribute('content');
document.addEventListener('DOMContentLoaded', function () {
var nonce = window.cspNonce;
// Add Google Analytics script
var gaScript = document.createElement('script');
gaScript.setAttribute('async', 'async');
gaScript.setAttribute('src', 'https://www.googletagmanager.com/gtag/js?id=YOUR_TRACKING_ID');
gaScript.setAttribute('nonce', nonce);
document.head.appendChild(gaScript);
// Add inline script for Google Analytics
var inlineScript = document.createElement('script');
inlineScript.setAttribute('nonce', nonce);
inlineScript.text = `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'YOUR_TRACKING_ID');
`;
document.head.appendChild(inlineScript);
// Example for dynamically adding scripts with jQuery
$.getScript('https://example.com/your-script.js', function () {
// Your script loaded and executed
}).attr('nonce', nonce);
});
</script>
</body>
</html>
5. Dynamically Add Nonce to Existing Script Elements
If you need to add a nonce to existing script elements that are added by some other means, you can iterate through the script elements and add the nonce.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="csp-nonce" content="${nonce}">
</head>
<body>
<!-- Your content here -->
<script>
// Make the nonce available to all scripts
window.cspNonce = document.querySelector('meta[name="csp-nonce"]').getAttribute('content');
document.addEventListener('DOMContentLoaded', function () {
var nonce = window.cspNonce;
// Add Google Analytics script
var gaScript = document.createElement('script');
gaScript.setAttribute('async', 'async');
gaScript.setAttribute('src', 'https://www.googletagmanager.com/gtag/js?id=YOUR_TRACKING_ID');
gaScript.setAttribute('nonce', nonce);
document.head.appendChild(gaScript);
// Example for adding an external script
var externalScript = document.createElement('script');
externalScript.setAttribute('src', 'https://example.com/external-script.js');
externalScript.setAttribute('nonce', nonce);
document.head.appendChild(externalScript);
// Apply nonce to all existing scripts
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
scripts[i].setAttribute('nonce', nonce);
}
});
</script>
</body>
</html>
By following these steps, you can ensure that the nonce is added to all your externally referenced JavaScripts dynamically using Java J2EE and the Spring framework.
Page 1 of this article:
https://community.veracode.com/s/article/How-to-fix-CWE-829-Add-CSP-header-correctly
Page 3 : Dot Net example.
Topics (0)
Related Articles
How to fix CWE 829 – Add CSP header correctly ? 748Number of Views How to open a support case in the Community? 6.24KNumber of Views FAQ: Viewing Support Cases in Veracode Community 6.66KNumber of Views What are Modules and how do my results change based on what I select? 17.94KNumber of Views Is there a place I can go online to monitor my support tickets? 582Number of Views
This topic isn't available in this community.
Related Topics
Ask the Community
Get answers, share a use case, discuss your favorite features, or get input from the Community.
.png)