Skip to content

Commit

Permalink
Merge pull request #845 from apache/fix/WW-5374-context
Browse files Browse the repository at this point in the history
[WW-5374] Allows to prepend reportUri with Servlet context
  • Loading branch information
lukaszlenart authored Jan 19, 2024
2 parents 5ee3811 + 790c663 commit 3a1a89a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public final class CspInterceptor extends AbstractInterceptor {

private static final Logger LOG = LogManager.getLogger(CspInterceptor.class);

private Boolean enforcingMode;
private boolean prependServletContext = true;
private boolean enforcingMode;
private String reportUri;

@Override
Expand All @@ -60,17 +61,22 @@ public String intercept(ActionInvocation invocation) throws Exception {
}

private void applySettings(ActionInvocation invocation, CspSettings cspSettings) {
if (enforcingMode != null) {
LOG.trace("Applying: {} to enforcingMode", enforcingMode);
cspSettings.setEnforcingMode(enforcingMode);
}
HttpServletRequest request = invocation.getInvocationContext().getServletRequest();
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();

LOG.trace("Applying: {} to enforcingMode", enforcingMode);
cspSettings.setEnforcingMode(enforcingMode);

if (reportUri != null) {
LOG.trace("Applying: {} to reportUri", reportUri);
cspSettings.setReportUri(reportUri);
}
String finalReportUri = reportUri;

HttpServletRequest request = invocation.getInvocationContext().getServletRequest();
HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
if (prependServletContext && (request.getContextPath() != null) && (!request.getContextPath().isEmpty())) {
finalReportUri = request.getContextPath() + finalReportUri;
}

cspSettings.setReportUri(finalReportUri);
}

invocation.addPreResultListener((actionInvocation, resultCode) -> {
LOG.trace("Applying CSP header: {} to the request", cspSettings);
Expand Down Expand Up @@ -99,8 +105,23 @@ private Optional<URI> buildUri(String reportUri) {
}
}

public void setEnforcingMode(String value) {
this.enforcingMode = Boolean.parseBoolean(value);
/**
* Enables enforcing mode, by default all exceptions are only reported
*
* @param enforcingMode {@code true} to enable enforcing mode, {@code false} to keep reporting mode.
*/
public void setEnforcingMode(boolean enforcingMode) {
this.enforcingMode = enforcingMode;
}

/**
* Sets whether to prepend the servlet context path to the {@link #reportUri}.
*
* @param prependServletContext {@code true} to prepend the location with the servlet context path,
* {@code false} otherwise.
*/
public void setPrependServletContext(boolean prependServletContext) {
this.prependServletContext = prependServletContext;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.opensymphony.xwork2.mock.MockActionInvocation;
import org.apache.logging.log4j.util.Strings;
import org.apache.struts2.StrutsInternalTestCase;
import org.apache.struts2.TestAction;
import org.apache.struts2.action.CspSettingsAware;
import org.apache.struts2.dispatcher.SessionMap;
import org.apache.struts2.interceptor.csp.CspInterceptor;
Expand All @@ -45,7 +46,7 @@ public class CspInterceptorTest extends StrutsInternalTestCase {

public void test_whenRequestReceived_thenNonceIsSetInSession_andCspHeaderContainsIt() throws Exception {
String reportUri = "/barfoo";
String reporting = "false";
boolean reporting = false;
interceptor.setReportUri(reportUri);
interceptor.setEnforcingMode(reporting);

Expand All @@ -58,7 +59,7 @@ public void test_whenRequestReceived_thenNonceIsSetInSession_andCspHeaderContain

public void test_whenNonceAlreadySetInSession_andRequestReceived_thenNewNonceIsSet() throws Exception {
String reportUri = "https://www.google.com/";
String enforcingMode = "true";
boolean enforcingMode = true;
interceptor.setReportUri(reportUri);
interceptor.setEnforcingMode(enforcingMode);
session.setAttribute("nonce", "foo");
Expand All @@ -73,7 +74,7 @@ public void test_whenNonceAlreadySetInSession_andRequestReceived_thenNewNonceIsS

public void testEnforcingCspHeadersSet() throws Exception {
String reportUri = "/csp-reports";
String enforcingMode = "true";
boolean enforcingMode = true;
interceptor.setReportUri(reportUri);
interceptor.setEnforcingMode(enforcingMode);
session.setAttribute("nonce", "foo");
Expand All @@ -88,7 +89,7 @@ public void testEnforcingCspHeadersSet() throws Exception {

public void testReportingCspHeadersSet() throws Exception {
String reportUri = "/csp-reports";
String enforcingMode = "false";
boolean enforcingMode = false;
interceptor.setReportUri(reportUri);
interceptor.setEnforcingMode(enforcingMode);
session.setAttribute("nonce", "foo");
Expand All @@ -101,7 +102,7 @@ public void testReportingCspHeadersSet() throws Exception {
}

public void test_uriSetOnlyWhenSetIsCalled() throws Exception {
String enforcingMode = "false";
boolean enforcingMode = false;
interceptor.setEnforcingMode(enforcingMode);

interceptor.intercept(mai);
Expand All @@ -115,7 +116,7 @@ public void test_uriSetOnlyWhenSetIsCalled() throws Exception {
}

public void testCannotParseUri() {
String enforcingMode = "false";
boolean enforcingMode = false;
interceptor.setEnforcingMode(enforcingMode);

try {
Expand All @@ -127,7 +128,7 @@ public void testCannotParseUri() {
}

public void testCannotParseRelativeUri() {
String enforcingMode = "false";
boolean enforcingMode = false;
interceptor.setEnforcingMode(enforcingMode);

try {
Expand All @@ -139,13 +140,41 @@ public void testCannotParseRelativeUri() {
}

public void testCustomPreResultListener() throws Exception {
boolean enforcingMode = false;
mai.setAction(new CustomerCspAction("/report-uri"));
interceptor.setEnforcingMode("false");
interceptor.setEnforcingMode(enforcingMode);
interceptor.intercept(mai);
checkHeader("/report-uri", enforcingMode);
}

public void testPrependContext() throws Exception {
boolean enforcingMode = true;
mai.setAction(new TestAction());
request.setContextPath("/app");

interceptor.setEnforcingMode(enforcingMode);
interceptor.setReportUri("/report-uri");

interceptor.intercept(mai);
checkHeader("/report-uri", "false");

checkHeader("/app/report-uri", enforcingMode);
}

public void testNoPrependContext() throws Exception {
boolean enforcingMode = true;
mai.setAction(new TestAction());
request.setContextPath("/app");

interceptor.setEnforcingMode(enforcingMode);
interceptor.setReportUri("/report-uri");
interceptor.setPrependServletContext(false);

interceptor.intercept(mai);

checkHeader("/report-uri", enforcingMode);
}

public void checkHeader(String reportUri, String enforcingMode) {
public void checkHeader(String reportUri, boolean enforcingMode) {
String expectedCspHeader;
if (Strings.isEmpty(reportUri)) {
expectedCspHeader = String.format("%s '%s'; %s 'nonce-%s' '%s' %s %s; %s '%s'; ",
Expand All @@ -163,7 +192,7 @@ public void checkHeader(String reportUri, String enforcingMode) {
}

String header;
if (enforcingMode.equals("true")) {
if (enforcingMode) {
header = response.getHeader(CspSettings.CSP_ENFORCE_HEADER);
} else {
header = response.getHeader(CspSettings.CSP_REPORT_HEADER);
Expand Down

0 comments on commit 3a1a89a

Please sign in to comment.