Skip to content

Commit

Permalink
Merge pull request #91 from BroadleafCommerce/QA-4965_update_security…
Browse files Browse the repository at this point in the history
…_settings_for_community

Update security setting for community
  • Loading branch information
riteshadhikari17 authored May 3, 2023
2 parents 369d26c + 7bdc406 commit efbd5b2
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
*/
package com.community.admin.configuration;

import com.community.admin.web.filter.AdminContentSecurityPolicyFilter;
import org.broadleafcommerce.common.security.handler.SecurityFilter;
import org.broadleafcommerce.openadmin.security.BroadleafAdminAuthenticationFailureHandler;
import org.broadleafcommerce.openadmin.security.BroadleafAdminAuthenticationSuccessHandler;
import org.broadleafcommerce.openadmin.web.filter.AdminSecurityFilter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
Expand Down Expand Up @@ -80,6 +82,13 @@ protected AuthenticationSuccessHandler blAdminAuthenticationSuccessHandler() {
@Value("${server.port:8444}")
protected int httpsRedirectPort;

@Value("${site.baseurl.domain}")
private String baseUrl;

@Value("${site.baseurl.port}")
private String baseUrlPort;


@Value("${asset.server.url.prefix.internal}")
protected String assetServerUrlPrefixInternal;

Expand Down Expand Up @@ -161,10 +170,24 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.http(8080).mapsTo(8443)
.http(httpServerPort).mapsTo(httpsRedirectPort)
.and()
.addFilterBefore(adminCsrfFilter, UsernamePasswordAuthenticationFilter.class);
.addFilterBefore(adminCsrfFilter, UsernamePasswordAuthenticationFilter.class)
.addFilterAfter(new AdminContentSecurityPolicyFilter(getCSPHeader()), AdminSecurityFilter.class);
return http.build();
}

/**
* Add the site's baseUrl and port as a frame-src value to the Content Security Policy header.
* This enables admin's CSR mode to load the site in a modal.
* @return The CSP header
*/
private String getCSPHeader() {
// Can contain one or more %s placeholders for substitution of a nonce token (e.g. 'nonce-%s')
return "default-src 'self';script-src 'self' 'unsafe-eval' 'nonce-%s'; " +
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data:; " +
"font-src 'self' https://fonts.gstatic.com data:; frame-src 'self' *." + baseUrl + ":" + baseUrlPort + ";";
}


/**
* Don't allow the auto registration of the filter for the main request flow. This filter should be limited
* to the spring security chain.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*-
* #%L
* Private Demo Admin
* %%
* Copyright (C) 2009 - 2023 Broadleaf Commerce
* %%
* Licensed under the Broadleaf Fair Use License Agreement, Version 1.0
* (the "Fair Use License" located at http://license.broadleafcommerce.org/fair_use_license-1.0.txt)
* unless the restrictions on use therein are violated and require payment to Broadleaf in which case
* the Broadleaf End User License Agreement (EULA), Version 1.1
* (the "Commercial License" located at http://license.broadleafcommerce.org/commercial_license-1.1.txt)
* shall apply.
*
* Alternatively, the Commercial License may be replaced with a mutually agreed upon license (the "Custom License")
* between you and Broadleaf Commerce. You may not use this file except in compliance with the applicable license.
* #L%
*/
package com.community.admin.web.filter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
* Creates a nonce token for use with Content Security Policy script blocks.
*
* Expects a Content Security Policy with a single string placeholder (%s). The created nonce will be
* - added to a request attribute ("blcCspNonce")
* - for use in a nonce varible on script tags
*
* <code>
* <script th:attr="nonce=${blcCspNonce}">
* </code>
*
* This filter would typically be initialized in the AdminSecurityConfig as a add filter.
*
* <code>
* . addFilterAfter(new AdminContentSecurityPolicyfFilter(cspHeaderValue), AdminSecurityFilter.class)
* </code>
*
* Note that multiple http requests can be made each of which would traverse the filter pipeline and
* each would receive a unique token. This should not be a problem as the response header will coincide
* with the nonce provided in the HTML script/tag. If it is desired to skip token generation for a specific
* request, the excludeRequestPattern could be used.
*
* @author Daniel Colgrove
*/
public class AdminContentSecurityPolicyFilter extends OncePerRequestFilter {

protected static final Log LOG = LogFactory.getLog(AdminContentSecurityPolicyFilter.class);

protected List<String> excludedRequestPatterns;
protected final String contentSecurityPolicy;

public AdminContentSecurityPolicyFilter(String csp) {
this.contentSecurityPolicy = csp;
}

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

boolean excludedRequestFound = false;
if (excludedRequestPatterns != null && excludedRequestPatterns.size() > 0) {
for (String pattern : excludedRequestPatterns) {
RequestMatcher matcher = new AntPathRequestMatcher(pattern);
if (matcher.matches(request)) {
excludedRequestFound = true;
break;
}
}
}

if (!excludedRequestFound) {
establishNonceToken(request, response);
}

filterChain.doFilter(request, response);
}

protected void establishNonceToken(HttpServletRequest request, HttpServletResponse response) {
final String nonce = UUID.randomUUID().toString();
request.setAttribute("blcCspNonce", nonce);

LOG.debug(String.format("Nonce token set to %s", nonce));

String headerValue = contentSecurityPolicy.replaceAll("%s", nonce);
response.addHeader("Content-Security-Policy", headerValue);
}

public List<String> getExcludedRequestPatterns() {
return excludedRequestPatterns;
}

/**
* This allows you to declaratively set a list of excluded Request Patterns
*
* <bean id="blFilter" class="org.broadleafcommerce.common.security.handler.CsrfFilter" >
* <property name="excludedRequestPatterns">
* <list>
* <value>/exclude-me/**</value>
* </list>
* </property>
* </bean>
*
**/
public void setExcludedRequestPatterns(List<String> excludedRequestPatterns) {
this.excludedRequestPatterns = excludedRequestPatterns;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,9 @@ admin.baseurl=http://localhost:8081/admin
crossapp.requireSsl=false

jcache.disable.cache=true

#Enable exploit protection for Admin
exploitProtection.xssEnabled=true
exploitProtection.xsrfEnabled=true
#Enable exploit protection for Site
blc.site.enable.xssWrapper=true
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

# Please see common-shared.properties for more information on how the properties files work

blPU.hibernate.hbm2ddl.auto=update
blPU.hibernate.hbm2ddl.auto=update

0 comments on commit efbd5b2

Please sign in to comment.