From 563d0e733432e16a48d1e1419d363c5dddad9a46 Mon Sep 17 00:00:00 2001 From: Michael Hohn Date: Wed, 22 Nov 2023 21:39:02 -0800 Subject: [PATCH] WIP: test structure and ultimate source query --- README.org | 29 ++++++++---- codeql-workspace.yml | 2 + js-sqli.code-workspace | 4 ++ .../codeql-pack.lock.yml | 0 qlpack.yml => session/qlpack.yml | 2 +- session/session.ql | 38 +++++++++++++++ solutions/UltimateSource.ql | 38 +++++++++++++++ solutions/codeql-pack.lock.yml | 22 +++++++++ solutions/qlpack.yml | 8 ++++ tests/UltimateSource/UltimateSource.expected | 0 tests/UltimateSource/UltimateSource.qlref | 1 + tests/UltimateSource/add-user.js | 47 +++++++++++++++++++ tests/codeql-pack.lock.yml | 22 +++++++++ tests/qlpack.yml | 8 ++++ 14 files changed, 210 insertions(+), 11 deletions(-) create mode 100644 codeql-workspace.yml rename codeql-pack.lock.yml => session/codeql-pack.lock.yml (100%) rename qlpack.yml => session/qlpack.yml (81%) create mode 100644 session/session.ql create mode 100644 solutions/UltimateSource.ql create mode 100644 solutions/codeql-pack.lock.yml create mode 100644 solutions/qlpack.yml create mode 100644 tests/UltimateSource/UltimateSource.expected create mode 100644 tests/UltimateSource/UltimateSource.qlref create mode 100644 tests/UltimateSource/add-user.js create mode 100644 tests/codeql-pack.lock.yml create mode 100644 tests/qlpack.yml diff --git a/README.org b/README.org index 20b4f33..6454d46 100644 --- a/README.org +++ b/README.org @@ -81,18 +81,27 @@ 8. install the pack dependencies for the CLI. In a shell, use #+BEGIN_SRC sh - cd ~/local/codeql-dataflow-sql-injection-python - codeql pack install + cd ~/local/codeql-javascript-multiflow/ + codeql pack install session + codeql pack install solutions + codeql pack install tests #+END_SRC - 9. install the pack dependencies VS Code. Do this via - : command palette - and then select all listed by - : CodeQL: Install Pack Dependencies + 9. Run the tests. + #+BEGIN_SRC sh + cd ~/local/codeql-javascript-multiflow/ + codeql test run tests/UltimateSource/UltimateSource.qlref + #+END_SRC - It will generate a =codeql-pack.lock.yml= file. - 10. use the following to build a CodeQL database. + 10. install the pack dependencies VS Code. Do this via + : command palette + and then select all listed by + : CodeQL: Install Pack Dependencies + + It will generate a =codeql-pack.lock.yml= file. + + 11. use the following to build a CodeQL database. #+BEGIN_SRC sh #* Build the db with source commit id. codeql --version @@ -112,12 +121,12 @@ unzip -v js-sqli-db-*/src.zip |grep add #+END_SRC - 11. add the database to the editor. To do this there is a widget on the left + 12. add the database to the editor. To do this there is a widget on the left side of editor that looks like QL and after selecting that, there is a databases panel. There are options to select from archive or folder. Select the "from folder" option and add the "database" folders you created above. - 12. open the query =trivial.ql= and run it via + 13. open the query =trivial.ql= and run it via : right click > run query on selected database There are several ways to install the CodeQL binaries and libraries. Here is a diff --git a/codeql-workspace.yml b/codeql-workspace.yml new file mode 100644 index 0000000..d3c7345 --- /dev/null +++ b/codeql-workspace.yml @@ -0,0 +1,2 @@ +provides: + - "*/*.qlpack" diff --git a/js-sqli.code-workspace b/js-sqli.code-workspace index 162d985..ed39235 100644 --- a/js-sqli.code-workspace +++ b/js-sqli.code-workspace @@ -2,6 +2,10 @@ "folders": [ { "path": "." + }, + { + "name": "[js-sqli-db-c860686 source archive]", + "uri": "codeql-zip-archive://0-72/Users/hohn/local/codeql-javascript-multiflow/js-sqli-db-c860686/src.zip" } ], "settings": { diff --git a/codeql-pack.lock.yml b/session/codeql-pack.lock.yml similarity index 100% rename from codeql-pack.lock.yml rename to session/codeql-pack.lock.yml diff --git a/qlpack.yml b/session/qlpack.yml similarity index 81% rename from qlpack.yml rename to session/qlpack.yml index fba5fbe..7e98010 100644 --- a/qlpack.yml +++ b/session/qlpack.yml @@ -1,6 +1,6 @@ --- library: false -name: hohn/codeql-javascript-multiflow +name: codeql-javascript-multiflow-session version: 0.0.1 # Install the queries for browsing. They are not needed for this example. dependencies: diff --git a/session/session.ql b/session/session.ql new file mode 100644 index 0000000..fdde5cd --- /dev/null +++ b/session/session.ql @@ -0,0 +1,38 @@ +import javascript + +// Ultimate source +// ---------------- +// var line = stdinBuffer.toString(); +predicate uSource(MethodCallExpr sbts) { + // sbts.getReceiver().(DotExpr).getPropertyNameExpr().(Identifier).getName() = "toString" + sbts.getMethodName().matches("%toString%") +} + +// Ultimate sink +// ---------------- +// db.exec(query); + +// Intermediate flow sink +// ------------------------ +// Connect +// const db = new sqlite3.Database( +// to its use +// db.exec(query); +// +// class IntermediateSink extends DataFlow::Configuration { +// IntermediateSink() { this = "IntermediateSink" } + +// override predicate isSource(DataFlow::Node nd) { +// exists(JsonParserCall jpc | nd = jpc.getOutput()) +// } + +// override predicate isSink(DataFlow::Node nd) { exists(DataFlow::PropRef pr | nd = pr.getBase()) } +// } + +// from IntermediateSink cfg, DataFlow::Node source, DataFlow::Node sink +// where cfg.hasFlow(source, sink) +// select sink, "Property access on JSON value originating $@.", source, "here" + +from MethodCallExpr sbts +where uSource(sbts) +select sbts \ No newline at end of file diff --git a/solutions/UltimateSource.ql b/solutions/UltimateSource.ql new file mode 100644 index 0000000..eda161d --- /dev/null +++ b/solutions/UltimateSource.ql @@ -0,0 +1,38 @@ +import javascript + +// Ultimate source +// ---------------- +// var line = stdinBuffer.toString(); +predicate uSource(MethodCallExpr sbts) { + // sbts.getReceiver().(DotExpr).getPropertyNameExpr().(Identifier).getName() = "toString" + sbts.getMethodName().matches("%toString%") +} + +// Ultimate sink +// ---------------- +// db.exec(query); + +// Intermediate flow sink +// ------------------------ +// Connect +// const db = new sqlite3.Database( +// to its use +// db.exec(query); +// +// class IntermediateSink extends DataFlow::Configuration { +// IntermediateSink() { this = "IntermediateSink" } + +// override predicate isSource(DataFlow::Node nd) { +// exists(JsonParserCall jpc | nd = jpc.getOutput()) +// } + +// override predicate isSink(DataFlow::Node nd) { exists(DataFlow::PropRef pr | nd = pr.getBase()) } +// } + +// from IntermediateSink cfg, DataFlow::Node source, DataFlow::Node sink +// where cfg.hasFlow(source, sink) +// select sink, "Property access on JSON value originating $@.", source, "here" + +from MethodCallExpr sbts +where uSource(sbts) +select sbts diff --git a/solutions/codeql-pack.lock.yml b/solutions/codeql-pack.lock.yml new file mode 100644 index 0000000..0466d67 --- /dev/null +++ b/solutions/codeql-pack.lock.yml @@ -0,0 +1,22 @@ +--- +lockVersion: 1.0.0 +dependencies: + codeql/javascript-all: + version: 0.8.3 + codeql/javascript-queries: + version: 0.8.3 + codeql/mad: + version: 0.2.3 + codeql/regex: + version: 0.2.3 + codeql/suite-helpers: + version: 0.7.3 + codeql/tutorial: + version: 0.2.3 + codeql/typos: + version: 0.2.3 + codeql/util: + version: 0.2.3 + codeql/yaml: + version: 0.2.3 +compiled: false diff --git a/solutions/qlpack.yml b/solutions/qlpack.yml new file mode 100644 index 0000000..c857416 --- /dev/null +++ b/solutions/qlpack.yml @@ -0,0 +1,8 @@ +--- +library: false +name: codeql-javascript-multiflow-solutions +version: 0.0.1 +# Install the queries for browsing. They are not needed for this example. +dependencies: + codeql/javascript-all: "*" + codeql/javascript-queries: "*" diff --git a/tests/UltimateSource/UltimateSource.expected b/tests/UltimateSource/UltimateSource.expected new file mode 100644 index 0000000..e69de29 diff --git a/tests/UltimateSource/UltimateSource.qlref b/tests/UltimateSource/UltimateSource.qlref new file mode 100644 index 0000000..3a57be9 --- /dev/null +++ b/tests/UltimateSource/UltimateSource.qlref @@ -0,0 +1 @@ +UltimateSource.ql diff --git a/tests/UltimateSource/add-user.js b/tests/UltimateSource/add-user.js new file mode 100644 index 0000000..a4c8b1c --- /dev/null +++ b/tests/UltimateSource/add-user.js @@ -0,0 +1,47 @@ +function get_user_info() { + var fs = require("fs"); + var stdinBuffer = fs.readFileSync(process.stdin.fd); + var line = stdinBuffer.toString(); + console.log(line); + line = line.replace(/(\r\n|\n|\r)/gm, ""); + return line +} + +function get_new_id() { + return Math.floor(Math.random() * 12345); +} + +function connect_db() { + const sqlite3 = require('sqlite3').verbose(); + const db = new sqlite3.Database( + 'users.sqlite', + sqlite3.OPEN_READWRITE | sqlite3.OPEN_FULLMUTEX, + err => { + if (err){ + console.log(err); + throw err; + } else { + console.log('DB opened'); + } + }); + + return db; +} + +function write_info(db, id, info) { + db.serialize(); + const query = `INSERT INTO users VALUES (${id}, "${info}")`; + console.log(query); + db.exec(query); + db.close(); +} + +let add_user = () => { + console.log("Running add-user"); + var info = get_user_info(); + var id = get_new_id(); + var db = connect_db(); + write_info(db, id, info); +} + +add_user() diff --git a/tests/codeql-pack.lock.yml b/tests/codeql-pack.lock.yml new file mode 100644 index 0000000..0466d67 --- /dev/null +++ b/tests/codeql-pack.lock.yml @@ -0,0 +1,22 @@ +--- +lockVersion: 1.0.0 +dependencies: + codeql/javascript-all: + version: 0.8.3 + codeql/javascript-queries: + version: 0.8.3 + codeql/mad: + version: 0.2.3 + codeql/regex: + version: 0.2.3 + codeql/suite-helpers: + version: 0.7.3 + codeql/tutorial: + version: 0.2.3 + codeql/typos: + version: 0.2.3 + codeql/util: + version: 0.2.3 + codeql/yaml: + version: 0.2.3 +compiled: false diff --git a/tests/qlpack.yml b/tests/qlpack.yml new file mode 100644 index 0000000..cc6d733 --- /dev/null +++ b/tests/qlpack.yml @@ -0,0 +1,8 @@ +--- +library: false +name: codeql-javascript-multiflow-tests +version: 0.0.1 +dependencies: + "codeql-javascript-multiflow-solutions" : "*" +extractor: javascript +