mirror of
https://github.com/hohn/codeql-workshop-sql-injection-java.git
synced 2025-12-16 10:43:05 +01:00
Make src/ and session/ runnable
This commit is contained in:
committed by
=Michael Hohn
parent
ddb5e545ff
commit
5ee57f0b58
118
session/README.org
Normal file
118
session/README.org
Normal file
@@ -0,0 +1,118 @@
|
||||
* SQL injection example
|
||||
This directory contains the codeql session snapshots as well as the full query
|
||||
[[./full-query-old-style.ql]]
|
||||
|
||||
The rest of this README contains a description of the query's development.
|
||||
|
||||
** Develop the query bottom-up
|
||||
1. Identify the /source/ part of the
|
||||
: System.console().readLine();
|
||||
expression, the =buf= argument.
|
||||
Start from a =from..where..select=, then convert to a predicate.
|
||||
|
||||
2. Identify the /sink/ part of the
|
||||
: conn.createStatement().executeUpdate(query);
|
||||
expression, the =query= argument. Again start from =from..where..select=,
|
||||
then convert to a predicate.
|
||||
|
||||
3. Fill in the /taintflow configuration/ boilerplate
|
||||
#+BEGIN_SRC java
|
||||
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||
SqliFlowConfig() { this = "SqliFlow" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node) {
|
||||
none()
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
The final query (without =isAdditionalTaintStep=) is
|
||||
#+BEGIN_SRC java
|
||||
/**
|
||||
,* @name SQLI Vulnerability
|
||||
,* @description Using untrusted strings in a sql query allows sql injection attacks.
|
||||
,* @kind path-problem
|
||||
,* @id java/SQLIVulnerable
|
||||
,* @problem.severity warning
|
||||
,*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||
SqliFlowConfig() { this = "SqliFlow" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
// System.console().readLine();
|
||||
exists(Call read |
|
||||
read.getCallee().getName() = "readLine" and
|
||||
read = source.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
// conn.createStatement().executeUpdate(query);
|
||||
exists(Call exec |
|
||||
exec.getCallee().getName() = "executeUpdate" and
|
||||
exec.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from SqliFlowConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink, source, sink, "Possible SQL injection"
|
||||
#+END_SRC
|
||||
|
||||
** (optional) Review of the results via SARIF file
|
||||
Query results are available in several output formats using the cli. The
|
||||
following produces the sarif format, a json-based result description.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# The setup information from before
|
||||
SRCDIR=$HOME/local/codeql-training-material.java-sqli/java/codeql-dataflow-sql-injection
|
||||
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||
|
||||
# Check paths
|
||||
echo $DB
|
||||
echo $SRCDIR
|
||||
|
||||
# To see the help
|
||||
codeql database analyze -h
|
||||
|
||||
# Run a query
|
||||
codeql database analyze \
|
||||
-v \
|
||||
--ram=14000 \
|
||||
-j12 \
|
||||
--rerun \
|
||||
--search-path ~/local/vmsync/ql \
|
||||
--format=sarif-latest \
|
||||
--output java-sqli.sarif \
|
||||
-- \
|
||||
$DB \
|
||||
$SRCDIR/SqlInjection.ql
|
||||
|
||||
# Examine the file in an editor
|
||||
edit java-sqli.sarif
|
||||
#+END_SRC
|
||||
|
||||
An example of using the sarif data is in the the jq script [[./sarif-summary.jq]].
|
||||
When run against the sarif input via
|
||||
#+BEGIN_SRC sh
|
||||
jq --raw-output --join-output -f sarif-summary.jq < java-sqli.sarif > java-sqli.txt
|
||||
#+END_SRC
|
||||
it produces output in a form close to that of compiler error messages:
|
||||
#+BEGIN_SRC text
|
||||
query-id: message line
|
||||
Path
|
||||
...
|
||||
Path
|
||||
...
|
||||
#+END_SRC
|
||||
|
||||
44
session/full-query-old-style.ql
Normal file
44
session/full-query-old-style.ql
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @name SQLI Vulnerability
|
||||
* @description Using untrusted strings in a sql query allows sql injection attacks.
|
||||
* @kind path-problem
|
||||
* @id cpp/SQLIVulnerable
|
||||
* @problem.severity warning
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class SqliFlowConfig extends TaintTracking::Configuration {
|
||||
SqliFlowConfig() { this = "SqliFlow" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
// System.console().readLine();
|
||||
exists(Call read |
|
||||
read.getCallee().getName() = "readLine" and
|
||||
read = source.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node sanitizer) { none() }
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node into, DataFlow::Node out) {
|
||||
// Extra taint step
|
||||
// String.format("INSERT INTO users VALUES (%d, '%s')", id, info);
|
||||
// Not needed here, but may be needed for larger libraries.
|
||||
none()
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
// conn.createStatement().executeUpdate(query);
|
||||
exists(Call exec |
|
||||
exec.getCallee().getName() = "executeUpdate" and
|
||||
exec.getArgument(0) = sink.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from SqliFlowConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink, source, sink, "Possible SQL injection"
|
||||
6
session/qlpack.yml
Normal file
6
session/qlpack.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
library: false
|
||||
name: codeql-workshop/java-sql-injection
|
||||
version: 0.0.1
|
||||
dependencies:
|
||||
codeql/java-all: "*"
|
||||
Reference in New Issue
Block a user