View Javadoc

1   package com.atlassian.plugins.rest.common.security.jersey;
2   
3   import com.atlassian.plugins.rest.common.security.XsrfCheckFailedException;
4   import com.atlassian.sal.api.web.context.HttpContext;
5   import com.atlassian.sal.core.xsrf.IndependentXsrfTokenAccessor;
6   import com.atlassian.sal.core.xsrf.IndependentXsrfTokenValidator;
7   import com.atlassian.sal.core.xsrf.XsrfRequestValidatorImpl;
8   import com.google.common.collect.ImmutableList;
9   import com.sun.jersey.spi.container.ContainerRequest;
10  import org.junit.Before;
11  import org.junit.Test;
12  import org.junit.runner.RunWith;
13  import org.mockito.Mock;
14  import org.mockito.runners.MockitoJUnitRunner;
15  
16  import javax.servlet.http.HttpServletRequest;
17  import javax.ws.rs.HttpMethod;
18  import javax.ws.rs.core.MediaType;
19  import java.net.URI;
20  import java.util.Arrays;
21  
22  import static com.atlassian.plugins.rest.common.security.jersey.TestXsrfResourceFilter.addTokenHeaderToRequest;
23  import static org.mockito.Mockito.when;
24  
25  @RunWith(MockitoJUnitRunner.class)
26  public class TestOriginBasedXsrfResourceFilter {
27      private static final String IE_8_UA = "Mozilla/4.0 (compatible; MSIE 8.0" +
28              "; Windows NT 6.0; Trident/4.0)";
29      private static final String IE_10_UA = "Mozilla/5.0 (compatible; " +
30              "MSIE 10.0; Windows NT 6.2; Trident/6.0)";
31      private static final String IE_11_UA = "Mozilla/5.0 " +
32              "(Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko";
33      private static final String CHROME_32_UA = "Mozilla/5.0 (Windows NT 6.2;" +
34              " Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " +
35              "Chrome/32.0.1667.0 Safari/537.36";
36  
37      private static final ImmutableList<String> IDEMPOTENT_METHODS = ImmutableList.of(
38          HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS, "TRACE");
39  
40      private XsrfResourceFilter xsrfResourceFilter;
41      @Mock
42      private ContainerRequest request;
43      @Mock
44      private HttpContext httpContext;
45      @Mock
46      private HttpServletRequest httpServletRequest;
47  
48      @Before
49      public void setUp() throws Exception {
50          xsrfResourceFilter = new OriginBasedXsrfResourceFilter();
51          xsrfResourceFilter.setXsrfRequestValidator(
52                  new XsrfRequestValidatorImpl(
53                          new IndependentXsrfTokenValidator(
54                                  new IndependentXsrfTokenAccessor())));
55          when(request.getRequestUri()).thenReturn(new URI("http://default.com"));
56          when(request.getPath()).thenReturn("/example");
57          when(request.getMethod()).thenReturn("POST");
58          when(httpContext.getRequest()).thenReturn(httpServletRequest);
59          xsrfResourceFilter.setHttpContext(httpContext);
60      }
61  
62      @Test
63      public void browserIdempotentRequestNotBlocked() throws Exception {
64          setBrowserUserAgentInRequest(request);
65          for (String method : IDEMPOTENT_METHODS) {
66              when(request.getMethod()).thenReturn(method);
67              xsrfResourceFilter.filter(request);
68          }
69      }
70  
71      @Test
72      public void nonBrowserIdempotentRequestNotBlocked() throws Exception {
73          for (String method : IDEMPOTENT_METHODS) {
74              when(request.getMethod()).thenReturn(method);
75              xsrfResourceFilter.filter(request);
76          }
77      }
78  
79      @Test(expected = XsrfCheckFailedException.class)
80      public void browserPostJsonRequestBlocked() throws Exception {
81          when(request.getMethod()).thenReturn("POST");
82          filterBrowserJsonRequest(request);
83      }
84  
85      @Test
86      public void browserPutJsonRequestNotBlocked() throws Exception {
87          when(request.getMethod()).thenReturn("PUT");
88          filterBrowserJsonRequest(request);
89      }
90  
91      @Test
92      public void browserDeleteJsonRequestNotBlocked() throws Exception {
93          when(request.getMethod()).thenReturn("DELETE");
94          filterBrowserJsonRequest(request);
95      }
96  
97      @Test
98      public void nonBrowserPostJsonRequestNotBlocked() throws Exception {
99          setJsonContentTypeForRequest(request);
100         xsrfResourceFilter.filter(request);
101     }
102 
103     @Test(expected = XsrfCheckFailedException.class)
104     public void NonIEBrowserPostJsonRequestWithTokenHeaderBlocked()
105             throws Exception {
106         addTokenHeaderToRequest(httpServletRequest, XsrfResourceFilter.NO_CHECK);
107         setJsonContentTypeForRequest(request);
108         setBrowserUserAgentInRequest(request, CHROME_32_UA);
109         xsrfResourceFilter.filter(request);
110     }
111 
112     @Test
113     public void internetExplorerBrowserPostJsonRequestWithTokenHeaderNotBlocked()
114             throws Exception {
115         addTokenHeaderToRequest(httpServletRequest, XsrfResourceFilter.NO_CHECK);
116         setJsonContentTypeForRequest(request);
117         for (String userAgent : Arrays.asList(IE_8_UA, IE_10_UA, IE_11_UA)) {
118             setBrowserUserAgentInRequest(request, userAgent);
119             xsrfResourceFilter.filter(request);
120         }
121     }
122 
123     @Test(expected = XsrfCheckFailedException.class)
124     public void browserPostNoContentTypeRequestBlocked() throws Exception {
125         setBrowserUserAgentInRequest(request);
126         setRequestContentType(request, null);
127         xsrfResourceFilter.filter(request);
128     }
129 
130     @Test
131     public void nonBrowserPostNoContentTypeRequestNotBlocked() throws Exception {
132         setRequestContentType(request, null);
133         xsrfResourceFilter.filter(request);
134     }
135 
136     @Test
137     public void browserPostXsrfContentTypeRequestNotBlocked() throws Exception {
138         setBrowserUserAgentInRequest(request);
139         setXsrfableContentType(request);
140         xsrfResourceFilter.filter(request);
141     }
142 
143     @Test
144     public void nonBrowserPostXsrfContentTypeRequestNotBlocked() throws Exception {
145         setXsrfableContentType(request);
146         xsrfResourceFilter.filter(request);
147     }
148 
149     @Test
150     public void browserDeleteXsrfContentTypeRequestNotBlocked() throws Exception {
151         when(request.getMethod()).thenReturn("DELETE");
152         setBrowserUserAgentInRequest(request);
153         setXsrfableContentType(request);
154         xsrfResourceFilter.filter(request);
155     }
156 
157     private void filterBrowserJsonRequest(ContainerRequest request)
158             throws Exception {
159         setBrowserUserAgentInRequest(request);
160         setJsonContentTypeForRequest(request);
161         xsrfResourceFilter.filter(request);
162     }
163 
164     static void setXsrfableContentType(ContainerRequest request) {
165         setRequestContentType(request, MediaType.TEXT_PLAIN_TYPE);
166     }
167 
168     private static void setJsonContentTypeForRequest(ContainerRequest request) {
169         setRequestContentType(request, MediaType.APPLICATION_JSON_TYPE);
170     }
171 
172     private static void setRequestContentType(ContainerRequest request,
173                                               MediaType mediaType) {
174         when(request.getMediaType()).thenReturn(mediaType);
175     }
176 
177     static void setBrowserUserAgentInRequest(ContainerRequest request) {
178         setBrowserUserAgentInRequest(request, CHROME_32_UA);
179     }
180 
181     private static void setBrowserUserAgentInRequest(ContainerRequest request, String userAgent) {
182         when(request.getHeaderValue("User-Agent")).thenReturn(userAgent);
183     }
184 
185 }