Skip to content
Permalink
Browse files

Adding default security filters for browsers to handle anything that …

…might come up in the future.
  • Loading branch information...
zabil committed Jul 18, 2016
1 parent e9acca0 commit 657feb33b40557a1639432ca43c6cd18d41da6ab
@@ -41,6 +41,7 @@
import javax.management.MBeanServer;
import javax.net.ssl.SSLSocketFactory;
import javax.servlet.ServletException;
import javax.servlet.SessionCookieConfig;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -102,7 +103,9 @@ public void addExtraJarsToClasspath(String extraClasspath) {

@Override
public void setCookieExpirePeriod(int cookieExpirePeriod) {
webAppContext.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(cookieExpirePeriod);
SessionCookieConfig cookieConfig = webAppContext.getSessionHandler().getSessionManager().getSessionCookieConfig();
cookieConfig.setHttpOnly(true);
cookieConfig.setMaxAge(cookieExpirePeriod);
}

@Override
@@ -141,7 +144,17 @@ public GoServerWelcomeFileHandler() {

private class Handler extends AbstractHandler {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (target.equals("/")) {

if ("/go".equals(request.getPathInfo()) || request.getPathInfo().startsWith("/go/")) {
return;
}

response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-Frame-Options", "SAMEORIGIN");
response.setHeader("X-UA-Compatible", "chrome=1");

if ("/".equals(target)) {
response.setHeader("Location", GoConstants.GO_URL_CONTEXT + "/home");
response.setStatus(301);
response.setHeader("Content-Type", "text/html");
@@ -35,8 +35,11 @@
import org.mockito.ArgumentCaptor;

import javax.net.ssl.SSLSocketFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

@@ -146,6 +149,82 @@ public void shouldAddWelcomeRequestHandler() throws Exception {
assertThat(welcomeFileHandler.getContextPath(), is("/"));
}

@Test
public void shouldAddDefaultHeadersForRootContext() throws Exception {
ArgumentCaptor<HandlerCollection> captor = ArgumentCaptor.forClass(HandlerCollection.class);
jetty9Server.configure();

verify(server, times(1)).setHandler(captor.capture());
HandlerCollection handlerCollection = captor.getValue();
Jetty9Server.GoServerWelcomeFileHandler handler = (Jetty9Server.GoServerWelcomeFileHandler)handlerCollection.getHandlers()[0];
Handler rootPathHandler = handler.getHandler();

HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getWriter()).thenReturn(mock(PrintWriter.class));

HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getPathInfo()).thenReturn("/");

rootPathHandler.handle("/", mock(Request.class), request, response);

verify(response).setHeader("X-XSS-Protection", "1; mode=block");
verify(response).setHeader("X-Content-Type-Options", "nosniff");
verify(response).setHeader("X-Frame-Options", "SAMEORIGIN");
verify(response).setHeader("X-UA-Compatible", "chrome=1");

}

@Test
public void shouldSkipDefaultHeadersIfContextPathIsGoRootPath() throws Exception {
ArgumentCaptor<HandlerCollection> captor = ArgumentCaptor.forClass(HandlerCollection.class);
jetty9Server.configure();

verify(server, times(1)).setHandler(captor.capture());
HandlerCollection handlerCollection = captor.getValue();
Jetty9Server.GoServerWelcomeFileHandler handler = (Jetty9Server.GoServerWelcomeFileHandler)handlerCollection.getHandlers()[0];
Handler rootPathHandler = handler.getHandler();

HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getWriter()).thenReturn(mock(PrintWriter.class));

HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getPathInfo()).thenReturn("/go");

rootPathHandler.handle("/go", mock(Request.class), request, response);

verify(response, never()).setHeader("X-XSS-Protection", "1; mode=block");
verify(response, never()).setHeader("X-Content-Type-Options", "nosniff");
verify(response, never()).setHeader("X-Frame-Options", "SAMEORIGIN");
verify(response, never()).setHeader("X-UA-Compatible", "chrome=1");

}


@Test
public void shouldSkipDefaultHeadersIfContextPathIsAnyOtherUrlWithinGo() throws Exception {
ArgumentCaptor<HandlerCollection> captor = ArgumentCaptor.forClass(HandlerCollection.class);
jetty9Server.configure();

verify(server, times(1)).setHandler(captor.capture());
HandlerCollection handlerCollection = captor.getValue();
Jetty9Server.GoServerWelcomeFileHandler handler = (Jetty9Server.GoServerWelcomeFileHandler)handlerCollection.getHandlers()[0];
Handler rootPathHandler = handler.getHandler();

HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getWriter()).thenReturn(mock(PrintWriter.class));

HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getPathInfo()).thenReturn("/go/pipelines");

rootPathHandler.handle("/go/pipelines", mock(Request.class), request, response);

verify(response, never()).setHeader("X-XSS-Protection", "1; mode=block");
verify(response, never()).setHeader("X-Content-Type-Options", "nosniff");
verify(response, never()).setHeader("X-Frame-Options", "SAMEORIGIN");
verify(response, never()).setHeader("X-UA-Compatible", "chrome=1");

}

@Test
public void shouldAddResourceHandlerForAssets() throws Exception {
ArgumentCaptor<HandlerCollection> captor = ArgumentCaptor.forClass(HandlerCollection.class);
@@ -0,0 +1,41 @@
/*
* Copyright 2016 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.thoughtworks.go.server.web;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class DefaultHeadersFilter implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletResponse response = (HttpServletResponse) resp;

response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-Frame-Options", "SAMEORIGIN");
response.setHeader("X-UA-Compatible", "chrome=1");

chain.doFilter(req, resp);
}

public void init(FilterConfig config) throws ServletException {
// No default config
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2016 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.thoughtworks.go.server.web;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;

public class DefaultHeadersFilterTest {

@Mock
private HttpServletResponse response;
@Mock
private FilterChain chain;
@Mock
private ServletRequest request;

@Before
public void setUp() throws Exception {
initMocks(this);
}

@Test
public void shouldAddDefaultHeaders() throws Exception {
DefaultHeadersFilter filter = new DefaultHeadersFilter();
filter.doFilter(request, response, chain);

verify(response).setHeader("X-XSS-Protection", "1; mode=block");
verify(response).setHeader("X-Content-Type-Options", "nosniff");
verify(response).setHeader("X-Frame-Options", "SAMEORIGIN");
verify(response).setHeader("X-UA-Compatible", "chrome=1");
}

@Test
public void shouldPropogateFilterChain() throws Exception {
DefaultHeadersFilter filter = new DefaultHeadersFilter();
filter.doFilter(request, response, chain);

verify(chain).doFilter(request, response);
}
}
@@ -30,6 +30,11 @@
<filter-class>com.thoughtworks.go.server.web.BackupFilter</filter-class>
</filter>

<filter>
<filter-name>Default headers filter</filter-name>
<filter-class>com.thoughtworks.go.server.web.DefaultHeadersFilter</filter-class>
</filter>

<filter>
<filter-name>Spring security Filter Chain Proxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
@@ -54,6 +59,11 @@
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>Default headers filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>Spring security Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>

0 comments on commit 657feb3

Please sign in to comment.
You can’t perform that action at this time.