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
128
src/README.org
128
src/README.org
@@ -1,4 +1,12 @@
|
||||
* SQL injection example
|
||||
This directory contains the problematic Java source code. The rest of this
|
||||
README describes
|
||||
- the [[*Setup and sample run][Setup and sample run]] for the problem,
|
||||
- briefly describes how to [[*Identify the problem][Identify the problem]] and
|
||||
- instructions to [[*Build the codeql database][Build the codeql database]]
|
||||
|
||||
The codeql query is developed in [[../session/README.org]].
|
||||
|
||||
** Setup and sample run
|
||||
The jdbc connector at https://github.com/xerial/sqlite-jdbc, from [[https://github.com/xerial/sqlite-jdbc/releases/download/3.36.0.1/sqlite-jdbc-3.36.0.1.jar][here]] is
|
||||
included in the git repository.
|
||||
@@ -51,12 +59,11 @@
|
||||
We write codeql to identify these two, and then connect them via
|
||||
- a /dataflow configuration/ -- for this problem, the more general /taintflow
|
||||
configuration/.
|
||||
|
||||
** Build codeql database
|
||||
|
||||
** Build the codeql database
|
||||
To get started, build the codeql database (adjust paths to your setup):
|
||||
#+BEGIN_SRC sh
|
||||
# Build the db with source commit id.
|
||||
export PATH=$HOME/local/vmsync/codeql250:"$PATH"
|
||||
SRCDIR=$(pwd)
|
||||
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||
|
||||
@@ -72,8 +79,7 @@
|
||||
|
||||
Then add this database directory to your VS Code =DATABASES= tab.
|
||||
|
||||
|
||||
** Build codeql database in steps
|
||||
** (old / optional) Build the codeql database in steps
|
||||
For larger projects, using a single command to build everything is costly when
|
||||
any part of the build fails.
|
||||
|
||||
@@ -103,116 +109,4 @@
|
||||
|
||||
Then add this database directory to your VS Code =DATABASES= tab.
|
||||
|
||||
** 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: sarif file review of the results
|
||||
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
|
||||
export PATH=$HOME/local/vmsync/codeql250:"$PATH"
|
||||
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
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @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"
|
||||
Reference in New Issue
Block a user