I am working on creating a query using codeql so that I can detect CWE vulnerabilities in Java code. My query executes just fine using the VS Code CodeQL extension, so I know that logically it works for what I need. However, when using the CLI (Which is necessary) I am getting this error.
A fatal error occurred: Could not process query metadata for ServletRuntimeErrorMessageContainingSensitiveInformation.ql. Error was: Expected result pattern(s) are not present for path-problem query: Expected at least two result patterns. These should include at least an 'edges' result set (see https://codeql.github.com/docs/writing-codeql-queries/creating-path-queries/). [INVALID_RESULT_PATTERNS]
Currently using CodeQL CLI v.2.15.1. However, I have used a few different version trying to fix this.
This seems related to a formatting issue since CodeQL can't find a way to output the results set. I have read the information in the suggested link and even at one point reformatted my entire query in order to ensure the issue wasn't caused by the structure.
Given the error, my first thought was I need to create an edges predicate. However, I have read other sources such as this one (Which is in JS, but still similar). Along with the docs that even suggest that you don't need to explicatally define an edges predicate.
You can import a predefined edges predicate from a path graph module in one of the standard data flow libraries. In addition to the path graph module, the data flow libraries contain the other classes, predicates, and modules that are commonly used in data flow analysis.
import MyFlow::PathGraphThis statement imports the PathGraph module from the data flow library (DataFlow.qll), in which edges is defined.
However, even after these attempts, I am still receiving this error for all of my queries that use dataflow.
/**
* @name Exposure of sensitive information in servlet responses
* @description Writing sensitive information from exceptions or sensitive file paths to HTTP responses can leak details to users.
* @kind path-problem
* @problem.severity warning
* @id CWE-536
* @tags security
* external/cwe/cwe-536
* @cwe CWE-536
*/
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.frameworks.Servlets
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.security.SensitiveVariables
import MyFlow::PathGraph
module SensitiveInfoLeakServletConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(MethodAccess ma |
// Sources from exceptions
ma.getMethod().getDeclaringType().getASupertype*().hasQualifiedName("java.lang", "Throwable") and
(ma.getMethod().hasName(["getMessage", "getStackTrace", "getStackTraceAsString", "printStackTrace"])) and
source.asExpr() = ma
)
or
exists(MethodAccess ma |
// Additional sources: Sensitive file paths
ma.getMethod().hasName("getAbsolutePath") and
ma.getMethod().getDeclaringType().hasQualifiedName("java.io", "File") and
source.asExpr() = ma
)
or
exists(SensitiveVariableExpr sve |
source.asExpr() = sve
)
}
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
// Ensuring write is called on servlet response
ma.getMethod().hasName("write") and
ma.getQualifier().(MethodAccess).getMethod().hasName("getWriter") and
ma.getQualifier().(MethodAccess).getQualifier().getType().(RefType).hasQualifiedName("javax.servlet.http", "HttpServletResponse") and
sink.asExpr() = ma.getAnArgument()
) or
exists(MethodAccess ma |
// Inferring println on PrintWriter obtained from servlet response, assuming context
ma.getMethod().hasName("println") and
ma.getQualifier().getType().(RefType).hasQualifiedName("java.io", "PrintWriter") and
// Additional context checks might be added here to more directly associate with servlets
sink.asExpr() = ma.getAnArgument()
)
}
}
module MyFlow = DataFlow::Global<SensitiveInfoLeakServletConfig>;
from MyFlow::PathNode source, MyFlow::PathNode sink
where MyFlow::flowPath(source, sink)
select sink, source, sink, "Potential CWE-536: Servlet Runtime Error Message Containing Sensitive Information."
I would appreciate any help with this.