mirror of
https://github.com/hohn/codeql-lab.git
synced 2025-12-16 18:03:08 +01:00
wip: set up codeql-sqlite/ sample
This commit is contained in:
committed by
=Michael Hohn
parent
0e06b153cc
commit
e2e555c44c
@@ -252,7 +252,6 @@
|
||||
| 14 | "return {}" | code-injection |
|
||||
|
||||
* Identify usage of injection-related models in existing queries
|
||||
|
||||
To verify whether existing CodeQL queries make use of the injection-related
|
||||
models, we can search for files in the =ql/java= and =ql/cpp= directories that
|
||||
contain the string =-injection=. This string often appears in taint-tracking
|
||||
@@ -290,7 +289,6 @@
|
||||
These files include both top-level queries (under =src/Security/...=) and reusable model libraries (under =lib/semmle/...=). Experimental and framework-specific queries are also included.
|
||||
|
||||
** C++ Queries
|
||||
|
||||
Likewise, to check for C++ queries that reference =-injection=, use:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
@@ -309,6 +307,7 @@
|
||||
These files indicate active use of injection-related taint tracking in the C++ suite as well.
|
||||
|
||||
* TODO for java, the sqltainted query will find the sink, not the source yet.
|
||||
[[../ql/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql]]
|
||||
* TODO vulnerable sample, jedis
|
||||
Running the model editor a jedis db models jedis dependencies; we need jedis
|
||||
/as/ dependency to model it.
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class AddUser {
|
||||
public static Connection connect() {
|
||||
Connection conn = null;
|
||||
try {
|
||||
String url = "jdbc:sqlite:users.sqlite";
|
||||
conn = DriverManager.getConnection(url);
|
||||
System.out.println("Connected...");
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
static String get_user_info() {
|
||||
System.out.println("Enter name:");
|
||||
return System.console().readLine();
|
||||
}
|
||||
|
||||
static void write_info(int id, String info) {
|
||||
try (Connection conn = connect()) {
|
||||
String query = String.format("INSERT INTO users VALUES (%d, '%s')", id, info);
|
||||
conn.createStatement().executeUpdate(query);
|
||||
System.err.printf("Sent: %s", query);
|
||||
} catch (SQLException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
static int get_new_id() {
|
||||
return (int)(Math.random()*100000);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String info;
|
||||
int id;
|
||||
|
||||
info = get_user_info();
|
||||
id = get_new_id();
|
||||
write_info(id, info);
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
* 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.
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
# Use a simple headline prompt
|
||||
PS1='
|
||||
\033[32m---- SQL injection demo ----\[\033[33m\033[0m\]
|
||||
$?:$ '
|
||||
|
||||
|
||||
# Build
|
||||
./build.sh
|
||||
|
||||
# Prepare db
|
||||
./admin -r
|
||||
./admin -c
|
||||
./admin -s
|
||||
|
||||
# Add regular user interactively
|
||||
./add-user 2>> users.log
|
||||
First User
|
||||
|
||||
# Check
|
||||
./admin -s
|
||||
|
||||
# Add Johnny Droptable
|
||||
./add-user 2>> users.log
|
||||
Johnny'); DROP TABLE users; --
|
||||
|
||||
# And the problem:
|
||||
./admin -s
|
||||
|
||||
# Check the log
|
||||
tail users.log
|
||||
#+END_SRC
|
||||
|
||||
** Identify the problem
|
||||
=./add-user= is reading from =STDIN=, and writing to a database; looking at the code in
|
||||
[[./AddUser.java]] leads to
|
||||
: System.console().readLine();
|
||||
for the read and
|
||||
: conn.createStatement().executeUpdate(query);
|
||||
for the write.
|
||||
|
||||
This problem is thus a dataflow problem; in codeql terminology we have
|
||||
- a /source/ at the =System.console().readLine();=
|
||||
- a /sink/ at the =conn.createStatement().executeUpdate(query);=
|
||||
|
||||
We write codeql to identify these two, and then connect them via
|
||||
- a /dataflow configuration/ -- for this problem, the more general /taintflow
|
||||
configuration/.
|
||||
|
||||
** 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.
|
||||
SRCDIR=$(pwd)
|
||||
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||
|
||||
echo $DB
|
||||
test -d "$DB" && rm -fR "$DB"
|
||||
mkdir -p "$DB"
|
||||
|
||||
cd $SRCDIR && codeql database create --language=java -s . -j 8 -v $DB --command='./build.sh'
|
||||
|
||||
# Check for AddUser in the db
|
||||
unzip -v $DB/src.zip | grep AddUser
|
||||
#+END_SRC
|
||||
|
||||
Then add this database directory to your VS Code =DATABASES= tab.
|
||||
|
||||
** (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. The sequence here is also used by the GHAS
|
||||
default setup, so familiarity with it helps in reviewing logs.
|
||||
|
||||
The purpose of these sections is to illustrate the codeql commands used in
|
||||
default setup and making the connection between the GHAS default action and the
|
||||
CodeQL CLI explicit.
|
||||
|
||||
After running default setup and downloading the log, you will see the following
|
||||
entries embedded in the full log. They are repeated here for completeness; you
|
||||
can skip the command-line options for now.
|
||||
#+BEGIN_SRC sh
|
||||
codeql version --format=json
|
||||
|
||||
codeql resolve languages --format=betterjson --extractor-options-verbosity=4 --extractor-include-aliases
|
||||
|
||||
codeql database init --force-overwrite --db-cluster /home/runner/work/_temp/codeql_databases --source-root=/home/runner/work/codeql-workshop-sql-injection-java/codeql-workshop-sql-injection-java --extractor-include-aliases --language=java --codescanning-config=/home/runner/work/_temp/user-config.yaml --build-mode=none --calculate-language-specific-baseline --sublanguage-file-coverage
|
||||
|
||||
codeql database trace-command --use-build-mode --working-dir /home/runner/work/codeql-workshop-sql-injection-java/codeql-workshop-sql-injection-java /home/runner/work/_temp/codeql_databases/java
|
||||
|
||||
codeql database finalize --finalize-dataset --threads=4 --ram=14567 /home/runner/work/_temp/codeql_databases/java
|
||||
|
||||
codeql database run-queries --ram=14567 --threads=4 /home/runner/work/_temp/codeql_databases/java --expect-discarded-cache --min-disk-free=1024 -v --intra-layer-parallelism
|
||||
|
||||
codeql database cleanup /home/runner/work/_temp/codeql_databases/java --cache-cleanup=brutal
|
||||
|
||||
codeql database bundle /home/runner/work/_temp/codeql_databases/java --output=/home/runner/work/_temp/codeql_databases/java.zip --name=java
|
||||
#+END_SRC
|
||||
|
||||
|
||||
To build a database in steps locally, use the following sequence, adjusting
|
||||
paths to your setup:
|
||||
#+BEGIN_SRC sh
|
||||
# Build the db with source commit id.
|
||||
|
||||
SRCDIR=$HOME/local/codeql-workshop-sql-injection-java/src
|
||||
DB=$SRCDIR/java-sqli-$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||
|
||||
# Check paths
|
||||
echo "DB will be: $DB"
|
||||
echo "SRC is in: $SRCDIR"
|
||||
|
||||
# Prepare db directory
|
||||
test -d "$DB" && rm -fR "$DB"
|
||||
mkdir -p "$DB"
|
||||
|
||||
# Run the build, without --db-cluster
|
||||
# Init database
|
||||
cd $SRCDIR
|
||||
codeql database init \
|
||||
--language=java \
|
||||
--build-mode=none \
|
||||
--source-root=. \
|
||||
-v $DB
|
||||
|
||||
# Repeat trace-command as needed to cover all targets
|
||||
codeql database trace-command \
|
||||
--use-build-mode \
|
||||
--working-dir . \
|
||||
$DB
|
||||
|
||||
# Finalize database
|
||||
codeql database finalize \
|
||||
--finalize-dataset \
|
||||
--threads=4 \
|
||||
--ram=14567 \
|
||||
$DB
|
||||
|
||||
# Use the database; get the location
|
||||
echo $DB
|
||||
# /Users/hohn/local/codeql-workshop-sql-injection-java/src/java-sqli-161a1d5
|
||||
#+END_SRC
|
||||
|
||||
To also analyze the database just built, we use the log's command but add an
|
||||
explicit query name:
|
||||
#+BEGIN_SRC sh
|
||||
codeql database run-queries \
|
||||
--ram=14567 \
|
||||
--threads=4 $DB \
|
||||
--expect-discarded-cache \
|
||||
--min-disk-free=1024 \
|
||||
-v \
|
||||
--intra-layer-parallelism \
|
||||
-- \
|
||||
../session/simple.ql
|
||||
|
||||
|
||||
#+END_SRC
|
||||
|
||||
This only gives us a bqrs file, we want sarif. Checking help:
|
||||
#+BEGIN_SRC text
|
||||
codeql database run-queries --help
|
||||
Usage: codeql database run-queries [OPTIONS] -- <database> [<query|dir|suite|pack>...]
|
||||
[Plumbing] Run a set of queries together.
|
||||
|
||||
Run one or more queries against a CodeQL database, saving the results to the results
|
||||
subdirectory of the database directory.
|
||||
|
||||
The results can later be converted to readable formats by codeql database interpret-results,
|
||||
or query-for-query by with codeql bqrs decode or codeql bqrs interpret.
|
||||
#+END_SRC
|
||||
|
||||
So we run the following
|
||||
#+BEGIN_SRC sh
|
||||
VERSION=$(cd $SRCDIR && git rev-parse --short HEAD)
|
||||
codeql database interpret-results \
|
||||
--format=sarifv2.1.0 \
|
||||
-o simple-$VERSION.sarif \
|
||||
-- $DB ../session/simple.ql
|
||||
|
||||
echo "Results in simple-$VERSION.sarif"
|
||||
#+END_SRC
|
||||
We kept the output for this sample in [[./simple-161a1d5.sarif]]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
java -cp ".:sqlite-jdbc-3.36.0.1.jar" AddUser $@
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
script=$(basename "$0")
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
MAGENTA='\033[0;95m'
|
||||
NC='\033[0m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[0;33m'
|
||||
|
||||
help() {
|
||||
echo -e "Usage: ./${script} [options]" \
|
||||
"\n${YELLOW}Options: ${NC}" \
|
||||
"\n\t -h ${GREEN}Show Help ${NC}" \
|
||||
"\n\t -c ${MAGENTA}Creates a users table ${NC}" \
|
||||
"\n\t -s ${MAGENTA}Shows all records in the users table ${NC}" \
|
||||
"\n\t -r ${RED}Removes users table ${NC}"
|
||||
}
|
||||
remove-db () {
|
||||
rm users.sqlite
|
||||
}
|
||||
|
||||
create-db () {
|
||||
echo '
|
||||
CREATE TABLE users (
|
||||
user_id INTEGER not null,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
' | sqlite3 users.sqlite
|
||||
}
|
||||
|
||||
show-db () {
|
||||
echo '
|
||||
SELECT * FROM users;
|
||||
' | sqlite3 users.sqlite
|
||||
}
|
||||
|
||||
if [ $# == 0 ]; then
|
||||
help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while getopts "h?csr" option
|
||||
do
|
||||
case "${option}"
|
||||
in
|
||||
h|\?)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
c) create-db
|
||||
;;
|
||||
s) show-db
|
||||
;;
|
||||
r) remove-db
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
javac -cp "sqlite-jdbc-3.36.0.1.jar" AddUser.java
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# -*- sh -*-
|
||||
.runs | .[] | .results | .[] |
|
||||
( (.ruleId, ": ",
|
||||
(.message.text | split("\n") | ( .[0], " [", length-1 , " more]")),
|
||||
"\n")
|
||||
,
|
||||
(if (.codeFlows != null) then
|
||||
(.codeFlows | .[] |
|
||||
(" Path\n"
|
||||
,
|
||||
( .threadFlows | .[] | .locations | .[] | .location | " "
|
||||
,
|
||||
( .physicalLocation | ( .artifactLocation.uri, ":", .region.startLine, ":"))
|
||||
,
|
||||
(.message.text, " ")
|
||||
,
|
||||
"\n"
|
||||
)))
|
||||
else
|
||||
(.locations | .[] |
|
||||
( " "
|
||||
,
|
||||
(.physicalLocation | ( .artifactLocation.uri, ":", .region.startLine, ":"))
|
||||
))
|
||||
,
|
||||
# .message.text,
|
||||
"\n"
|
||||
end)
|
||||
) | tostring
|
||||
|
||||
# This script extracts the following parts of the sarif output:
|
||||
#
|
||||
# # problem
|
||||
# "runs" : [ {
|
||||
# "results" : [ {
|
||||
# "ruleId" : "cpp/UncheckedErrorCode",
|
||||
|
||||
# # path problem
|
||||
# "runs" : [ {
|
||||
# "tool" : {
|
||||
# "driver" : {
|
||||
# "rules" : [ {
|
||||
# "properties" : {
|
||||
# "kind" : "path-problem",
|
||||
|
||||
# "runs" : [ {
|
||||
# "results" : [ {
|
||||
# "ruleId" : "cpp/DangerousArithmetic",
|
||||
# "ruleIndex" : 6,
|
||||
# "message" : {
|
||||
# "text" : "Potential overflow (conversion: int -> unsigned int)\nPotential overflow (con
|
||||
|
||||
# "runs" : [ {
|
||||
# "results" : [ {
|
||||
# "codeFlows" : [ {
|
||||
# "threadFlows" : [ {
|
||||
# "locations" : [ {
|
||||
# "location" : {
|
||||
# "message" : {
|
||||
# "text" : "buff"
|
||||
BIN
codeql-jedis/src-sqlite/sqlite-jdbc-3.36.0.1.jar
(Stored with Git LFS)
BIN
codeql-jedis/src-sqlite/sqlite-jdbc-3.36.0.1.jar
(Stored with Git LFS)
Binary file not shown.
Reference in New Issue
Block a user