mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Query to detect unsafe getResource calls in Java EE applications
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
// BAD: no URI validation
|
||||
URL url = servletContext.getResource(requestUrl);
|
||||
InputStream in = url.openStream();
|
||||
|
||||
InputStream in = request.getServletContext().getResourceAsStream(requestPath);
|
||||
|
||||
// GOOD: check for a trusted prefix, ensuring path traversal is not used to erase that prefix:
|
||||
// (alternatively use `Path.normalize` instead of checking for `..`)
|
||||
if (!requestPath.contains("..") && requestPath.startsWith("/trusted")) {
|
||||
InputStream in = request.getServletContext().getResourceAsStream(requestPath);
|
||||
}
|
||||
|
||||
Path path = Paths.get(requestUrl).normalize().toRealPath();
|
||||
URL url = sc.getResource(path.toString());
|
||||
@@ -36,6 +36,13 @@ attacks. It also shows how to remedy the problem by validating the user input.
|
||||
|
||||
<sample src="UnsafeServletRequestDispatch.java" />
|
||||
|
||||
<p>The following examples show an HTTP request parameter or request path being used directly to
|
||||
retrieve a resource of a Java EE application without validating the input, which allows sensitive
|
||||
file exposure attacks. It also shows how to remedy the problem by validating the user input.
|
||||
</p>
|
||||
|
||||
<sample src="UnsafeResourceGet.java" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
<li>File Disclosure:
|
||||
@@ -47,5 +54,8 @@ attacks. It also shows how to remedy the problem by validating the user input.
|
||||
<li>Micro Focus:
|
||||
<a href="https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.file_disclosure_j2ee">File Disclosure: J2EE</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://vuldb.com/?id.81084">Apache Tomcat 6.0/7.0/8.0/9.0 Servletcontext Getresource/getresourceasstream/getresourcepaths Path Traversal</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import java
|
||||
import experimental.semmle.code.java.frameworks.Jsf
|
||||
import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.StringPrefixes
|
||||
|
||||
@@ -18,6 +19,49 @@ private class RequestDispatcherSink extends UnsafeUrlForwardSink {
|
||||
}
|
||||
}
|
||||
|
||||
/** The JBoss class `FileResourceManager`. */
|
||||
class FileResourceManager extends RefType {
|
||||
FileResourceManager() {
|
||||
this.hasQualifiedName("io.undertow.server.handlers.resource", "FileResourceManager")
|
||||
}
|
||||
}
|
||||
|
||||
/** The JBoss method `getResource` of `FileResourceManager`. */
|
||||
class GetWildflyResourceMethod extends Method {
|
||||
GetWildflyResourceMethod() {
|
||||
this.getDeclaringType().getASupertype*() instanceof FileResourceManager and
|
||||
this.hasName("getResource")
|
||||
}
|
||||
}
|
||||
|
||||
/** The JBoss class `VirtualFile`. */
|
||||
class VirtualFile extends RefType {
|
||||
VirtualFile() { this.hasQualifiedName("org.jboss.vfs", "VirtualFile") }
|
||||
}
|
||||
|
||||
/** The JBoss method `getChild` of `FileResourceManager`. */
|
||||
class GetVirtualFileMethod extends Method {
|
||||
GetVirtualFileMethod() {
|
||||
this.getDeclaringType().getASupertype*() instanceof VirtualFile and
|
||||
this.hasName("getChild")
|
||||
}
|
||||
}
|
||||
|
||||
/** An argument to `getResource()` or `getResourceAsStream()`. */
|
||||
private class GetResourceSink extends UnsafeUrlForwardSink {
|
||||
GetResourceSink() {
|
||||
exists(MethodAccess ma |
|
||||
(
|
||||
ma.getMethod() instanceof GetServletResourceMethod or
|
||||
ma.getMethod() instanceof GetFacesResourceMethod or
|
||||
ma.getMethod() instanceof GetWildflyResourceMethod or
|
||||
ma.getMethod() instanceof GetVirtualFileMethod
|
||||
) and
|
||||
ma.getArgument(0) = this.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** An argument to `new ModelAndView` or `ModelAndView.setViewName`. */
|
||||
private class SpringModelAndViewSink extends UnsafeUrlForwardSink {
|
||||
SpringModelAndViewSink() {
|
||||
|
||||
24
java/ql/src/experimental/semmle/code/java/frameworks/Jsf.qll
Normal file
24
java/ql/src/experimental/semmle/code/java/frameworks/Jsf.qll
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Provides classes and predicates for working with the Java Server Faces (JSF).
|
||||
*/
|
||||
|
||||
import semmle.code.java.Type
|
||||
|
||||
/**
|
||||
* The JSF class `FacesContext` for processing HTTP requests.
|
||||
*/
|
||||
class ExternalContext extends RefType {
|
||||
ExternalContext() {
|
||||
this.hasQualifiedName(["javax.faces.context", "jakarta.faces.context"], "ExternalContext")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods `getResource()` and `getResourceAsStream()` declared in JSF `ExternalContext`.
|
||||
*/
|
||||
class GetFacesResourceMethod extends Method {
|
||||
GetFacesResourceMethod() {
|
||||
this.getDeclaringType().getASupertype*() instanceof ExternalContext and
|
||||
this.hasName(["getResource", "getResourceAsStream"])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user