Skip to content

Commit

Permalink
WICKET-7107 configure ContentSecurityPolicySettings to protect buffer…
Browse files Browse the repository at this point in the history
…ed pages
  • Loading branch information
pedrosans committed Nov 27, 2024
1 parent f67bccf commit 6dde1f3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@
*/
package org.apache.wicket.csp;

import static org.apache.wicket.csp.CSPDirective.CHILD_SRC;
import static org.apache.wicket.csp.CSPDirective.DEFAULT_SRC;
import static org.apache.wicket.csp.CSPDirective.FRAME_SRC;
import static org.apache.wicket.csp.CSPDirective.IMG_SRC;
import static org.apache.wicket.csp.CSPDirective.REPORT_URI;
import static org.apache.wicket.csp.CSPDirective.SANDBOX;
import static org.apache.wicket.csp.CSPDirectiveSandboxValue.ALLOW_FORMS;
import static org.apache.wicket.csp.CSPDirectiveSandboxValue.EMPTY;
import static org.apache.wicket.csp.CSPDirectiveSrcValue.NONE;
import static org.apache.wicket.csp.CSPDirectiveSrcValue.SELF;
import static org.apache.wicket.csp.CSPDirectiveSrcValue.WILDCARD;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.markup.IMarkupResourceStreamProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.mock.MockApplication;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.StringResourceStream;
import org.apache.wicket.util.tester.DummyHomePage;
import org.apache.wicket.util.tester.WicketTestCase;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -39,15 +41,14 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.wicket.mock.MockApplication;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.util.tester.DummyHomePage;
import org.apache.wicket.util.tester.WicketTestCase;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.apache.wicket.csp.CSPDirective.*;
import static org.apache.wicket.csp.CSPDirectiveSandboxValue.ALLOW_FORMS;
import static org.apache.wicket.csp.CSPDirectiveSandboxValue.EMPTY;
import static org.apache.wicket.csp.CSPDirectiveSrcValue.*;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class CSPSettingRequestCycleListenerTest extends WicketTestCase
{
Expand Down Expand Up @@ -381,6 +382,36 @@ void testConstantValues_whenInvalidConstant_acceptedByConfigurer(String source)
assertThrows(IllegalArgumentException.class, () -> settings.add(IMG_SRC, source + ":"));
}

@Test
void addCspDirectiveInBufferedPageResponses()
{
tester.setFollowRedirects(true);
tester.getApplication().getCspSettings().blocking().add(STYLE_SRC, SELF);

tester.startPage(RedirectPage.class);

assertThat(tester.getLastResponse().getHeader("Content-Security-Policy"),
containsString(STYLE_SRC.getValue()));
}

public static class Page extends WebPage implements IMarkupResourceStreamProvider
{
@Override
public IResourceStream getMarkupResourceStream(MarkupContainer container,
Class<?> containerClass)
{
return new StringResourceStream("<html><head></head><body></body></html>");
}
}

public static class RedirectPage extends Page
{
public RedirectPage()
{
throw new RestartResponseException(new Page());
}
}


private String renderDirective(List<CSPRenderable> values,
ContentSecurityPolicySettings settings, RequestCycle cycle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.wicket.Application;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.Page;
import org.apache.wicket.core.request.handler.BufferedResponseRequestHandler;
import org.apache.wicket.core.request.handler.IPageRequestHandler;
import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
import org.apache.wicket.protocol.http.WebApplication;
Expand Down Expand Up @@ -69,14 +70,18 @@ public class ContentSecurityPolicySettings
private final Map<CSPHeaderMode, CSPHeaderConfiguration> configs = new EnumMap<>(
CSPHeaderMode.class);

private Predicate<IRequestHandler> protectedFilter = RenderPageRequestHandler.class::isInstance;
private Predicate<IRequestHandler> protectedFilter;

private Supplier<String> nonceCreator;

public ContentSecurityPolicySettings(Application application)
{
Args.notNull(application, "application");


Predicate<IRequestHandler> isPage = RenderPageRequestHandler.class::isInstance;
Predicate<IRequestHandler> isBufferedPage = BufferedResponseRequestHandler.class::isInstance;
protectedFilter = isPage.or(isBufferedPage);

nonceCreator = () ->
application.getSecuritySettings().getRandomSupplier().getRandomBase64(NONCE_LENGTH);
}
Expand Down

0 comments on commit 6dde1f3

Please sign in to comment.