Why am I getting this error when using dataflow in Codeql

50 Views Asked by At

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::PathGraph This 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.

0

There are 0 best solutions below