This project has retired. For details please refer to its
Attic page.
CsrfManager xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.server.shared;
20
21 import java.security.SecureRandom;
22
23 import javax.servlet.ServletConfig;
24 import javax.servlet.ServletException;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27 import javax.servlet.http.HttpSession;
28
29 import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
30
31 public class CsrfManager {
32
33 public static final String CSRF_ATTR = "org.apache.chemistry.opencmis.csrftoken";
34
35 private static final String CSRF_HEADER = "csrfHeader";
36 private static final String CSRF_PARAMETER = "csrfParameter";
37 private static final String FETCH_VALUE = "fetch";
38
39 private static char[][] hexArrays = new char[][] { "0123456789ABCDEF".toCharArray(),
40 "0123456789abcdef".toCharArray(),
41 "ABCDEFGHIJKLMNOP".toCharArray(),
42 "abcdefghijklmnop".toCharArray() };
43
44 private String csrfHeader;
45 private String csrfParameter;
46
47 private SecureRandom random = new SecureRandom();
48
49 public CsrfManager(String csrfHeader, String csrfParameter) {
50 if (csrfHeader != null) {
51 this.csrfHeader = csrfHeader.trim();
52 if (this.csrfHeader.length() == 0) {
53 throw new IllegalArgumentException("Invalid CSRF header!");
54 }
55 if (csrfParameter != null) {
56 this.csrfParameter = csrfParameter.trim();
57 if (this.csrfParameter.length() == 0) {
58 throw new IllegalArgumentException("Invalid CSRF parameter!");
59 }
60 }
61 }
62 }
63
64 public CsrfManager(ServletConfig config) throws ServletException {
65 csrfHeader = config.getInitParameter(CSRF_HEADER);
66 if (csrfHeader != null) {
67 this.csrfHeader = csrfHeader.trim();
68 if (this.csrfHeader.length() == 0) {
69 throw new ServletException("Invalid CSRF header!");
70 }
71
72
73 csrfParameter = config.getInitParameter(CSRF_PARAMETER);
74 if (csrfParameter != null) {
75 this.csrfParameter = csrfParameter.trim();
76 if (this.csrfParameter.length() == 0) {
77 throw new ServletException("Invalid CSRF parameter!");
78 }
79 }
80 }
81 }
82
83 public void check(HttpServletRequest req, HttpServletResponse resp, boolean isRepositoryInfoRequest,
84 boolean isContentRequest) {
85 if (csrfHeader == null) {
86
87 return;
88 }
89
90 HttpSession httpSession = req.getSession(true);
91 String token = (String) httpSession.getAttribute(CSRF_ATTR);
92 String headerValue = req.getHeader(csrfHeader);
93
94
95
96 if (headerValue == null || headerValue.isEmpty()) {
97 if (isContentRequest && csrfParameter != null) {
98 String paramValue = req.getParameter(csrfParameter);
99 if (paramValue != null && paramValue.equals(token)) {
100 return;
101 }
102 }
103
104 throw new CmisPermissionDeniedException("Invalid CSRF token!");
105 }
106
107
108 if (isRepositoryInfoRequest && FETCH_VALUE.equals(headerValue) && token == null) {
109 token = generateNewToken();
110 httpSession.setAttribute(CSRF_ATTR, token);
111 resp.addHeader(csrfHeader, token);
112 return;
113 }
114
115
116 if (token == null) {
117 throw new CmisPermissionDeniedException("Invalid CSRF token!");
118 }
119
120
121 if (!token.equals(headerValue)) {
122 throw new CmisPermissionDeniedException("Invalid CSRF token!");
123 }
124 }
125
126 private String generateNewToken() {
127 byte[] tokenBytes = new byte[16];
128 random.nextBytes(tokenBytes);
129
130 int ary = random.nextInt(hexArrays.length);
131
132 char[] token = new char[tokenBytes.length * 2];
133 for (int i = 0; i < tokenBytes.length; i++) {
134 int v = tokenBytes[i] & 0xFF;
135 token[i * 2] = hexArrays[ary][v >>> 4];
136 token[i * 2 + 1] = hexArrays[ary][v & 0x0F];
137 }
138
139 return new String(token);
140 }
141 }