From d2595c657ff82fff89ba4c167b5c127cd5d72b8b Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 30 Jul 2025 11:55:22 -0400 Subject: [PATCH 1/2] Add starting point for taint debugging java sqli --- codeql-sqlite/TaintFlowDebugging.ql | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 codeql-sqlite/TaintFlowDebugging.ql diff --git a/codeql-sqlite/TaintFlowDebugging.ql b/codeql-sqlite/TaintFlowDebugging.ql new file mode 100644 index 0000000..37e1ab6 --- /dev/null +++ b/codeql-sqlite/TaintFlowDebugging.ql @@ -0,0 +1,67 @@ +/** + * @name introduction workshop + * @description Sample SQL Injection problem + * @id test + * @kind path-problem + * @problem.severity warning + */ + +import java +import semmle.code.java.dataflow.FlowSources + +class ReadLineSource extends Source { + ReadLineSource() { this.getMethod().hasQualifiedName("java.io", "Console", "readLine") } +} + +abstract class Source extends MethodCall { } + +class Sink extends MethodCall { + Sink() { this.getMethod().hasQualifiedName("java.sql", "Statement", "executeUpdate") } +} + +// from Sink s +// select s, "" +// from MethodCall mc +// where mc.getMethod().getName() = "readLine" +// select mc, mc.getMethod().getQualifiedName() +import semmle.code.java.dataflow.TaintTracking + +module MyFlowConfiguration implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + //exists(Source s | source.asExpr() = s) + source.asExpr() instanceof Source + } + + predicate isSink(DataFlow::Node sink) { + //sink.asExpr() instanceof Sink + exists(Sink sink2 | sink.asExpr() = sink2.getArgument(_)) + //any() + } + + predicate isBarrier(DataFlow::Node node) { + exists(MethodCall s | + s.getMethod().getName() = "hypotheticalSanitizer" and + s.getAnArgument() = node.asExpr() + ) + } + // predicate isAdditionalFlowStep(DataFlow::Node inNode, DataFlow::Node outNode) { + // exists(MethodCall mc | + // outNode.asExpr() = mc and + // mc.getMethod().hasQualifiedName("java.lang", "String", "format") and + // inNode.asExpr() = mc.getAnArgument() + // ) + // // exists(MethodCall mc | + // // mc.getAnArgument() = inNode.asExpr() and + // // outNode.asExpr() = mc + // // ) + // } +} + +//purposely does not find the result +module MyFlow = DataFlow::Global; + +import MyFlow::PathGraph + +from MyFlow::PathNode source, MyFlow::PathNode sink +where MyFlow::flowPath(source, sink) +select sink, source, sink, "Potential sql injection here " From 1b5de3ff9a11ceb4b009bd30409ef2cbdfcd0f6c Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Wed, 30 Jul 2025 11:56:28 -0400 Subject: [PATCH 2/2] Clean code for TaintFlowDebugging.ql --- codeql-sqlite/TaintFlowDebugging.ql | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/codeql-sqlite/TaintFlowDebugging.ql b/codeql-sqlite/TaintFlowDebugging.ql index 37e1ab6..a854532 100644 --- a/codeql-sqlite/TaintFlowDebugging.ql +++ b/codeql-sqlite/TaintFlowDebugging.ql @@ -8,6 +8,7 @@ import java import semmle.code.java.dataflow.FlowSources +import semmle.code.java.dataflow.TaintTracking class ReadLineSource extends Source { ReadLineSource() { this.getMethod().hasQualifiedName("java.io", "Console", "readLine") } @@ -19,13 +20,6 @@ class Sink extends MethodCall { Sink() { this.getMethod().hasQualifiedName("java.sql", "Statement", "executeUpdate") } } -// from Sink s -// select s, "" -// from MethodCall mc -// where mc.getMethod().getName() = "readLine" -// select mc, mc.getMethod().getQualifiedName() -import semmle.code.java.dataflow.TaintTracking - module MyFlowConfiguration implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { //exists(Source s | source.asExpr() = s) @@ -33,7 +27,6 @@ module MyFlowConfiguration implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { - //sink.asExpr() instanceof Sink exists(Sink sink2 | sink.asExpr() = sink2.getArgument(_)) //any() }