[Java] CWE-552: Unsafe url forward#6240
[Java] CWE-552: Unsafe url forward#6240smowton merged 7 commits intogithub:mainfrom haby0:java/UnsafeUrlForward
Conversation
smowton
left a comment
There was a problem hiding this comment.
Only taken a quick look so do please check in more detail, but I think there are already queries for the Spring aspects of this. getRequestDispatcher(...) does appear to be new.
| } | ||
|
|
||
| /** A Unsafe url forward sink from spring controller method. */ | ||
| private class SpringUrlForwardSink extends UnsafeUrlForwardSink { |
There was a problem hiding this comment.
Overlap with CWE-601/SpringUrlRedirect.ql?
There was a problem hiding this comment.
No overlap, no url jump will be triggered here, files will be read.
There was a problem hiding this comment.
Hello @pwntester, do you have any suggestions for this?
| ) | ||
| or | ||
| exists(MethodAccess ma | | ||
| ma.getMethod().hasName("setViewName") and |
There was a problem hiding this comment.
Overlap with CWE-094/SpringViewManipulation.ql?
There was a problem hiding this comment.
CWE-094/SpringViewManipulation must use the Thymeleaf template engine.
| exists(AddExpr ae | | ||
| ae.getRightOperand() = node.asExpr() and | ||
| ( | ||
| not ae.getLeftOperand().(CompileTimeConstantExpr).getStringValue().matches("/WEB-INF/%") | ||
| and | ||
| not ae.getLeftOperand().(CompileTimeConstantExpr).getStringValue() = "forward:" | ||
| ) | ||
| ) |
There was a problem hiding this comment.
Needs to account for string building patterns. This has been implemented in the past (#4530)
There was a problem hiding this comment.
I made changes, please review again, thank you!
| not exists(MethodAccess ma | | ||
| ma.getMethod().getName() in ["getRequestURI", "getRequestURL", "getPathInfo"] and | ||
| ma.getMethod() | ||
| .getDeclaringType() | ||
| .getASupertype*() | ||
| .hasQualifiedName("javax.servlet.http", "HttpServletRequest") | ||
| ) | ||
| } |
There was a problem hiding this comment.
You forgot to connect ma and source. Probably you want to add source.asExpr() = ma
atorralba
left a comment
There was a problem hiding this comment.
I added some inline comments.
Also, I agree there's some overlap with SpringUrlRedirect, since that query also looks for forward: URLs, but I guess it makes sense because that would be both an open redirect and a local file include. So I think there's no need to change it in this PR, but it's something to take into account when we eventually promote all of these (altogether with the copy-pasted code from SpringUrlRedirect, SpringViewManipulation and RequestForgery).
| getNumberOfParameters() = 1 and | ||
| getParameter(0).getType() instanceof TypeString |
There was a problem hiding this comment.
Are there overloads of this method with different parameters? If not, these two conditions aren't needed.
| /** | ||
| * A concatenate expression using the string `forward:` on the left. | ||
| * | ||
| * E.g: `"forward:" + url` |
There was a problem hiding this comment.
Avoid contractions in QLDoc: https://github.com/github/codeql/blob/main/docs/qldoc-style-guide.md#language-requirements
| /** | ||
| * A call to `StringBuilder.append` or `StringBuffer.append` method, and the parameter value is `"forward:"`. | ||
| * | ||
| * E.g: `StringBuilder.append("forward:")` |
There was a problem hiding this comment.
Avoid contractions in QLDoc: https://github.com/github/codeql/blob/main/docs/qldoc-style-guide.md#language-requirements
| ma.getMethod() | ||
| .getDeclaringType() | ||
| .getASupertype*() | ||
| .hasQualifiedName("javax.servlet.http", "HttpServletRequest") and |
There was a problem hiding this comment.
you can use the HttpServletRequest class from Servlets.qll.
| ) | ||
| or | ||
| exists(ClassInstanceExpr cie | | ||
| cie.getConstructedType().hasQualifiedName("org.springframework.web.servlet", "ModelAndView") and |
There was a problem hiding this comment.
You can use the ModelAndView class from SpringWeb.qll.
| ma.getMethod().hasName("setViewName") and | ||
| ma.getMethod() | ||
| .getDeclaringType() | ||
| .hasQualifiedName("org.springframework.web.servlet", "ModelAndView") and |
There was a problem hiding this comment.
You can use the ModelAndView class from SpringWeb.qll.
| In <code>bad1</code> method and <code>bad2</code> method and <code>bad3</code> method and | ||
| <code>bad4</code> method and <code>bad5</code> method and <code>bad6</code> method, shows an HTTP request parameter being used directly in a URL forward |
There was a problem hiding this comment.
| In <code>bad1</code> method and <code>bad2</code> method and <code>bad3</code> method and | |
| <code>bad4</code> method and <code>bad5</code> method and <code>bad6</code> method, shows an HTTP request parameter being used directly in a URL forward | |
| The <code>bad</code> methods show an HTTP request parameter being used directly in a URL forward |
There was a problem hiding this comment.
Also consider should the user manual example have so many cases? Are they all illustrating sufficiently different things, or would one or two do, with the rest kept in the tests but not the documentation?
| private Expr getQualifier(Expr e) { result = e.(MethodAccess).getQualifier() } | ||
|
|
||
| /** | ||
| * An extension of `StringBuilderVar` that also accounts for strings appended in StringBuilder/Buffer's constructor |
There was a problem hiding this comment.
This being copy-pasted from RequestForgery.qll, let's pull it out into a library rather than duplicate
|
Rewritten to use the shared library; will merge on green |
Constructing a server-side redirect path with user input could allow an attacker to download application binaries
(including application classes or jar files) or view arbitrary files within protected directories.