diff --git a/java/ql/lib/change-notes/2026-08-17-spring-url-redirect-sinks.md b/java/ql/lib/change-notes/2026-08-17-spring-url-redirect-sinks.md new file mode 100644 index 000000000000..ad17bde080b9 --- /dev/null +++ b/java/ql/lib/change-notes/2026-08-17-spring-url-redirect-sinks.md @@ -0,0 +1,8 @@ +--- +category: minorAnalysis +--- +* The `java/unvalidated-url-redirection` query now detects untrusted URLs used in returned Spring MVC + `RedirectView` objects and leading `redirect:` view names, including helper-generated names passed + to returned `ModelAndView` objects, conditional or branch-assigned names, and local prefix variables. + Redirect views wrapped in `ModelAndView` and view objects returned by response-body handlers are + also covered. diff --git a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll index be6addfa2529..048ed09d020d 100644 --- a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll +++ b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll @@ -8,7 +8,10 @@ import semmle.code.java.frameworks.Servlets import semmle.code.java.frameworks.ApacheHttp private import semmle.code.java.dataflow.ExternalFlow private import semmle.code.java.dataflow.FlowSinks +private import semmle.code.java.dataflow.SSA +private import semmle.code.java.dataflow.TaintTracking private import semmle.code.java.frameworks.JaxWS +private import semmle.code.java.frameworks.spring.SpringController private import semmle.code.java.security.RequestForgery /** A URL redirection sink. */ @@ -50,5 +53,193 @@ private class ApacheUrlRedirectSink extends UrlRedirectSink { } } +/** An expression appended to a Spring `"redirect:"` view-name returned by a request handler. */ +private class SpringUrlRedirectPrefixSink extends UrlRedirectSink { + SpringUrlRedirectPrefixSink() { + exists(Expr name | + (isSpringMvcReturnedString(name) or isSpringModelAndViewName(name)) and + this.asExpr() = getRedirectTarget(name) and + TaintTracking::localTaint(this, DataFlow::exprNode(name)) + ) + } +} + +/** A call to a helper that returns a Spring `"redirect:"` view name. */ +private class SpringUrlRedirectHelperSink extends UrlRedirectSink { + SpringUrlRedirectHelperSink() { + exists(Expr name, MethodCall call | + this.asExpr() = call and + (isSpringMvcReturnedString(name) or isSpringModelAndViewName(name)) and + call = getViewNamePrefix(name) and + returnsRedirectViewName(call.getCallee().getSourceDeclaration()) + ) + } +} + +/** The exact Spring redirect prefix, without a fixed target path or host. */ +private class SpringRedirectPrefix extends CompileTimeConstantExpr { + SpringRedirectPrefix() { this.getStringValue() = "redirect:" } +} + +/** Relates a local read to its reaching SSA definitions. */ +private predicate localViewDefinition(Expr value, SsaDefinition def) { + value.getUnderlyingExpr().(VarRead).getVariable() instanceof LocalVariableDecl and + def.getARead() = value.getUnderlyingExpr() +} + +/** Gets a possible local view-name value, following conditional branches and SSA inputs. */ +pragma[nomagic] +private Expr getAViewNameValue(Expr value) { + result = value.getUnderlyingExpr() and + not result instanceof ConditionalExpr and + ( + not exists(SsaDefinition def | localViewDefinition(value, def)) + or + exists(SsaDefinition def | + localViewDefinition(value, def) and + not exists(def.getAnUltimateDefinition().(SsaExplicitWrite).getValue()) + ) + ) + or + exists(SsaDefinition def | + localViewDefinition(value, def) and + result = getAViewNameValue(def.getAnUltimateDefinition().(SsaExplicitWrite).getValue()) + ) + or + result = getAViewNameValue(value.getUnderlyingExpr().(ConditionalExpr).getABranchExpr()) +} + +/** Gets a possible leading expression, following only left-hand concatenation. */ +pragma[nomagic] +private Expr getViewNamePrefix(Expr value) { + result = getAViewNameValue(value) and not result instanceof AddExpr + or + result = getViewNamePrefix(getAViewNameValue(value).(AddExpr).getLeftOperand()) +} + +/** Gets the target appended to an exact redirect prefix at the start of a view name. */ +pragma[nomagic] +private Expr getRedirectTarget(Expr value) { + exists(AddExpr add | add = getAViewNameValue(value) | + getViewNamePrefix(add.getLeftOperand()) instanceof SpringRedirectPrefix and + result = add.getRightOperand() + or + result = getRedirectTarget(add.getLeftOperand()) + ) +} + +/** Holds if `value` contributes to a view returned from a Spring MVC request handler. */ +pragma[nomagic] +private predicate isSpringMvcViewResult(Expr value) { + exists(ReturnStmt ret | + ret.getEnclosingCallable() = value.getEnclosingCallable() and + ret.getEnclosingCallable() instanceof SpringRequestMappingMethod and + DataFlow::localFlow(DataFlow::exprNode(value), DataFlow::exprNode(ret.getExpr())) + ) + or + exists(ClassInstanceExpr newModelAndView | + newModelAndView + .getConstructedType() + .hasQualifiedName("org.springframework.web.servlet", "ModelAndView") and + newModelAndView + .getConstructor() + .getParameter(0) + .getType() + .(RefType) + .hasQualifiedName("org.springframework.web.servlet", "View") and + DataFlow::localFlow(DataFlow::exprNode(value), + DataFlow::exprNode(newModelAndView.getArgument(0))) and + isSpringMvcViewResult(newModelAndView) + ) +} + +/** Holds if `name` is a string view name returned by a request handler. */ +private predicate isSpringMvcReturnedString(Expr name) { + exists(ReturnStmt ret, SpringRequestMappingMethod handler | + handler = name.getEnclosingCallable() and + ret.getEnclosingCallable() = handler and + not handler.isResponseBody() and + not handler instanceof SpringModelAttributeMethod and + name = ret.getExpr() + ) +} + +/** Holds if `name` is the string view name of a returned `ModelAndView`. */ +private predicate isSpringModelAndViewName(Expr name) { + exists(ClassInstanceExpr newModelAndView | + newModelAndView + .getConstructedType() + .hasQualifiedName("org.springframework.web.servlet", "ModelAndView") and + newModelAndView.getConstructor().getParameter(0).getType() instanceof TypeString and + name = newModelAndView.getArgument(0) and + isSpringMvcViewResult(newModelAndView) + ) +} + +/** Holds if a name is constant or is constructed from the exact redirect prefix. */ +private predicate isConstantOrRedirectViewName(Expr name) { + exists(getAViewNameValue(name)) and + forall(Expr value | value = getAViewNameValue(name) | + exists(value.(CompileTimeConstantExpr).getStringValue()) + or + exists(getViewNamePrefix(value)) and + forall(Expr prefix | prefix = getViewNamePrefix(value) | prefix instanceof SpringRedirectPrefix) + ) +} + +/** Holds if `callable` returns redirect names without mixing in other dynamic view names. */ +pragma[nomagic] +private predicate returnsRedirectViewName(Callable callable) { + exists(Expr target, ReturnStmt ret | + callable.(Method).getReturnType() instanceof TypeString and + forall(ReturnStmt r | r.getEnclosingCallable() = callable | + isConstantOrRedirectViewName(r.getExpr()) + ) and + ret.getEnclosingCallable() = callable and + target = getRedirectTarget(ret.getExpr()) and + TaintTracking::localTaint(DataFlow::exprNode(target), DataFlow::exprNode(ret.getExpr())) + ) + or + exists(MethodCall call, ReturnStmt ret | + callable.(Method).getReturnType() instanceof TypeString and + ret = unique(ReturnStmt r | r.getEnclosingCallable() = callable) and + call = unique(Expr prefix | prefix = getViewNamePrefix(ret.getExpr())) and + returnsRedirectViewName(call.getCallee().getSourceDeclaration()) + ) +} + +/** A URL passed to a Spring `RedirectView` constructor. */ +private class SpringRedirectViewSink extends UrlRedirectSink { + SpringRedirectViewSink() { + exists(ClassInstanceExpr newRedirectView | + newRedirectView + .getConstructedType() + .hasQualifiedName("org.springframework.web.servlet.view", "RedirectView") and + isSpringMvcViewResult(newRedirectView) and + this.asExpr() = newRedirectView.getArgument(0) + ) + } +} + +/** A URL passed to `setUrl` on a Spring `RedirectView` that is returned by a request handler. */ +private class SpringRedirectViewSetUrlSink extends UrlRedirectSink { + SpringRedirectViewSetUrlSink() { + exists(MethodCall setUrl | + setUrl + .getMethod() + .getSourceDeclaration() + .hasQualifiedName("org.springframework.web.servlet.view", "AbstractUrlBasedView", "setUrl") and + setUrl + .getQualifier() + .getType() + .(RefType) + .getASupertype*() + .hasQualifiedName("org.springframework.web.servlet.view", "RedirectView") and + isSpringMvcViewResult(setUrl.getQualifier()) and + this.asExpr() = setUrl.getArgument(0) + ) + } +} + private class DefaultUrlRedirectSanitizer extends UrlRedirectSanitizer instanceof RequestForgerySanitizer { } diff --git a/java/ql/test/query-tests/security/CWE-601/semmle/tests/SpringUrlRedirect.java b/java/ql/test/query-tests/security/CWE-601/semmle/tests/SpringUrlRedirect.java new file mode 100644 index 000000000000..f659b85f6ab5 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-601/semmle/tests/SpringUrlRedirect.java @@ -0,0 +1,779 @@ +package test.cwe601.cwe.examples; + +import javax.servlet.http.HttpServletRequest; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.view.RedirectView; + +class BaseController { + protected String redirect(String path) { + return "redirect:" + path; + } + + protected String ordinaryView(String path) { + return "view:" + path; + } + + protected String discardedRedirect(String path) { + return "redirect:" + path; + } +} + +class LabeledRedirectView extends RedirectView { + LabeledRedirectView(String label, String url) { + super(url); + } + + void setUrl(Object label) { + } +} + +@Controller +public class SpringUrlRedirect extends BaseController { + @GetMapping("/case1") + public String directViewName(HttpServletRequest request) { + String next = request.getHeader("referer"); // $ Source + return "redirect:" + next; // $ Alert + } + + @GetMapping("/case2") + public ModelAndView modelAndView(HttpServletRequest request) { + String next = request.getHeader("referer"); // $ Source + return new ModelAndView("redirect:" + next); // $ Alert + } + + @GetMapping("/case3") + public RedirectView redirectView(HttpServletRequest request) { + String next = request.getHeader("referer"); // $ Source + return new RedirectView(next); // $ Alert + } + + @GetMapping("/case4") + public String helperViewName(HttpServletRequest request) { + String next = request.getHeader("referer"); // $ Source + return redirect(next); // $ Alert + } + + @GetMapping("/case5") + public RedirectView configuredRedirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(); + view.setUrl(next); // $ Alert + return view; + } + + @GetMapping("/case6") + public RedirectView overloadedRedirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new RedirectView(next, true); // $ Alert + } + + @GetMapping("/safe-constant") + public String constantViewName() { + return "redirect:/account"; + } + + @GetMapping("/safe-path") + public String fixedPath(HttpServletRequest request) { + String tab = request.getParameter("tab"); + return "redirect:/account?tab=" + tab; + } + + @GetMapping("/safe-model-and-view") + public ModelAndView ordinaryModelAndView(HttpServletRequest request) { + String view = request.getParameter("view"); + return new ModelAndView(ordinaryView(view)); + } + + @GetMapping("/safe-model-value") + public ModelAndView redirectInModel(HttpServletRequest request) { + String value = "redirect:" + request.getParameter("value"); + return new ModelAndView("home", "value", value); + } + + @GetMapping("/safe-discarded") + public String discardedRedirectValue(HttpServletRequest request) { + discardedRedirect(request.getParameter("next")); + return "home"; + } + + @GetMapping("/safe-redirect-view") + public RedirectView constantRedirectView() { + return new RedirectView("https://example.com/account"); + } + + @GetMapping("/safe-subclass-label") + public RedirectView customRedirectView(HttpServletRequest request) { + String label = request.getParameter("label"); + return new LabeledRedirectView(label, "/account"); + } + + @GetMapping("/safe-set-url-overload") + public RedirectView customSetUrl(HttpServletRequest request) { + LabeledRedirectView view = new LabeledRedirectView("label", "/account"); + Object label = request.getParameter("label"); + view.setUrl(label); + return view; + } +} + +@Controller +class ResponseBodyController { + @ResponseBody + @GetMapping("/body") + public String responseBody(HttpServletRequest request) { + return "redirect:" + request.getParameter("value"); + } +} + +@RestController +class JsonController { + @GetMapping("/json") + public String responseBody(HttpServletRequest request) { + return "redirect:" + request.getParameter("value"); + } +} + +class SharedRedirectHelper { + protected String redirectShared(String path) { + return "redirect:" + path; + } +} + +@Controller +class MvcViewUser extends SharedRedirectHelper { + @GetMapping("/constant-view") + public String view() { + return redirectShared("/account"); + } +} + +@Controller +class ResponseBodyUser extends SharedRedirectHelper { + @ResponseBody + @GetMapping("/body-user") + public String body(HttpServletRequest request) { + return redirectShared(request.getParameter("value")); + } +} + +@Controller +class SpringRedirectRegressions extends BaseController { + + protected String embeddedRedirect(String path) { + String base = "home"; + return base + "redirect:" + path; + } + + protected String fixedRelativeRedirect(String tab) { + return "redirect:/account?tab=" + tab; + } + + protected String mixedRedirect(String path, boolean useConstant) { + if (useConstant) { + return "redirect:" + "/account"; + } + return "home:" + path; + } + + @GetMapping("/helper-model-and-view") + public ModelAndView helperModelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(redirect(next)); // $ Alert + } + + @GetMapping("/helper-model-and-view-model") + public ModelAndView helperModelAndViewWithModel(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(redirect(next), "note", "value"); // $ Alert + } + + @GetMapping("/redirect-with-suffix") + public String redirectWithSuffix(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return "redirect:" + next + "?tab=profile"; // $ Alert + } + + @GetMapping("/local-model-and-view-name") + public ModelAndView localModelAndViewName(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + String viewName = "redirect:" + next; // $ Alert + return new ModelAndView(viewName); + } + + @GetMapping("/safe-leading-view-name") + public String leadingViewName(HttpServletRequest request) { + String next = request.getParameter("next"); + String base = "home"; + return base + "redirect:" + next; + } + + @GetMapping("/safe-leading-model-and-view") + public ModelAndView leadingModelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); + String base = "home"; + return new ModelAndView(base + "redirect:" + next); + } + + @GetMapping("/safe-leading-helper-model-and-view") + public ModelAndView leadingHelperModelAndView(HttpServletRequest request) { + return new ModelAndView("home" + redirect(request.getParameter("next"))); + } + + @GetMapping("/safe-embedded-helper-prefix") + public String embeddedHelperPrefix(HttpServletRequest request) { + return embeddedRedirect(request.getParameter("next")); + } + + @GetMapping("/safe-helper-model-value") + public ModelAndView helperInModel(HttpServletRequest request) { + return new ModelAndView("home", "value", redirect(request.getParameter("next"))); + } + + @GetMapping("/safe-discarded-model-and-view") + public ModelAndView discardedModelAndView(HttpServletRequest request) { + new ModelAndView(redirect(request.getParameter("next"))); + return new ModelAndView("home"); + } + + @GetMapping("/safe-logged-helper") + public String loggedHelper(HttpServletRequest request) { + System.out.println(redirect(request.getParameter("next"))); + return "home"; + } + + @GetMapping("/safe-leading-builder") + public String leadingBuilder(HttpServletRequest request) { + StringBuilder builder = new StringBuilder("home"); + builder.append("redirect:"); + builder.append(request.getParameter("next")); + return builder.toString(); + } + + @GetMapping("/safe-leading-format") + public String leadingFormat(HttpServletRequest request) { + return "home" + String.format("redirect:%s", request.getParameter("next")); + } + + @GetMapping("/safe-fixed-relative-helper") + public ModelAndView fixedRelativeHelper(HttpServletRequest request) { + return new ModelAndView(fixedRelativeRedirect(request.getParameter("tab"))); + } + + @GetMapping("/safe-mixed-helper") + public ModelAndView mixedHelper(HttpServletRequest request, boolean useConstant) { + return new ModelAndView(mixedRedirect(request.getParameter("next"), useConstant)); + } + + @GetMapping("/safe-validated-helper") + public ModelAndView validatedHelper(HttpServletRequest request) throws Exception { + java.net.URI uri = new java.net.URI(request.getParameter("next")); + if ("example.com".equals(uri.getHost())) { + return new ModelAndView(redirect(uri.toString())); + } + return new ModelAndView("home"); + } + + // As with other redirect sinks, later property writes do not suppress an alert. + @GetMapping("/overwritten-constructor-url") + public RedirectView overwrittenConstructorUrl(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + view.setUrl("/safe"); + return view; + } + + @GetMapping("/overwritten-setter-url") + public RedirectView overwrittenSetterUrl(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(); + view.setUrl(next); // $ Alert + view.setUrl("/safe"); + return view; + } + + @GetMapping("/overwritten-model-and-view-name") + public ModelAndView overwrittenModelAndViewName(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + ModelAndView view = new ModelAndView("redirect:" + next); // $ Alert + view.setViewName("home"); + return view; + } +} + +@Controller +class ResponseBodyRedirectRegressions extends BaseController { + + @ResponseBody + @GetMapping("/body-redirect-view") + public RedirectView redirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new RedirectView(next); // $ Alert + } + + @ResponseBody + @GetMapping("/body-model-and-view") + public ModelAndView modelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView("redirect:" + next); // $ Alert + } + + @ResponseBody + @GetMapping("/body-helper-model-and-view") + public ModelAndView helperModelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(redirect(next)); // $ Alert + } +} + +@RestController +class JsonRedirectRegressions extends BaseController { + + @GetMapping("/json-redirect-view") + public RedirectView redirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new RedirectView(next); // $ Alert + } + + @GetMapping("/json-model-and-view") + public ModelAndView modelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView("redirect:" + next); // $ Alert + } + + @GetMapping("/json-helper-model-and-view") + public ModelAndView helperModelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(redirect(next)); // $ Alert + } + + @GetMapping("/json-configured-redirect-view") + public RedirectView configuredRedirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(); + view.setUrl(next); // $ Alert + return view; + } + + @GetMapping("/json-object-redirect-view") + public Object objectRedirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new RedirectView(next); // $ Alert + } +} + +@Controller +class SpringViewPropertyRegressions extends SpringRedirectRegressions { + @GetMapping("/conditional-url-overwrite") + public RedirectView conditionalUrlOverwrite(HttpServletRequest request, boolean replace) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + if (replace) { + view.setUrl("/safe"); + } + return view; + } + + @GetMapping("/other-view-url-overwrite") + public RedirectView otherViewUrlOverwrite(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + RedirectView other = new RedirectView("/account"); + other.setUrl("/safe"); + return view; + } + + @GetMapping("/alias-url-overwrite") + public RedirectView aliasUrlOverwrite(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + RedirectView alias = view; + alias.setUrl("/safe"); + return view; + } + + @GetMapping("/conditional-alias-url-overwrite") + public RedirectView conditionalAliasUrlOverwrite(HttpServletRequest request, boolean replace) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + RedirectView alias = replace ? view : new RedirectView("/account"); + alias.setUrl("/safe"); + return view; + } + + @GetMapping("/returned-before-url-overwrite") + public RedirectView returnedBeforeUrlOverwrite(HttpServletRequest request, boolean keepOriginal) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + if (keepOriginal) { + return view; + } + view.setUrl("/safe"); + return view; + } + + @GetMapping("/later-unsafe-url-overwrite") + public RedirectView laterUnsafeUrlOverwrite(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + view.setUrl("/safe"); + view.setUrl(next); // $ Alert + return view; + } + + @GetMapping("/safe-mixed-helper-string") + public String mixedHelperString(HttpServletRequest request, boolean useConstant) { + return mixedRedirect(request.getParameter("next"), useConstant); + } + + @ResponseBody + @GetMapping("/safe-body-shared-view-helper") + public String responseBodySharedViewHelper(HttpServletRequest request) { + return redirect(request.getParameter("next")); + } +} + +@Controller +class SpringModelAndViewPropertyRegressions extends BaseController { + @GetMapping("/later-unsafe-model-and-view-overwrite") + public ModelAndView laterUnsafeModelAndViewOverwrite(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + ModelAndView view = new ModelAndView("redirect:" + next); // $ Alert + view.setViewName("home"); + view.setViewName("redirect:" + next); + return view; + } +} + +@Controller +class SpringAdditionalPrefixRegressions extends BaseController { + protected String conditionalMixedRedirect(String path, boolean useConstant) { + return useConstant ? redirect("/safe") : "home:" + path; + } + + protected String branchingRedirect(String path, boolean useConstant) { + if (useConstant) { + return "redirect:" + "/account"; + } + return "redirect:" + path; + } + + private static void restoreUrl(RedirectView view, String url) { + view.setUrl(url); + } + + @GetMapping("/safe-conditional-mixed-helper") + public ModelAndView conditionalMixedHelper(HttpServletRequest request, boolean useConstant) { + return new ModelAndView(conditionalMixedRedirect(request.getParameter("next"), useConstant)); + } + + @GetMapping("/helper-restores-unsafe-url") + public RedirectView helperRestoresUnsafeUrl(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + view.setUrl("/safe"); + restoreUrl(view, next); + return view; + } + + @GetMapping("/safe-outer-relative-prefix") + public String outerRelativePrefix(HttpServletRequest request) { + String next = request.getParameter("next"); + return "redirect:/safe/" + ("redirect:" + next); + } + + @GetMapping("/safe-outer-relative-model-and-view") + public ModelAndView outerRelativeModelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); + return new ModelAndView("redirect:/safe/" + ("redirect:" + next)); + } + + @GetMapping("/branching-view-name") + public String branchingViewName(HttpServletRequest request, boolean useConstant) { + String next = request.getParameter("next"); // $ Source + return branchingRedirect(next, useConstant); // $ Alert + } + + @GetMapping("/branching-model-and-view-name") + public ModelAndView branchingModelAndViewName(HttpServletRequest request, boolean useConstant) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(branchingRedirect(next, useConstant)); // $ Alert + } +} + +@Controller +class SpringRedirectHelperRegressions extends BaseController { + protected String internallyValidatedRedirect(String path) { + if (!java.util.Arrays.asList("/account", "/home").contains(path)) { + return "redirect:/safe"; + } + return "redirect:" + path; + } + + protected String internallySourcedRedirect(HttpServletRequest request) { + String next = request.getHeader("referer"); // $ Source + return "redirect:" + next; + } + + protected String secondRedirect(String... paths) { + return "redirect:" + paths[1]; + } + + protected String fixedBranchingRedirect(String tab, boolean useConstant) { + if (useConstant) { + return "redirect:/account"; + } + return "redirect:/account?tab=" + tab; + } + + private static void restoreArrayUrl(RedirectView[] views, String url) { + views[0].setUrl(url); + } + + @GetMapping("/safe-internally-validated-helper") + public ModelAndView internallyValidatedHelper(HttpServletRequest request) { + return new ModelAndView(internallyValidatedRedirect(request.getParameter("next"))); + } + + @GetMapping("/internally-sourced-helper") + public ModelAndView internallySourcedHelper(HttpServletRequest request) { + return new ModelAndView(internallySourcedRedirect(request)); // $ Alert + } + + @GetMapping("/varargs-model-and-view-name") + public ModelAndView varargsModelAndViewName(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(secondRedirect("/safe", next)); // $ Alert + } + + @GetMapping("/safe-fixed-branching-helper") + public ModelAndView fixedBranchingHelper(HttpServletRequest request, boolean useConstant) { + return new ModelAndView(fixedBranchingRedirect(request.getParameter("tab"), useConstant)); + } + + @GetMapping("/ambiguous-finally-url-overwrite") + public RedirectView ambiguousFinallyUrlOverwrite( + HttpServletRequest request, boolean flag, RedirectView supplied) { + String next = request.getParameter("next"); // $ Source + RedirectView result = new RedirectView(next); // $ Alert + RedirectView view = result; + try { + if (flag) { + return result; + } + view = supplied; + } finally { + view.setUrl("/safe"); + } + return result; + } + + @GetMapping("/array-helper-restores-unsafe-url") + public RedirectView arrayHelperRestoresUnsafeUrl(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + RedirectView[] views = { view }; + view.setUrl("/safe"); + restoreArrayUrl(views, next); + return view; + } +} + +@Controller +class SpringRedirectFallbackRegressions extends BaseController { + protected String branchingFallbackRedirect(String path, boolean useRedirect) { + if (useRedirect) { + return "redirect:" + path; + } + return "home"; + } + + @GetMapping("/branching-helper-with-ordinary-fallback") + public ModelAndView branchingFallbackModelAndView(HttpServletRequest request, boolean useRedirect) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(branchingFallbackRedirect(next, useRedirect)); // $ Alert + } +} + +@Controller +class SpringModelAttributeRedirectRegressions extends BaseController { + @org.springframework.web.bind.annotation.ModelAttribute("value") + @GetMapping("/safe-model-attribute-value") + public String modelAttributeValue(HttpServletRequest request) { + return "redirect:" + request.getParameter("next"); + } + + @org.springframework.web.bind.annotation.ModelAttribute("value") + @GetMapping("/model-attribute-redirect-view") + public RedirectView modelAttributeRedirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new RedirectView(next); // $ Alert + } + + @org.springframework.web.bind.annotation.ModelAttribute("value") + @GetMapping("/model-attribute-model-and-view") + public ModelAndView modelAttributeModelAndView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView("redirect:" + next); // $ Alert + } +} + +@Controller +class SpringConditionalRedirectRegressions extends BaseController { + @GetMapping("/original-conditional-helper") + public String originalConditionalHelper(HttpServletRequest request) { + String referer = request.getHeader("referer"); // $ Source + return org.springframework.util.StringUtils.isEmpty(referer) ? redirect("/") : redirect(referer); // $ Alert + } + + @GetMapping("/conditional-concatenation") + public String conditionalConcatenation(HttpServletRequest request, boolean useRedirect) { + String next = request.getParameter("next"); // $ Source + return useRedirect ? "redirect:" + next : "home"; // $ Alert + } + + @GetMapping("/branch-assigned-name") + public ModelAndView branchAssignedName(HttpServletRequest request, boolean useRedirect) { + String next = request.getParameter("next"); // $ Source + String name; + if (useRedirect) { + name = "redirect:" + next; // $ Alert + } else { + name = "home"; + } + return new ModelAndView(name); + } + + @GetMapping("/branch-assigned-helper") + public String branchAssignedHelper(HttpServletRequest request, boolean useRedirect) { + String next = request.getParameter("next"); // $ Source + String name; + if (useRedirect) { + name = redirect(next); // $ Alert + } else { + name = "home"; + } + return name; + } + + @GetMapping("/local-prefix") + public String localPrefix(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + String prefix = "redirect:"; + return prefix + next; // $ Alert + } + + protected String localPrefixHelper(String next) { + String prefix = "redirect:"; + return prefix + next; + } + + @GetMapping("/local-prefix-helper") + public ModelAndView localPrefixHelperName(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(localPrefixHelper(next)); // $ Alert + } + + @GetMapping("/conditional-prefix") + public String conditionalPrefix(HttpServletRequest request, boolean useRedirect) { + String next = request.getParameter("next"); // $ Source + String prefix = useRedirect ? "redirect:" : "home:"; + return prefix + next; // $ Alert + } + + @GetMapping("/safe-reassigned-prefix") + public String reassignedPrefix(HttpServletRequest request) { + String prefix = "redirect:"; + prefix = "home:"; + return prefix + request.getParameter("next"); + } + + @GetMapping("/safe-branch-assigned-name") + public String safeBranchAssignedName(HttpServletRequest request, boolean useRedirect) { + String name; + if (useRedirect) { + name = "redirect:/account"; + } else { + name = "home:" + request.getParameter("next"); + } + return name; + } + + @GetMapping("/safe-conditional-relative-name") + public String conditionalRelativeName(HttpServletRequest request, boolean useRedirect) { + return useRedirect ? "redirect:/account?tab=" + request.getParameter("tab") : "home"; + } + + @GetMapping("/safe-local-embedded-prefix") + public String localEmbeddedPrefix(HttpServletRequest request) { + String prefix = "redirect:"; + return "home" + prefix + request.getParameter("next"); + } + + @GetMapping("/safe-reassigned-view-name") + public String reassignedViewName(HttpServletRequest request) { + String name = "redirect:" + request.getParameter("next"); + name = "home"; + return name; + } + + @GetMapping("/empty-prefix-part") + public String emptyPrefixPart(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + String empty = ""; + return "redirect:" + empty + next; // $ Alert + } + + @GetMapping("/local-scheme-prefix") + public String localSchemePrefix(HttpServletRequest request) { + String host = request.getParameter("host"); // $ Source + String scheme = "https://"; + return "redirect:" + scheme + host; // $ Alert + } +} + +@RestController +class SpringWrappedRedirectRegressions { + @GetMapping("/wrapped-redirect-view") + public ModelAndView wrappedRedirectView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + return new ModelAndView(new RedirectView(next)); // $ Alert + } + + @GetMapping("/wrapped-configured-view") + public ModelAndView wrappedConfiguredView(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(); + view.setUrl(next); // $ Alert + return new ModelAndView(view); + } + + @GetMapping("/wrapped-view-with-model") + public ModelAndView wrappedViewWithModel(HttpServletRequest request) { + String next = request.getParameter("next"); // $ Source + RedirectView view = new RedirectView(next); // $ Alert + ModelAndView result = new ModelAndView(view, "note", "value"); + return result; + } + + @GetMapping("/safe-discarded-wrapper") + public ModelAndView discardedWrapper(HttpServletRequest request) { + new ModelAndView(new RedirectView(request.getParameter("next"))); + return new ModelAndView("home"); + } + + @GetMapping("/safe-view-in-model") + public ModelAndView viewInModel(HttpServletRequest request) { + return new ModelAndView("home", "view", new RedirectView(request.getParameter("next"))); + } + + @GetMapping("/safe-different-wrapped-view") + public ModelAndView differentWrappedView(HttpServletRequest request) { + RedirectView view = new RedirectView(); + view.setUrl(request.getParameter("next")); + return new ModelAndView(new RedirectView("/account")); + } +} diff --git a/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected b/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected index 7a16ee15c617..ddcc4038eb07 100644 --- a/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected +++ b/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected @@ -20,6 +20,57 @@ | MicronautUrlRedirect.java:28:47:28:64 | create(...) | MicronautUrlRedirect.java:27:45:27:69 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:27:45:27:69 | target | user-provided value | | MicronautUrlRedirect.java:33:38:33:55 | create(...) | MicronautUrlRedirect.java:32:44:32:68 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:32:44:32:68 | target | user-provided value | | MicronautUrlRedirect.java:38:47:38:64 | create(...) | MicronautUrlRedirect.java:37:45:37:69 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:37:45:37:69 | target | user-provided value | +| SpringUrlRedirect.java:39:30:39:33 | next | SpringUrlRedirect.java:38:23:38:50 | getHeader(...) : String | SpringUrlRedirect.java:39:30:39:33 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:38:23:38:50 | getHeader(...) | user-provided value | +| SpringUrlRedirect.java:45:47:45:50 | next | SpringUrlRedirect.java:44:23:44:50 | getHeader(...) : String | SpringUrlRedirect.java:45:47:45:50 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:44:23:44:50 | getHeader(...) | user-provided value | +| SpringUrlRedirect.java:51:33:51:36 | next | SpringUrlRedirect.java:50:23:50:50 | getHeader(...) : String | SpringUrlRedirect.java:51:33:51:36 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:50:23:50:50 | getHeader(...) | user-provided value | +| SpringUrlRedirect.java:57:16:57:29 | redirect(...) | SpringUrlRedirect.java:56:23:56:50 | getHeader(...) : String | SpringUrlRedirect.java:57:16:57:29 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:56:23:56:50 | getHeader(...) | user-provided value | +| SpringUrlRedirect.java:64:21:64:24 | next | SpringUrlRedirect.java:62:23:62:50 | getParameter(...) : String | SpringUrlRedirect.java:64:21:64:24 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:62:23:62:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:71:33:71:36 | next | SpringUrlRedirect.java:70:23:70:50 | getParameter(...) : String | SpringUrlRedirect.java:71:33:71:36 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:70:23:70:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:185:33:185:46 | redirect(...) | SpringUrlRedirect.java:184:23:184:50 | getParameter(...) : String | SpringUrlRedirect.java:185:33:185:46 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:184:23:184:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:191:33:191:46 | redirect(...) | SpringUrlRedirect.java:190:23:190:50 | getParameter(...) : String | SpringUrlRedirect.java:191:33:191:46 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:190:23:190:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:197:30:197:33 | next | SpringUrlRedirect.java:196:23:196:50 | getParameter(...) : String | SpringUrlRedirect.java:197:30:197:33 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:196:23:196:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:203:41:203:44 | next | SpringUrlRedirect.java:202:23:202:50 | getParameter(...) : String | SpringUrlRedirect.java:203:41:203:44 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:202:23:202:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:284:46:284:49 | next | SpringUrlRedirect.java:283:23:283:50 | getParameter(...) : String | SpringUrlRedirect.java:284:46:284:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:283:23:283:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:293:21:293:24 | next | SpringUrlRedirect.java:291:23:291:50 | getParameter(...) : String | SpringUrlRedirect.java:293:21:293:24 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:291:23:291:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:301:60:301:63 | next | SpringUrlRedirect.java:300:23:300:50 | getParameter(...) : String | SpringUrlRedirect.java:301:60:301:63 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:300:23:300:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:314:33:314:36 | next | SpringUrlRedirect.java:313:23:313:50 | getParameter(...) : String | SpringUrlRedirect.java:314:33:314:36 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:313:23:313:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:321:47:321:50 | next | SpringUrlRedirect.java:320:23:320:50 | getParameter(...) : String | SpringUrlRedirect.java:321:47:321:50 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:320:23:320:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:328:33:328:46 | redirect(...) | SpringUrlRedirect.java:327:23:327:50 | getParameter(...) : String | SpringUrlRedirect.java:328:33:328:46 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:327:23:327:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:338:33:338:36 | next | SpringUrlRedirect.java:337:23:337:50 | getParameter(...) : String | SpringUrlRedirect.java:338:33:338:36 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:337:23:337:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:344:47:344:50 | next | SpringUrlRedirect.java:343:23:343:50 | getParameter(...) : String | SpringUrlRedirect.java:344:47:344:50 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:343:23:343:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:350:33:350:46 | redirect(...) | SpringUrlRedirect.java:349:23:349:50 | getParameter(...) : String | SpringUrlRedirect.java:350:33:350:46 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:349:23:349:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:357:21:357:24 | next | SpringUrlRedirect.java:355:23:355:50 | getParameter(...) : String | SpringUrlRedirect.java:357:21:357:24 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:355:23:355:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:364:33:364:36 | next | SpringUrlRedirect.java:363:23:363:50 | getParameter(...) : String | SpringUrlRedirect.java:364:33:364:36 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:363:23:363:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:373:46:373:49 | next | SpringUrlRedirect.java:372:23:372:50 | getParameter(...) : String | SpringUrlRedirect.java:373:46:373:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:372:23:372:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:383:46:383:49 | next | SpringUrlRedirect.java:382:23:382:50 | getParameter(...) : String | SpringUrlRedirect.java:383:46:383:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:382:23:382:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:392:46:392:49 | next | SpringUrlRedirect.java:391:23:391:50 | getParameter(...) : String | SpringUrlRedirect.java:392:46:392:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:391:23:391:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:401:46:401:49 | next | SpringUrlRedirect.java:400:23:400:50 | getParameter(...) : String | SpringUrlRedirect.java:401:46:401:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:400:23:400:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:410:46:410:49 | next | SpringUrlRedirect.java:409:23:409:50 | getParameter(...) : String | SpringUrlRedirect.java:410:46:410:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:409:23:409:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:421:46:421:49 | next | SpringUrlRedirect.java:420:23:420:50 | getParameter(...) : String | SpringUrlRedirect.java:421:46:421:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:420:23:420:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:423:21:423:24 | next | SpringUrlRedirect.java:420:23:420:50 | getParameter(...) : String | SpringUrlRedirect.java:423:21:423:24 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:420:23:420:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:444:60:444:63 | next | SpringUrlRedirect.java:443:23:443:50 | getParameter(...) : String | SpringUrlRedirect.java:444:60:444:63 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:443:23:443:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:476:46:476:49 | next | SpringUrlRedirect.java:475:23:475:50 | getParameter(...) : String | SpringUrlRedirect.java:476:46:476:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:475:23:475:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:497:16:497:51 | branchingRedirect(...) | SpringUrlRedirect.java:496:23:496:50 | getParameter(...) : String | SpringUrlRedirect.java:497:16:497:51 | branchingRedirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:496:23:496:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:503:33:503:68 | branchingRedirect(...) | SpringUrlRedirect.java:502:23:502:50 | getParameter(...) : String | SpringUrlRedirect.java:503:33:503:68 | branchingRedirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:502:23:502:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:543:33:543:66 | internallySourcedRedirect(...) | SpringUrlRedirect.java:517:23:517:50 | getHeader(...) : String | SpringUrlRedirect.java:543:33:543:66 | internallySourcedRedirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:517:23:517:50 | getHeader(...) | user-provided value | +| SpringUrlRedirect.java:549:33:549:61 | secondRedirect(...) | SpringUrlRedirect.java:548:23:548:50 | getParameter(...) : String | SpringUrlRedirect.java:549:33:549:61 | secondRedirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:548:23:548:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:561:48:561:51 | next | SpringUrlRedirect.java:560:23:560:50 | getParameter(...) : String | SpringUrlRedirect.java:561:48:561:51 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:560:23:560:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:577:46:577:49 | next | SpringUrlRedirect.java:576:23:576:50 | getParameter(...) : String | SpringUrlRedirect.java:577:46:577:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:576:23:576:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:597:33:597:76 | branchingFallbackRedirect(...) | SpringUrlRedirect.java:596:23:596:50 | getParameter(...) : String | SpringUrlRedirect.java:597:33:597:76 | branchingFallbackRedirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:596:23:596:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:613:33:613:36 | next | SpringUrlRedirect.java:612:23:612:50 | getParameter(...) : String | SpringUrlRedirect.java:613:33:613:36 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:612:23:612:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:620:47:620:50 | next | SpringUrlRedirect.java:619:23:619:50 | getParameter(...) : String | SpringUrlRedirect.java:620:47:620:50 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:619:23:619:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:629:88:629:104 | redirect(...) | SpringUrlRedirect.java:628:26:628:53 | getHeader(...) : String | SpringUrlRedirect.java:629:88:629:104 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:628:26:628:53 | getHeader(...) | user-provided value | +| SpringUrlRedirect.java:635:44:635:47 | next | SpringUrlRedirect.java:634:23:634:50 | getParameter(...) : String | SpringUrlRedirect.java:635:44:635:47 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:634:23:634:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:643:34:643:37 | next | SpringUrlRedirect.java:640:23:640:50 | getParameter(...) : String | SpringUrlRedirect.java:643:34:643:37 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:640:23:640:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:655:20:655:33 | redirect(...) | SpringUrlRedirect.java:652:23:652:50 | getParameter(...) : String | SpringUrlRedirect.java:655:20:655:33 | redirect(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:652:23:652:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:666:25:666:28 | next | SpringUrlRedirect.java:664:23:664:50 | getParameter(...) : String | SpringUrlRedirect.java:666:25:666:28 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:664:23:664:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:677:33:677:55 | localPrefixHelper(...) | SpringUrlRedirect.java:676:23:676:50 | getParameter(...) : String | SpringUrlRedirect.java:677:33:677:55 | localPrefixHelper(...) | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:676:23:676:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:684:25:684:28 | next | SpringUrlRedirect.java:682:23:682:50 | getParameter(...) : String | SpringUrlRedirect.java:684:25:684:28 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:682:23:682:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:727:38:727:41 | next | SpringUrlRedirect.java:725:23:725:50 | getParameter(...) : String | SpringUrlRedirect.java:727:38:727:41 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:725:23:725:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:734:39:734:42 | host | SpringUrlRedirect.java:732:23:732:50 | getParameter(...) : String | SpringUrlRedirect.java:734:39:734:42 | host | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:732:23:732:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:743:50:743:53 | next | SpringUrlRedirect.java:742:23:742:50 | getParameter(...) : String | SpringUrlRedirect.java:743:50:743:53 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:742:23:742:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:750:21:750:24 | next | SpringUrlRedirect.java:748:23:748:50 | getParameter(...) : String | SpringUrlRedirect.java:750:21:750:24 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:748:23:748:50 | getParameter(...) | user-provided value | +| SpringUrlRedirect.java:757:46:757:49 | next | SpringUrlRedirect.java:756:23:756:50 | getParameter(...) : String | SpringUrlRedirect.java:757:46:757:49 | next | Untrusted URL redirection depends on a $@. | SpringUrlRedirect.java:756:23:756:50 | getParameter(...) | user-provided value | | UrlRedirect2.java:27:25:27:54 | getParameter(...) | UrlRedirect2.java:27:25:27:54 | getParameter(...) | UrlRedirect2.java:27:25:27:54 | getParameter(...) | Untrusted URL redirection depends on a $@. | UrlRedirect2.java:27:25:27:54 | getParameter(...) | user-provided value | | UrlRedirect.java:23:25:23:54 | getParameter(...) | UrlRedirect.java:23:25:23:54 | getParameter(...) | UrlRedirect.java:23:25:23:54 | getParameter(...) | Untrusted URL redirection depends on a $@. | UrlRedirect.java:23:25:23:54 | getParameter(...) | user-provided value | | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | Untrusted URL redirection depends on a $@. | UrlRedirect.java:32:37:32:66 | getParameter(...) | user-provided value | @@ -28,69 +79,153 @@ | mad/Test.java:14:22:14:38 | (...)... | mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:22:14:38 | (...)... | Untrusted URL redirection depends on a $@. | mad/Test.java:9:16:9:41 | getParameter(...) | user-provided value | edges | HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | HostComparisonRedirect.java:9:31:9:33 | uri : URI | provenance | | -| HostComparisonRedirect.java:8:27:8:53 | getParameter(...) : String | HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:9:31:9:33 | uri : URI | HostComparisonRedirect.java:9:31:9:44 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:8:27:8:53 | getParameter(...) : String | HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:9:31:9:33 | uri : URI | HostComparisonRedirect.java:9:31:9:44 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:50:19:50:54 | new URI(...) : URI | HostComparisonRedirect.java:52:35:52:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:50:27:50:53 | getParameter(...) : String | HostComparisonRedirect.java:50:19:50:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:52:35:52:37 | uri : URI | HostComparisonRedirect.java:52:35:52:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:50:27:50:53 | getParameter(...) : String | HostComparisonRedirect.java:50:19:50:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:52:35:52:37 | uri : URI | HostComparisonRedirect.java:52:35:52:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:57:19:57:54 | new URI(...) : URI | HostComparisonRedirect.java:59:35:59:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:57:27:57:53 | getParameter(...) : String | HostComparisonRedirect.java:57:19:57:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:59:35:59:37 | uri : URI | HostComparisonRedirect.java:59:35:59:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:57:27:57:53 | getParameter(...) : String | HostComparisonRedirect.java:57:19:57:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:59:35:59:37 | uri : URI | HostComparisonRedirect.java:59:35:59:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:68:19:68:54 | new URI(...) : URI | HostComparisonRedirect.java:70:35:70:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:68:27:68:53 | getParameter(...) : String | HostComparisonRedirect.java:68:19:68:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:70:35:70:37 | uri : URI | HostComparisonRedirect.java:70:35:70:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:68:27:68:53 | getParameter(...) : String | HostComparisonRedirect.java:68:19:68:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:70:35:70:37 | uri : URI | HostComparisonRedirect.java:70:35:70:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:84:19:84:54 | new URI(...) : URI | HostComparisonRedirect.java:86:35:86:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:84:27:84:53 | getParameter(...) : String | HostComparisonRedirect.java:84:19:84:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:86:35:86:37 | uri : URI | HostComparisonRedirect.java:86:35:86:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:84:27:84:53 | getParameter(...) : String | HostComparisonRedirect.java:84:19:84:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:86:35:86:37 | uri : URI | HostComparisonRedirect.java:86:35:86:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:92:20:92:55 | new URI(...) : URI | HostComparisonRedirect.java:94:35:94:38 | used : URI | provenance | | -| HostComparisonRedirect.java:92:28:92:54 | getParameter(...) : String | HostComparisonRedirect.java:92:20:92:55 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:94:35:94:38 | used : URI | HostComparisonRedirect.java:94:35:94:49 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:92:28:92:54 | getParameter(...) : String | HostComparisonRedirect.java:92:20:92:55 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:94:35:94:38 | used : URI | HostComparisonRedirect.java:94:35:94:49 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:103:19:103:54 | new URI(...) : URI | HostComparisonRedirect.java:105:35:105:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:103:27:103:53 | getParameter(...) : String | HostComparisonRedirect.java:103:19:103:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:105:35:105:37 | uri : URI | HostComparisonRedirect.java:105:35:105:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:103:27:103:53 | getParameter(...) : String | HostComparisonRedirect.java:103:19:103:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:105:35:105:37 | uri : URI | HostComparisonRedirect.java:105:35:105:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:111:20:111:55 | new URI(...) : URI | HostComparisonRedirect.java:113:35:113:38 | used : URI | provenance | | -| HostComparisonRedirect.java:111:28:111:54 | getParameter(...) : String | HostComparisonRedirect.java:111:20:111:55 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:113:35:113:38 | used : URI | HostComparisonRedirect.java:113:35:113:49 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:111:28:111:54 | getParameter(...) : String | HostComparisonRedirect.java:111:20:111:55 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:113:35:113:38 | used : URI | HostComparisonRedirect.java:113:35:113:49 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:118:19:118:54 | new URI(...) : URI | HostComparisonRedirect.java:122:35:122:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:118:27:118:53 | getParameter(...) : String | HostComparisonRedirect.java:118:19:118:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:122:35:122:37 | uri : URI | HostComparisonRedirect.java:122:35:122:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:118:27:118:53 | getParameter(...) : String | HostComparisonRedirect.java:118:19:118:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:122:35:122:37 | uri : URI | HostComparisonRedirect.java:122:35:122:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:127:19:127:54 | new URI(...) : URI | HostComparisonRedirect.java:133:35:133:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:127:27:127:53 | getParameter(...) : String | HostComparisonRedirect.java:127:19:127:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:133:35:133:37 | uri : URI | HostComparisonRedirect.java:133:35:133:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:127:27:127:53 | getParameter(...) : String | HostComparisonRedirect.java:127:19:127:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:133:35:133:37 | uri : URI | HostComparisonRedirect.java:133:35:133:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:140:15:140:50 | new URI(...) : URI | HostComparisonRedirect.java:142:35:142:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:140:23:140:49 | getParameter(...) : String | HostComparisonRedirect.java:140:15:140:50 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:142:35:142:37 | uri : URI | HostComparisonRedirect.java:142:35:142:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:140:23:140:49 | getParameter(...) : String | HostComparisonRedirect.java:140:15:140:50 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:142:35:142:37 | uri : URI | HostComparisonRedirect.java:142:35:142:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:147:19:147:54 | new URI(...) : URI | HostComparisonRedirect.java:149:35:149:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:147:27:147:53 | getParameter(...) : String | HostComparisonRedirect.java:147:19:147:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:149:35:149:37 | uri : URI | HostComparisonRedirect.java:149:35:149:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:147:27:147:53 | getParameter(...) : String | HostComparisonRedirect.java:147:19:147:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:149:35:149:37 | uri : URI | HostComparisonRedirect.java:149:35:149:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:154:19:154:54 | new URI(...) : URI | HostComparisonRedirect.java:156:35:156:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:154:27:154:53 | getParameter(...) : String | HostComparisonRedirect.java:154:19:154:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:156:35:156:37 | uri : URI | HostComparisonRedirect.java:156:35:156:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:154:27:154:53 | getParameter(...) : String | HostComparisonRedirect.java:154:19:154:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:156:35:156:37 | uri : URI | HostComparisonRedirect.java:156:35:156:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:177:19:177:54 | new URI(...) : URI | HostComparisonRedirect.java:184:39:184:41 | uri : URI | provenance | | -| HostComparisonRedirect.java:177:27:177:53 | getParameter(...) : String | HostComparisonRedirect.java:177:19:177:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:184:39:184:41 | uri : URI | HostComparisonRedirect.java:184:39:184:52 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:177:27:177:53 | getParameter(...) : String | HostComparisonRedirect.java:177:19:177:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:184:39:184:41 | uri : URI | HostComparisonRedirect.java:184:39:184:52 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:207:19:207:54 | new URI(...) : URI | HostComparisonRedirect.java:210:35:210:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:207:27:207:53 | getParameter(...) : String | HostComparisonRedirect.java:207:19:207:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:210:35:210:37 | uri : URI | HostComparisonRedirect.java:210:35:210:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:207:27:207:53 | getParameter(...) : String | HostComparisonRedirect.java:207:19:207:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:210:35:210:37 | uri : URI | HostComparisonRedirect.java:210:35:210:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:232:19:232:54 | new URI(...) : URI | HostComparisonRedirect.java:236:35:236:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:232:27:232:53 | getParameter(...) : String | HostComparisonRedirect.java:232:19:232:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:236:35:236:37 | uri : URI | HostComparisonRedirect.java:236:35:236:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:232:27:232:53 | getParameter(...) : String | HostComparisonRedirect.java:232:19:232:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:236:35:236:37 | uri : URI | HostComparisonRedirect.java:236:35:236:48 | toString(...) | provenance | MaD:12 | | HostComparisonRedirect.java:241:19:241:54 | new URI(...) : URI | HostComparisonRedirect.java:245:35:245:37 | uri : URI | provenance | | -| HostComparisonRedirect.java:241:27:241:53 | getParameter(...) : String | HostComparisonRedirect.java:241:19:241:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | -| HostComparisonRedirect.java:245:35:245:37 | uri : URI | HostComparisonRedirect.java:245:35:245:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:241:27:241:53 | getParameter(...) : String | HostComparisonRedirect.java:241:19:241:54 | new URI(...) : URI | provenance | Src:MaD:8 MaD:10 | +| HostComparisonRedirect.java:245:35:245:37 | uri : URI | HostComparisonRedirect.java:245:35:245:48 | toString(...) | provenance | MaD:12 | | MicronautUrlRedirect.java:12:39:12:63 | target : String | MicronautUrlRedirect.java:14:49:14:54 | target : String | provenance | | -| MicronautUrlRedirect.java:14:49:14:54 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | provenance | MaD:9 Sink:MaD:2 | +| MicronautUrlRedirect.java:14:49:14:54 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | provenance | MaD:11 Sink:MaD:2 | | MicronautUrlRedirect.java:27:45:27:69 | target : String | MicronautUrlRedirect.java:28:58:28:63 | target : String | provenance | | -| MicronautUrlRedirect.java:28:58:28:63 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | provenance | MaD:9 Sink:MaD:1 | +| MicronautUrlRedirect.java:28:58:28:63 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | provenance | MaD:11 Sink:MaD:1 | | MicronautUrlRedirect.java:32:44:32:68 | target : String | MicronautUrlRedirect.java:33:49:33:54 | target : String | provenance | | -| MicronautUrlRedirect.java:33:49:33:54 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | provenance | MaD:9 Sink:MaD:3 | +| MicronautUrlRedirect.java:33:49:33:54 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | provenance | MaD:11 Sink:MaD:3 | | MicronautUrlRedirect.java:37:45:37:69 | target : String | MicronautUrlRedirect.java:38:58:38:63 | target : String | provenance | | -| MicronautUrlRedirect.java:38:58:38:63 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | provenance | MaD:9 Sink:MaD:4 | -| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | provenance | Src:MaD:6 MaD:7 | -| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:45:28:45:39 | input : String | provenance | Src:MaD:6 | +| MicronautUrlRedirect.java:38:58:38:63 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | provenance | MaD:11 Sink:MaD:4 | +| SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | provenance | | +| SpringUrlRedirect.java:38:23:38:50 | getHeader(...) : String | SpringUrlRedirect.java:39:30:39:33 | next | provenance | Src:MaD:7 | +| SpringUrlRedirect.java:44:23:44:50 | getHeader(...) : String | SpringUrlRedirect.java:45:47:45:50 | next | provenance | Src:MaD:7 | +| SpringUrlRedirect.java:50:23:50:50 | getHeader(...) : String | SpringUrlRedirect.java:51:33:51:36 | next | provenance | Src:MaD:7 | +| SpringUrlRedirect.java:56:23:56:50 | getHeader(...) : String | SpringUrlRedirect.java:57:25:57:28 | next : String | provenance | Src:MaD:7 | +| SpringUrlRedirect.java:57:25:57:28 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:57:25:57:28 | next : String | SpringUrlRedirect.java:57:16:57:29 | redirect(...) | provenance | | +| SpringUrlRedirect.java:62:23:62:50 | getParameter(...) : String | SpringUrlRedirect.java:64:21:64:24 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:70:23:70:50 | getParameter(...) : String | SpringUrlRedirect.java:71:33:71:36 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:184:23:184:50 | getParameter(...) : String | SpringUrlRedirect.java:185:42:185:45 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:185:42:185:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:185:42:185:45 | next : String | SpringUrlRedirect.java:185:33:185:46 | redirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:190:23:190:50 | getParameter(...) : String | SpringUrlRedirect.java:191:42:191:45 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:191:42:191:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:191:42:191:45 | next : String | SpringUrlRedirect.java:191:33:191:46 | redirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:196:23:196:50 | getParameter(...) : String | SpringUrlRedirect.java:197:30:197:33 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:202:23:202:50 | getParameter(...) : String | SpringUrlRedirect.java:203:41:203:44 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:283:23:283:50 | getParameter(...) : String | SpringUrlRedirect.java:284:46:284:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:291:23:291:50 | getParameter(...) : String | SpringUrlRedirect.java:293:21:293:24 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:300:23:300:50 | getParameter(...) : String | SpringUrlRedirect.java:301:60:301:63 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:313:23:313:50 | getParameter(...) : String | SpringUrlRedirect.java:314:33:314:36 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:320:23:320:50 | getParameter(...) : String | SpringUrlRedirect.java:321:47:321:50 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:327:23:327:50 | getParameter(...) : String | SpringUrlRedirect.java:328:42:328:45 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:328:42:328:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:328:42:328:45 | next : String | SpringUrlRedirect.java:328:33:328:46 | redirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:337:23:337:50 | getParameter(...) : String | SpringUrlRedirect.java:338:33:338:36 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:343:23:343:50 | getParameter(...) : String | SpringUrlRedirect.java:344:47:344:50 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:349:23:349:50 | getParameter(...) : String | SpringUrlRedirect.java:350:42:350:45 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:350:42:350:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:350:42:350:45 | next : String | SpringUrlRedirect.java:350:33:350:46 | redirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:355:23:355:50 | getParameter(...) : String | SpringUrlRedirect.java:357:21:357:24 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:363:23:363:50 | getParameter(...) : String | SpringUrlRedirect.java:364:33:364:36 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:372:23:372:50 | getParameter(...) : String | SpringUrlRedirect.java:373:46:373:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:382:23:382:50 | getParameter(...) : String | SpringUrlRedirect.java:383:46:383:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:391:23:391:50 | getParameter(...) : String | SpringUrlRedirect.java:392:46:392:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:400:23:400:50 | getParameter(...) : String | SpringUrlRedirect.java:401:46:401:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:409:23:409:50 | getParameter(...) : String | SpringUrlRedirect.java:410:46:410:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:420:23:420:50 | getParameter(...) : String | SpringUrlRedirect.java:421:46:421:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:420:23:420:50 | getParameter(...) : String | SpringUrlRedirect.java:423:21:423:24 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:443:23:443:50 | getParameter(...) : String | SpringUrlRedirect.java:444:60:444:63 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:457:40:457:50 | path : String | SpringUrlRedirect.java:461:16:461:33 | ... + ... : String | provenance | | +| SpringUrlRedirect.java:475:23:475:50 | getParameter(...) : String | SpringUrlRedirect.java:476:46:476:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:496:23:496:50 | getParameter(...) : String | SpringUrlRedirect.java:497:34:497:37 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:497:34:497:37 | next : String | SpringUrlRedirect.java:457:40:457:50 | path : String | provenance | | +| SpringUrlRedirect.java:497:34:497:37 | next : String | SpringUrlRedirect.java:497:16:497:51 | branchingRedirect(...) | provenance | | +| SpringUrlRedirect.java:502:23:502:50 | getParameter(...) : String | SpringUrlRedirect.java:503:51:503:54 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:503:51:503:54 | next : String | SpringUrlRedirect.java:457:40:457:50 | path : String | provenance | | +| SpringUrlRedirect.java:503:51:503:54 | next : String | SpringUrlRedirect.java:503:33:503:68 | branchingRedirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:517:23:517:50 | getHeader(...) : String | SpringUrlRedirect.java:518:16:518:33 | ... + ... : String | provenance | Src:MaD:7 | +| SpringUrlRedirect.java:518:16:518:33 | ... + ... : String | SpringUrlRedirect.java:543:33:543:66 | internallySourcedRedirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:521:37:521:51 | paths : String[] [[]] : String | SpringUrlRedirect.java:522:30:522:34 | paths : String[] [[]] : String | provenance | | +| SpringUrlRedirect.java:522:30:522:34 | paths : String[] [[]] : String | SpringUrlRedirect.java:522:30:522:37 | ...[...] : String | provenance | | +| SpringUrlRedirect.java:522:30:522:37 | ...[...] : String | SpringUrlRedirect.java:522:16:522:37 | ... + ... : String | provenance | | +| SpringUrlRedirect.java:548:23:548:50 | getParameter(...) : String | SpringUrlRedirect.java:549:57:549:60 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:549:33:549:61 | new ..[] { .. } : String[] [[]] : String | SpringUrlRedirect.java:521:37:521:51 | paths : String[] [[]] : String | provenance | | +| SpringUrlRedirect.java:549:33:549:61 | new ..[] { .. } : String[] [[]] : String | SpringUrlRedirect.java:549:33:549:61 | secondRedirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:549:57:549:60 | next : String | SpringUrlRedirect.java:549:33:549:61 | new ..[] { .. } : String[] [[]] : String | provenance | | +| SpringUrlRedirect.java:560:23:560:50 | getParameter(...) : String | SpringUrlRedirect.java:561:48:561:51 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:576:23:576:50 | getParameter(...) : String | SpringUrlRedirect.java:577:46:577:49 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:587:48:587:58 | path : String | SpringUrlRedirect.java:589:20:589:37 | ... + ... : String | provenance | | +| SpringUrlRedirect.java:596:23:596:50 | getParameter(...) : String | SpringUrlRedirect.java:597:59:597:62 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:597:59:597:62 | next : String | SpringUrlRedirect.java:587:48:587:58 | path : String | provenance | | +| SpringUrlRedirect.java:597:59:597:62 | next : String | SpringUrlRedirect.java:597:33:597:76 | branchingFallbackRedirect(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:612:23:612:50 | getParameter(...) : String | SpringUrlRedirect.java:613:33:613:36 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:619:23:619:50 | getParameter(...) : String | SpringUrlRedirect.java:620:47:620:50 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:628:26:628:53 | getHeader(...) : String | SpringUrlRedirect.java:629:97:629:103 | referer : String | provenance | Src:MaD:7 | +| SpringUrlRedirect.java:629:97:629:103 | referer : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:629:97:629:103 | referer : String | SpringUrlRedirect.java:629:88:629:104 | redirect(...) | provenance | | +| SpringUrlRedirect.java:634:23:634:50 | getParameter(...) : String | SpringUrlRedirect.java:635:44:635:47 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:640:23:640:50 | getParameter(...) : String | SpringUrlRedirect.java:643:34:643:37 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:652:23:652:50 | getParameter(...) : String | SpringUrlRedirect.java:655:29:655:32 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:655:29:655:32 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | provenance | | +| SpringUrlRedirect.java:655:29:655:32 | next : String | SpringUrlRedirect.java:655:20:655:33 | redirect(...) | provenance | | +| SpringUrlRedirect.java:664:23:664:50 | getParameter(...) : String | SpringUrlRedirect.java:666:25:666:28 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:669:40:669:50 | next : String | SpringUrlRedirect.java:671:16:671:28 | ... + ... : String | provenance | | +| SpringUrlRedirect.java:676:23:676:50 | getParameter(...) : String | SpringUrlRedirect.java:677:51:677:54 | next : String | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:677:51:677:54 | next : String | SpringUrlRedirect.java:669:40:669:50 | next : String | provenance | | +| SpringUrlRedirect.java:677:51:677:54 | next : String | SpringUrlRedirect.java:677:33:677:55 | localPrefixHelper(...) | provenance | Sink:MaD:6 | +| SpringUrlRedirect.java:682:23:682:50 | getParameter(...) : String | SpringUrlRedirect.java:684:25:684:28 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:725:23:725:50 | getParameter(...) : String | SpringUrlRedirect.java:727:38:727:41 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:732:23:732:50 | getParameter(...) : String | SpringUrlRedirect.java:734:39:734:42 | host | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:742:23:742:50 | getParameter(...) : String | SpringUrlRedirect.java:743:50:743:53 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:748:23:748:50 | getParameter(...) : String | SpringUrlRedirect.java:750:21:750:24 | next | provenance | Src:MaD:8 | +| SpringUrlRedirect.java:756:23:756:50 | getParameter(...) : String | SpringUrlRedirect.java:757:46:757:49 | next | provenance | Src:MaD:8 | +| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | provenance | Src:MaD:8 MaD:9 | +| UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:45:28:45:39 | input : String | provenance | Src:MaD:8 | | UrlRedirect.java:45:28:45:39 | input : String | UrlRedirect.java:46:10:46:14 | input : String | provenance | | -| UrlRedirect.java:46:10:46:14 | input : String | UrlRedirect.java:46:10:46:40 | replaceAll(...) : String | provenance | MaD:7 | -| mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:31:14:38 | source(...) : String | provenance | Src:MaD:6 | +| UrlRedirect.java:46:10:46:14 | input : String | UrlRedirect.java:46:10:46:40 | replaceAll(...) : String | provenance | MaD:9 | +| mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:31:14:38 | source(...) : String | provenance | Src:MaD:8 | | mad/Test.java:14:31:14:38 | source(...) : String | mad/Test.java:14:22:14:38 | (...)... | provenance | Sink:MaD:5 | models | 1 | Sink: io.micronaut.http; HttpResponse; true; permanentRedirect; (URI); ; Argument[0]; url-redirection; manual | @@ -98,11 +233,13 @@ models | 3 | Sink: io.micronaut.http; HttpResponse; true; seeOther; (URI); ; Argument[0]; url-redirection; manual | | 4 | Sink: io.micronaut.http; HttpResponse; true; temporaryRedirect; (URI); ; Argument[0]; url-redirection; manual | | 5 | Sink: org.kohsuke.stapler; HttpResponses; true; redirectTo; (String); ; Argument[0]; url-redirection; ai-manual | -| 6 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual | -| 7 | Summary: java.lang; String; false; replaceAll; ; ; Argument[this]; ReturnValue; taint; manual | -| 8 | Summary: java.net; URI; false; URI; (String); ; Argument[0]; Argument[this]; taint; manual | -| 9 | Summary: java.net; URI; false; create; ; ; Argument[0]; ReturnValue; taint; manual | -| 10 | Summary: java.net; URI; false; toString; ; ; Argument[this]; ReturnValue; taint; manual | +| 6 | Sink: org.springframework.web.servlet; ModelAndView; false; ModelAndView; ; ; Argument[0]; url-forward; manual | +| 7 | Source: javax.servlet.http; HttpServletRequest; false; getHeader; (String); ; ReturnValue; remote; manual | +| 8 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual | +| 9 | Summary: java.lang; String; false; replaceAll; ; ; Argument[this]; ReturnValue; taint; manual | +| 10 | Summary: java.net; URI; false; URI; (String); ; Argument[0]; Argument[this]; taint; manual | +| 11 | Summary: java.net; URI; false; create; ; ; Argument[0]; ReturnValue; taint; manual | +| 12 | Summary: java.net; URI; false; toString; ; ; Argument[this]; ReturnValue; taint; manual | nodes | HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | | HostComparisonRedirect.java:8:27:8:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | @@ -184,6 +321,133 @@ nodes | MicronautUrlRedirect.java:37:45:37:69 | target : String | semmle.label | target : String | | MicronautUrlRedirect.java:38:47:38:64 | create(...) | semmle.label | create(...) | | MicronautUrlRedirect.java:38:58:38:63 | target : String | semmle.label | target : String | +| SpringUrlRedirect.java:12:31:12:41 | path : String | semmle.label | path : String | +| SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | semmle.label | ... + ... : String | +| SpringUrlRedirect.java:38:23:38:50 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| SpringUrlRedirect.java:39:30:39:33 | next | semmle.label | next | +| SpringUrlRedirect.java:44:23:44:50 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| SpringUrlRedirect.java:45:47:45:50 | next | semmle.label | next | +| SpringUrlRedirect.java:50:23:50:50 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| SpringUrlRedirect.java:51:33:51:36 | next | semmle.label | next | +| SpringUrlRedirect.java:56:23:56:50 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| SpringUrlRedirect.java:57:16:57:29 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:57:25:57:28 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:62:23:62:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:64:21:64:24 | next | semmle.label | next | +| SpringUrlRedirect.java:70:23:70:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:71:33:71:36 | next | semmle.label | next | +| SpringUrlRedirect.java:184:23:184:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:185:33:185:46 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:185:42:185:45 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:190:23:190:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:191:33:191:46 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:191:42:191:45 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:196:23:196:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:197:30:197:33 | next | semmle.label | next | +| SpringUrlRedirect.java:202:23:202:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:203:41:203:44 | next | semmle.label | next | +| SpringUrlRedirect.java:283:23:283:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:284:46:284:49 | next | semmle.label | next | +| SpringUrlRedirect.java:291:23:291:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:293:21:293:24 | next | semmle.label | next | +| SpringUrlRedirect.java:300:23:300:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:301:60:301:63 | next | semmle.label | next | +| SpringUrlRedirect.java:313:23:313:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:314:33:314:36 | next | semmle.label | next | +| SpringUrlRedirect.java:320:23:320:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:321:47:321:50 | next | semmle.label | next | +| SpringUrlRedirect.java:327:23:327:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:328:33:328:46 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:328:42:328:45 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:337:23:337:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:338:33:338:36 | next | semmle.label | next | +| SpringUrlRedirect.java:343:23:343:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:344:47:344:50 | next | semmle.label | next | +| SpringUrlRedirect.java:349:23:349:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:350:33:350:46 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:350:42:350:45 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:355:23:355:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:357:21:357:24 | next | semmle.label | next | +| SpringUrlRedirect.java:363:23:363:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:364:33:364:36 | next | semmle.label | next | +| SpringUrlRedirect.java:372:23:372:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:373:46:373:49 | next | semmle.label | next | +| SpringUrlRedirect.java:382:23:382:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:383:46:383:49 | next | semmle.label | next | +| SpringUrlRedirect.java:391:23:391:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:392:46:392:49 | next | semmle.label | next | +| SpringUrlRedirect.java:400:23:400:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:401:46:401:49 | next | semmle.label | next | +| SpringUrlRedirect.java:409:23:409:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:410:46:410:49 | next | semmle.label | next | +| SpringUrlRedirect.java:420:23:420:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:421:46:421:49 | next | semmle.label | next | +| SpringUrlRedirect.java:423:21:423:24 | next | semmle.label | next | +| SpringUrlRedirect.java:443:23:443:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:444:60:444:63 | next | semmle.label | next | +| SpringUrlRedirect.java:457:40:457:50 | path : String | semmle.label | path : String | +| SpringUrlRedirect.java:461:16:461:33 | ... + ... : String | semmle.label | ... + ... : String | +| SpringUrlRedirect.java:475:23:475:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:476:46:476:49 | next | semmle.label | next | +| SpringUrlRedirect.java:496:23:496:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:497:16:497:51 | branchingRedirect(...) | semmle.label | branchingRedirect(...) | +| SpringUrlRedirect.java:497:34:497:37 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:502:23:502:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:503:33:503:68 | branchingRedirect(...) | semmle.label | branchingRedirect(...) | +| SpringUrlRedirect.java:503:51:503:54 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:517:23:517:50 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| SpringUrlRedirect.java:518:16:518:33 | ... + ... : String | semmle.label | ... + ... : String | +| SpringUrlRedirect.java:521:37:521:51 | paths : String[] [[]] : String | semmle.label | paths : String[] [[]] : String | +| SpringUrlRedirect.java:522:16:522:37 | ... + ... : String | semmle.label | ... + ... : String | +| SpringUrlRedirect.java:522:30:522:34 | paths : String[] [[]] : String | semmle.label | paths : String[] [[]] : String | +| SpringUrlRedirect.java:522:30:522:37 | ...[...] : String | semmle.label | ...[...] : String | +| SpringUrlRedirect.java:543:33:543:66 | internallySourcedRedirect(...) | semmle.label | internallySourcedRedirect(...) | +| SpringUrlRedirect.java:548:23:548:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:549:33:549:61 | new ..[] { .. } : String[] [[]] : String | semmle.label | new ..[] { .. } : String[] [[]] : String | +| SpringUrlRedirect.java:549:33:549:61 | secondRedirect(...) | semmle.label | secondRedirect(...) | +| SpringUrlRedirect.java:549:57:549:60 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:560:23:560:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:561:48:561:51 | next | semmle.label | next | +| SpringUrlRedirect.java:576:23:576:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:577:46:577:49 | next | semmle.label | next | +| SpringUrlRedirect.java:587:48:587:58 | path : String | semmle.label | path : String | +| SpringUrlRedirect.java:589:20:589:37 | ... + ... : String | semmle.label | ... + ... : String | +| SpringUrlRedirect.java:596:23:596:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:597:33:597:76 | branchingFallbackRedirect(...) | semmle.label | branchingFallbackRedirect(...) | +| SpringUrlRedirect.java:597:59:597:62 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:612:23:612:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:613:33:613:36 | next | semmle.label | next | +| SpringUrlRedirect.java:619:23:619:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:620:47:620:50 | next | semmle.label | next | +| SpringUrlRedirect.java:628:26:628:53 | getHeader(...) : String | semmle.label | getHeader(...) : String | +| SpringUrlRedirect.java:629:88:629:104 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:629:97:629:103 | referer : String | semmle.label | referer : String | +| SpringUrlRedirect.java:634:23:634:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:635:44:635:47 | next | semmle.label | next | +| SpringUrlRedirect.java:640:23:640:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:643:34:643:37 | next | semmle.label | next | +| SpringUrlRedirect.java:652:23:652:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:655:20:655:33 | redirect(...) | semmle.label | redirect(...) | +| SpringUrlRedirect.java:655:29:655:32 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:664:23:664:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:666:25:666:28 | next | semmle.label | next | +| SpringUrlRedirect.java:669:40:669:50 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:671:16:671:28 | ... + ... : String | semmle.label | ... + ... : String | +| SpringUrlRedirect.java:676:23:676:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:677:33:677:55 | localPrefixHelper(...) | semmle.label | localPrefixHelper(...) | +| SpringUrlRedirect.java:677:51:677:54 | next : String | semmle.label | next : String | +| SpringUrlRedirect.java:682:23:682:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:684:25:684:28 | next | semmle.label | next | +| SpringUrlRedirect.java:725:23:725:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:727:38:727:41 | next | semmle.label | next | +| SpringUrlRedirect.java:732:23:732:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:734:39:734:42 | host | semmle.label | host | +| SpringUrlRedirect.java:742:23:742:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:743:50:743:53 | next | semmle.label | next | +| SpringUrlRedirect.java:748:23:748:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:750:21:750:24 | next | semmle.label | next | +| SpringUrlRedirect.java:756:23:756:50 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SpringUrlRedirect.java:757:46:757:49 | next | semmle.label | next | | UrlRedirect2.java:27:25:27:54 | getParameter(...) | semmle.label | getParameter(...) | | UrlRedirect.java:23:25:23:54 | getParameter(...) | semmle.label | getParameter(...) | | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | semmle.label | weakCleanup(...) | @@ -197,4 +461,16 @@ nodes | mad/Test.java:14:22:14:38 | (...)... | semmle.label | (...)... | | mad/Test.java:14:31:14:38 | source(...) : String | semmle.label | source(...) : String | subpaths +| SpringUrlRedirect.java:57:25:57:28 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:57:16:57:29 | redirect(...) | +| SpringUrlRedirect.java:185:42:185:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:185:33:185:46 | redirect(...) | +| SpringUrlRedirect.java:191:42:191:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:191:33:191:46 | redirect(...) | +| SpringUrlRedirect.java:328:42:328:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:328:33:328:46 | redirect(...) | +| SpringUrlRedirect.java:350:42:350:45 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:350:33:350:46 | redirect(...) | +| SpringUrlRedirect.java:497:34:497:37 | next : String | SpringUrlRedirect.java:457:40:457:50 | path : String | SpringUrlRedirect.java:461:16:461:33 | ... + ... : String | SpringUrlRedirect.java:497:16:497:51 | branchingRedirect(...) | +| SpringUrlRedirect.java:503:51:503:54 | next : String | SpringUrlRedirect.java:457:40:457:50 | path : String | SpringUrlRedirect.java:461:16:461:33 | ... + ... : String | SpringUrlRedirect.java:503:33:503:68 | branchingRedirect(...) | +| SpringUrlRedirect.java:549:33:549:61 | new ..[] { .. } : String[] [[]] : String | SpringUrlRedirect.java:521:37:521:51 | paths : String[] [[]] : String | SpringUrlRedirect.java:522:16:522:37 | ... + ... : String | SpringUrlRedirect.java:549:33:549:61 | secondRedirect(...) | +| SpringUrlRedirect.java:597:59:597:62 | next : String | SpringUrlRedirect.java:587:48:587:58 | path : String | SpringUrlRedirect.java:589:20:589:37 | ... + ... : String | SpringUrlRedirect.java:597:33:597:76 | branchingFallbackRedirect(...) | +| SpringUrlRedirect.java:629:97:629:103 | referer : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:629:88:629:104 | redirect(...) | +| SpringUrlRedirect.java:655:29:655:32 | next : String | SpringUrlRedirect.java:12:31:12:41 | path : String | SpringUrlRedirect.java:13:16:13:33 | ... + ... : String | SpringUrlRedirect.java:655:20:655:33 | redirect(...) | +| SpringUrlRedirect.java:677:51:677:54 | next : String | SpringUrlRedirect.java:669:40:669:50 | next : String | SpringUrlRedirect.java:671:16:671:28 | ... + ... : String | SpringUrlRedirect.java:677:33:677:55 | localPrefixHelper(...) | | UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:45:28:45:39 | input : String | UrlRedirect.java:46:10:46:40 | replaceAll(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | diff --git a/java/ql/test/query-tests/security/CWE-601/semmle/tests/options b/java/ql/test/query-tests/security/CWE-601/semmle/tests/options index e0a964b29dc4..260ed68b4373 100644 --- a/java/ql/test/query-tests/security/CWE-601/semmle/tests/options +++ b/java/ql/test/query-tests/security/CWE-601/semmle/tests/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/micronaut-4.x:${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/stapler-1.263:${testdir}/../../../../../stubs/javax-servlet-2.5:${testdir}/../../../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../../../stubs/saxon-xqj-9.x:${testdir}/../../../../../stubs/apache-commons-beanutils:${testdir}/../../../../../stubs/dom4j-2.1.1:${testdir}/../../../../../stubs/apache-commons-lang:${testdir}/../../../../../stubs/jaxen-1.2.0 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/micronaut-4.x:${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/stapler-1.263:${testdir}/../../../../../stubs/javax-servlet-2.5:${testdir}/../../../../../stubs/apache-commons-jelly-1.0.1:${testdir}/../../../../../stubs/apache-commons-fileupload-1.4:${testdir}/../../../../../stubs/saxon-xqj-9.x:${testdir}/../../../../../stubs/apache-commons-beanutils:${testdir}/../../../../../stubs/dom4j-2.1.1:${testdir}/../../../../../stubs/apache-commons-lang:${testdir}/../../../../../stubs/jaxen-1.2.0:${testdir}/../../../../../stubs/springframework-5.8.x diff --git a/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractUrlBasedView.java b/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractUrlBasedView.java index 9efd87af12f3..8c948a8a4ce7 100644 --- a/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractUrlBasedView.java +++ b/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractUrlBasedView.java @@ -3,7 +3,7 @@ import java.util.Locale; import org.springframework.lang.Nullable; -public abstract class AbstractUrlBasedView { +public abstract class AbstractUrlBasedView extends AbstractView { @Nullable private String url; diff --git a/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractView.java b/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractView.java new file mode 100644 index 000000000000..5c632428601e --- /dev/null +++ b/java/ql/test/stubs/springframework-5.8.x/org/springframework/web/servlet/view/AbstractView.java @@ -0,0 +1,11 @@ +package org.springframework.web.servlet.view; + +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.web.servlet.View; + +public abstract class AbstractView implements View { + @Override + public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { } +}