Expand my Community achievements bar.

SOLVED

Add nonce value to Content Security Policy Headers?

Avatar

Level 2

Hello everyone.

We are working on AEM as a cloud services

 

We are trying to add nonce attribute in Content-Security-Police header.

We have been looking at different solutions, but none satisfactory.

We started thinking about making a filter in the aem application server to read the header, add a random number and put it in the <script nonce-xxxxx> tags, we discarded this option because the portal has cache.
We have found several articles indicating how to perform this functionality in the (apache web server) dispatcher.

We activate in our virtual host the include, to activate the SSI and thus replace the variable set in dispatcher in the pages.

Header set Content-Security-Policy “script-src ... 'nonce-%{UNIQUE_ID}e'; ...”
<script nonce=“<!--#echo var=UNIQUE_ID -->”>...</script>

The UNIQUE_ID variable is not strictly base64 encoded. CSP requires a nonce to be base64 encoded, you can solve this by using Apache expressions but it starts to get complicated.

A better approach is to use a specially created module, such as mod_cspnonce. It also provides an environment variable, in this case called CSP_NONCE.

We have tried in dispatcher and the variable returns null, we think this module is not available in dispatcher, is it possible to enable this module in dispatcher?

I don't know if we could have problems with Fastly CDN.

Or you can think of another solution.

 

Best Regards.

 

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Level 6

Hi @jorganer , Have you considered a Custom AEM Filter, there will be of course some trade-off that needs to be considered. Despite your initial concerns about caching, a custom AEM filter could be a viable option. You could generate a nonce, store it in a session or request attribute, and inject it into the response. While caching might be a challenge, it could be done through cache invalidation strategies or by using a unique nonce per user session. Something like below.

// Nonce Sling Filter in AEM
@Component(immediate = true, service = Filter.class, property = {
"sling.filter.scope=REQUEST",
"sling.filter.pattern=/.*"
})
public class CSPNonceFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;

// Generate a base64-encoded nonce
String nonce = Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes());

// Set the CSP header with the nonce
httpResponse.setHeader("Content-Security-Policy", "script-src 'self' 'nonce-" + nonce + "';");

// Include the nonce in the response
httpRequest.setAttribute("cspNonce", nonce);
chain.doFilter(request, response);
}
}


Pros:

Full control over nonce generation and injection.
Can be tailored to AEM specifics.


Cons:
Potential caching issues

View solution in original post

6 Replies

Avatar

Level 2

Thank you very much.

I have consulted that article before opening this query.

Greetings.

Avatar

Correct answer by
Level 6

Hi @jorganer , Have you considered a Custom AEM Filter, there will be of course some trade-off that needs to be considered. Despite your initial concerns about caching, a custom AEM filter could be a viable option. You could generate a nonce, store it in a session or request attribute, and inject it into the response. While caching might be a challenge, it could be done through cache invalidation strategies or by using a unique nonce per user session. Something like below.

// Nonce Sling Filter in AEM
@Component(immediate = true, service = Filter.class, property = {
"sling.filter.scope=REQUEST",
"sling.filter.pattern=/.*"
})
public class CSPNonceFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;

// Generate a base64-encoded nonce
String nonce = Base64.getEncoder().encodeToString(UUID.randomUUID().toString().getBytes());

// Set the CSP header with the nonce
httpResponse.setHeader("Content-Security-Policy", "script-src 'self' 'nonce-" + nonce + "';");

// Include the nonce in the response
httpRequest.setAttribute("cspNonce", nonce);
chain.doFilter(request, response);
}
}


Pros:

Full control over nonce generation and injection.
Can be tailored to AEM specifics.


Cons:
Potential caching issues

Thank you very much Pradeep_Kumar_Srivastav.

 

We had already taken this option into account, but due to the cache issue we had not wanted to apply it for the moment.

How difficult is the inclusion in dispatcher of new apache modules like mod_cspnonce?

I will wait a few days, if someone can give us a solution that only applies to dispatcher, otherwise we will finally apply the filter solution.

Best regards.

Hi @jorganer , You have to create custom code to purge cache using API. You,for example , can create a workflow by using which you can purge the cache by API after filter is called. Or Reachout to Adobe for enhancement for enabling this module.

Avatar

Administrator

@jorganer Did you find the suggestions from users helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!



Kautuk Sahni