Java: adjust prefix barriers

This commit is contained in:
Jami Cogswell
2024-03-12 20:44:53 -04:00
parent e99cea340b
commit 04d27f2d65
2 changed files with 41 additions and 12 deletions

View File

@@ -41,29 +41,50 @@ abstract class UrlForwardBarrier extends DataFlow::Node { }
private class PrimitiveBarrier extends UrlForwardBarrier instanceof SimpleTypeSanitizer { }
private class FollowsBarrierPrefix extends DataFlow::Node {
FollowsBarrierPrefix() { this.asExpr() = any(BarrierPrefix fp).getAnAppendedExpression() }
/**
* A barrier for values appended to a "redirect:" prefix.
* These results are excluded because they should be handled
* by the `java/unvalidated-url-redirection` query instead.
*/
private class RedirectPrefixBarrier extends UrlForwardBarrier {
RedirectPrefixBarrier() { this.asExpr() = any(RedirectPrefix fp).getAnAppendedExpression() }
}
private class BarrierPrefix extends InterestingPrefix {
BarrierPrefix() {
not this.getStringValue().matches("/WEB-INF/%") and
not this instanceof ForwardPrefix
}
private class RedirectPrefix extends InterestingPrefix {
RedirectPrefix() { this.getStringValue() = "redirect:" }
override int getOffset() { result = 0 }
}
/**
* A barrier that protects against path injection vulnerabilities while accounting
* for URL encoding and concatenated prefixes.
* A value that is the result of prepending a string that prevents
* any value from controlling the path of a URL.
*/
private class FollowsBarrierPrefix extends UrlForwardBarrier {
FollowsBarrierPrefix() { this.asExpr() = any(BarrierPrefix fp).getAnAppendedExpression() }
}
private class BarrierPrefix extends InterestingPrefix {
int offset;
BarrierPrefix() {
// Matches strings that look like when prepended to untrusted input, they will restrict
// the path of a URL: for example, anything containing `?` or `#`.
exists(this.getStringValue().regexpFind("[?#]", 0, offset))
}
override int getOffset() { result = offset }
}
/**
* A barrier that protects against path injection vulnerabilities
* while accounting for URL encoding.
*/
private class UrlPathBarrier extends UrlForwardBarrier instanceof PathInjectionSanitizer {
UrlPathBarrier() {
this instanceof ExactPathMatchSanitizer or
this instanceof NoUrlEncodingBarrier or
this instanceof FullyDecodesUrlBarrier or
this instanceof FollowsBarrierPrefix
this instanceof FullyDecodesUrlBarrier
}
}

View File

@@ -48,6 +48,14 @@ public class UrlForwardTest extends HttpServlet implements Filter {
return modelAndView;
}
// Not relevant for this query since redirecting instead of forwarding
// This result should be found by the `java/unvalidated-url-redirection` query instead.
@GetMapping("/redirect")
public ModelAndView redirect(String url) {
ModelAndView modelAndView = new ModelAndView("redirect:" + url);
return modelAndView;
}
// `RequestDispatcher` test cases from a Spring `GetMapping` entry point
@GetMapping("/bad5")
public void bad5(String url, HttpServletRequest request, HttpServletResponse response) {
@@ -85,7 +93,7 @@ public class UrlForwardTest extends HttpServlet implements Filter {
@GetMapping("/good1")
public void good1(String url, HttpServletRequest request, HttpServletResponse response) {
try {
request.getRequestDispatcher("/index.jsp?token=" + url).forward(request, response); // $ SPURIOUS: hasUrlForward
request.getRequestDispatcher("/index.jsp?token=" + url).forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {