Skip to content

Commit a2179c1

Browse files
Disable serving Internet Explorer by default #101
* Applied the User-Agent check to the JavaScriptServlet as well (although if the CsrfGuardFilter is correctly configured against the web root, it should not be needed)
1 parent 919f8f6 commit a2179c1

File tree

3 files changed

+47
-35
lines changed

3 files changed

+47
-35
lines changed

csrfguard/src/main/java/org/owasp/csrfguard/CsrfGuardFilter.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,7 @@ public void doFilter(final ServletRequest request, final ServletResponse respons
6464
final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
6565
final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
6666

67-
final String[] bannedUserAgentProperties = csrfGuard.getBannedUserAgentProperties().toArray(new String[0]);
68-
final String userAgent = httpServletRequest.getHeader("User-Agent");
69-
if (bannedUserAgentProperties.length > 0 && StringUtils.containsAnyIgnoreCase(userAgent, bannedUserAgentProperties)) {
70-
LOGGER.warn("HTTP request with forbidden User-Agent: '{}'", userAgent);
71-
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden HTTP Client!");
72-
} else {
67+
if (CsrfGuardUtils.isPermittedUserAgent(httpServletRequest, httpServletResponse, csrfGuard)) {
7368
doFilter(httpServletRequest, httpServletResponse, filterChain, csrfGuard);
7469
}
7570
} else {

csrfguard/src/main/java/org/owasp/csrfguard/servlet/JavaScriptServlet.java

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,7 @@
5050
import java.net.MalformedURLException;
5151
import java.net.URL;
5252
import java.nio.charset.Charset;
53-
import java.util.HashMap;
54-
import java.util.HashSet;
55-
import java.util.Map;
56-
import java.util.Objects;
57-
import java.util.Set;
53+
import java.util.*;
5854
import java.util.function.BiFunction;
5955
import java.util.regex.Pattern;
6056

@@ -99,7 +95,7 @@ public final class JavaScriptServlet extends HttpServlet {
9995
private static final String TOKENS_PER_PAGE_IDENTIFIER = "'%TOKENS_PER_PAGE%'";
10096

10197
private static final String ASYNC_XHR = "'%ASYNC_XHR%'";
102-
98+
10399
private static final Map<String, BiFunction<CsrfGuard, HttpServletRequest, String>> JS_REPLACEMENT_MAP = new HashMap<>();
104100

105101
static {
@@ -121,7 +117,6 @@ public final class JavaScriptServlet extends HttpServlet {
121117
JS_REPLACEMENT_MAP.put(DOMAIN_STRICT_IDENTIFIER, (csrfGuard, request) -> Boolean.toString(csrfGuard.isJavascriptDomainStrict()));
122118
JS_REPLACEMENT_MAP.put(ASYNC_XHR, (csrfGuard, request) -> Boolean.toString(!csrfGuard.isForceSynchronousAjax()));
123119
}
124-
125120

126121
/* MIME Type constants */
127122
private static final String JSON_MIME_TYPE = "application/json";
@@ -157,16 +152,17 @@ public void init(final ServletConfig theServletConfig) {
157152
csrfGuard.initializeJavaScriptConfiguration();
158153

159154
// print again since it might change based on servlet config of javascript servlet
160-
CsrfGuardServletContextListener.printConfigIfConfigured(servletConfig.getServletContext(),
161-
"Printing properties after JavaScript servlet, note, the javascript properties have now been initialized: ");
155+
CsrfGuardServletContextListener.printConfigIfConfigured(servletConfig.getServletContext(), "Printing properties after JavaScript servlet, note, the javascript properties have now been initialized: ");
162156
}
163157

164158
@Override
165159
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
166160
final CsrfGuard csrfGuard = CsrfGuard.getInstance();
167161

168162
if (csrfGuard.isEnabled()) {
169-
writeJavaScript(csrfGuard, request, response);
163+
if (CsrfGuardUtils.isPermittedUserAgent(request, response, csrfGuard)) {
164+
writeJavaScript(csrfGuard, request, response);
165+
}
170166
} else {
171167
response.setContentType(JAVASCRIPT_MIME_TYPE);
172168
final String javaScriptCode = "console.log('CSRFGuard is disabled');";
@@ -178,22 +174,24 @@ public void doGet(final HttpServletRequest request, final HttpServletResponse re
178174
public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
179175
final CsrfGuard csrfGuard = CsrfGuard.getInstance();
180176

181-
if (new CsrfValidator().isValid(request, response)) {
182-
if (csrfGuard.isTokenPerPageEnabled()) {
183-
// TODO pass the logical session downstream, see whether the null check can be done from here
184-
final LogicalSession logicalSession = csrfGuard.getLogicalSessionExtractor().extract(request);
185-
if (Objects.isNull(logicalSession)) {
186-
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Could not create a logical session from the current request.");
177+
if (CsrfGuardUtils.isPermittedUserAgent(request, response, csrfGuard)) {
178+
if (new CsrfValidator().isValid(request, response)) {
179+
if (csrfGuard.isTokenPerPageEnabled()) {
180+
// TODO pass the logical session downstream, see whether the null check can be done from here
181+
final LogicalSession logicalSession = csrfGuard.getLogicalSessionExtractor().extract(request);
182+
if (Objects.isNull(logicalSession)) {
183+
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Could not create a logical session from the current request.");
184+
} else {
185+
final Map<String, String> pageTokens = csrfGuard.getTokenService().getPageTokens(logicalSession.getKey());
186+
final TokenTO tokenTO = new TokenTO(pageTokens);
187+
writeTokens(response, tokenTO);
188+
}
187189
} else {
188-
final Map<String, String> pageTokens = csrfGuard.getTokenService().getPageTokens(logicalSession.getKey());
189-
final TokenTO tokenTO = new TokenTO(pageTokens);
190-
writeTokens(response, tokenTO);
190+
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "This endpoint should not be invoked if the Token-Per-Page functionality is disabled!");
191191
}
192192
} else {
193-
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "This endpoint should not be invoked if the Token-Per-Page functionality is disabled!");
193+
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Master token missing from the request.");
194194
}
195-
} else {
196-
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Master token missing from the request.");
197195
}
198196
}
199197

@@ -220,11 +218,11 @@ private static void writeJavaScript(final HttpServletRequest request, final Http
220218
}
221219

222220
response.setContentType(JAVASCRIPT_MIME_TYPE);
223-
221+
224222
final String[] replacementList = JS_REPLACEMENT_MAP.values().stream().map(v -> v.apply(csrfGuard, request)).toArray(String[]::new);
225223

226224
final String code = StringUtils.replaceEach(csrfGuard.getJavascriptTemplateCode(), JS_REPLACEMENT_MAP.keySet().toArray(new String[0]), replacementList);
227-
225+
228226
response.getWriter().write(code);
229227
}
230228

@@ -270,12 +268,12 @@ private void writeJavaScript(final CsrfGuard csrfGuard, final HttpServletRequest
270268
}
271269
}
272270
} else {
273-
if (!javaScriptReferer.equals(JavaScriptConfigParameters.DEFAULT_REFERER_PATTERN)) {
274-
LOGGER.error("Missing referer headers are not accepted if a non-default referer pattern '{}' is configured!", javaScriptReferer);
271+
if (!javaScriptReferer.equals(JavaScriptConfigParameters.DEFAULT_REFERER_PATTERN)) {
272+
LOGGER.error("Missing referer headers are not accepted if a non-default referer pattern '{}' is configured!", javaScriptReferer);
275273

276-
response.sendError(HttpServletResponse.SC_FORBIDDEN);
277-
return;
278-
}
274+
response.sendError(HttpServletResponse.SC_FORBIDDEN);
275+
return;
276+
}
279277
}
280278

281279
// save this path so javascript is whitelisted

csrfguard/src/main/java/org/owasp/csrfguard/util/CsrfGuardUtils.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.owasp.csrfguard.CsrfGuard;
3535
import org.owasp.csrfguard.config.overlay.ConfigPropertiesCascadeCommonUtils;
3636
import org.owasp.csrfguard.token.transferobject.TokenTO;
37+
import org.slf4j.Logger;
38+
import org.slf4j.LoggerFactory;
3739

3840
import javax.servlet.http.HttpServletRequest;
3941
import javax.servlet.http.HttpServletResponse;
@@ -51,6 +53,8 @@
5153
*/
5254
public final class CsrfGuardUtils {
5355

56+
private static final Logger LOGGER = LoggerFactory.getLogger(CsrfGuardUtils.class.getName());
57+
5458
private CsrfGuardUtils() {}
5559

5660
/**
@@ -146,6 +150,21 @@ public static String readInputStreamContent(final InputStream inputStream) {
146150
}
147151
}
148152

153+
public static boolean isPermittedUserAgent(HttpServletRequest request, HttpServletResponse response, CsrfGuard csrfGuard) throws IOException {
154+
final boolean result;
155+
156+
final String[] bannedUserAgentProperties = csrfGuard.getBannedUserAgentProperties().toArray(new String[0]);
157+
final String userAgent = request.getHeader("User-Agent");
158+
if (bannedUserAgentProperties.length > 0 && StringUtils.containsAnyIgnoreCase(userAgent, bannedUserAgentProperties)) {
159+
LOGGER.warn("HTTP request with forbidden User-Agent: '{}'", userAgent);
160+
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden HTTP Client!");
161+
result = false;
162+
} else {
163+
result = true;
164+
}
165+
return result;
166+
}
167+
149168
/**
150169
* for a url, get the protocol and domain, e.g. for url https://a.b/path, will return https://a.b
151170
*

0 commit comments

Comments
 (0)