From d45b9ddee3cd6800be2c69fe430ed904bfe1250c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 17 Dec 2024 16:00:57 +0100 Subject: [PATCH 01/15] CI: Pin the codeql checkout to the branch that the CLI is based on. --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1a55db3..64d28d11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,8 +38,9 @@ jobs: if: steps.changes.outputs.src == 'true' env: GITHUB_TOKEN: ${{ github.token }} + CODEQL_CLI_VERSION: ${{ env.CODEQL_CLI_VERSION }} run: | - gh repo clone github/codeql # to make stubs available for tests + gh repo clone github/codeql -- -b codeql-cli-${CODEQL_CLI_VERSION} # to make stubs available for tests codeql pack download "codeql/${{ matrix.language }}-queries" codeql pack install "${{ matrix.language }}/lib" codeql pack install "${{ matrix.language }}/src" From 7ae252542f94a6b5c14170b0b28770fa14d248cd Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 17 Dec 2024 16:46:30 +0100 Subject: [PATCH 02/15] Do not download the query pack. --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 64d28d11..2eeb9d13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,6 @@ jobs: CODEQL_CLI_VERSION: ${{ env.CODEQL_CLI_VERSION }} run: | gh repo clone github/codeql -- -b codeql-cli-${CODEQL_CLI_VERSION} # to make stubs available for tests - codeql pack download "codeql/${{ matrix.language }}-queries" codeql pack install "${{ matrix.language }}/lib" codeql pack install "${{ matrix.language }}/src" codeql pack install "${{ matrix.language }}/test" From 1d0459293d1c641d0463cf346491633d7d1e60e3 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 09:35:40 +0100 Subject: [PATCH 03/15] Use CodeQL CLI 2.19.3 (this is the minimum version required by the java libraries). --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2eeb9d13..50a53665 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: workflow_dispatch: env: - CODEQL_CLI_VERSION: 2.19.2 + CODEQL_CLI_VERSION: 2.19.3 jobs: compile-and-test: From 29c7bb02234fbc05998ddeab42088f0511741cb5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 09:43:31 +0100 Subject: [PATCH 04/15] Run CI for all languages when there is change to the workflows. --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50a53665..0d2cbd39 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ jobs: filters: | src: - '${{ matrix.language }}/**' + - '.github/**' - name: Setup CodeQL if: steps.changes.outputs.src == 'true' From 1230787e4de84085554c75ed1abc4d7c270f0c1b Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 10:13:33 +0100 Subject: [PATCH 05/15] C++: Update dependencies to those released with 2.19.3. --- cpp/lib/codeql-pack.lock.yml | 20 +++++++++++++++----- cpp/src/codeql-pack.lock.yml | 24 +++++++++++++++++------- cpp/test/codeql-pack.lock.yml | 24 +++++++++++++++++------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/cpp/lib/codeql-pack.lock.yml b/cpp/lib/codeql-pack.lock.yml index 570a091a..44d02778 100644 --- a/cpp/lib/codeql-pack.lock.yml +++ b/cpp/lib/codeql-pack.lock.yml @@ -2,13 +2,23 @@ lockVersion: 1.0.0 dependencies: codeql/cpp-all: - version: 0.9.2 + version: 2.1.0 codeql/dataflow: - version: 0.0.3 + version: 1.1.5 + codeql/mad: + version: 1.0.11 + codeql/rangeanalysis: + version: 1.0.11 codeql/ssa: - version: 0.1.4 + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typeflow: + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 + codeql/xml: + version: 1.0.11 compiled: false diff --git a/cpp/src/codeql-pack.lock.yml b/cpp/src/codeql-pack.lock.yml index 2c012295..70645314 100644 --- a/cpp/src/codeql-pack.lock.yml +++ b/cpp/src/codeql-pack.lock.yml @@ -2,17 +2,27 @@ lockVersion: 1.0.0 dependencies: codeql/cpp-all: - version: 0.9.2 + version: 2.1.0 codeql/cpp-queries: - version: 0.7.4 + version: 1.2.6 codeql/dataflow: - version: 0.0.3 + version: 1.1.5 + codeql/mad: + version: 1.0.11 + codeql/rangeanalysis: + version: 1.0.11 codeql/ssa: - version: 0.1.4 + version: 1.0.11 codeql/suite-helpers: - version: 0.6.4 + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typeflow: + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 + codeql/xml: + version: 1.0.11 compiled: false diff --git a/cpp/test/codeql-pack.lock.yml b/cpp/test/codeql-pack.lock.yml index 2c012295..70645314 100644 --- a/cpp/test/codeql-pack.lock.yml +++ b/cpp/test/codeql-pack.lock.yml @@ -2,17 +2,27 @@ lockVersion: 1.0.0 dependencies: codeql/cpp-all: - version: 0.9.2 + version: 2.1.0 codeql/cpp-queries: - version: 0.7.4 + version: 1.2.6 codeql/dataflow: - version: 0.0.3 + version: 1.1.5 + codeql/mad: + version: 1.0.11 + codeql/rangeanalysis: + version: 1.0.11 codeql/ssa: - version: 0.1.4 + version: 1.0.11 codeql/suite-helpers: - version: 0.6.4 + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typeflow: + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 + codeql/xml: + version: 1.0.11 compiled: false From 4fadf59b4cf3d692ed2581fc903babc5780fe96c Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 10:20:57 +0100 Subject: [PATCH 06/15] C#: Update dependencies to those released with 2.19.3. --- csharp/lib/codeql-pack.lock.yml | 20 ++++++++++---------- csharp/src/codeql-pack.lock.yml | 24 ++++++++++++------------ csharp/test/codeql-pack.lock.yml | 24 ++++++++++++------------ 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/csharp/lib/codeql-pack.lock.yml b/csharp/lib/codeql-pack.lock.yml index aea2bd6e..ca0db41d 100644 --- a/csharp/lib/codeql-pack.lock.yml +++ b/csharp/lib/codeql-pack.lock.yml @@ -2,23 +2,23 @@ lockVersion: 1.0.0 dependencies: codeql/controlflow: - version: 1.0.10 + version: 1.0.11 codeql/csharp-all: - version: 3.0.1 + version: 3.1.0 codeql/dataflow: - version: 1.1.4 + version: 1.1.5 codeql/mad: - version: 1.0.10 + version: 1.0.11 codeql/ssa: - version: 1.0.10 + version: 1.0.11 codeql/threat-models: - version: 1.0.10 + version: 1.0.11 codeql/tutorial: - version: 1.0.10 + version: 1.0.11 codeql/typetracking: - version: 1.0.10 + version: 1.0.11 codeql/util: - version: 1.0.10 + version: 1.0.11 codeql/xml: - version: 1.0.10 + version: 1.0.11 compiled: false diff --git a/csharp/src/codeql-pack.lock.yml b/csharp/src/codeql-pack.lock.yml index 7b7bf720..f0c21ff3 100644 --- a/csharp/src/codeql-pack.lock.yml +++ b/csharp/src/codeql-pack.lock.yml @@ -2,27 +2,27 @@ lockVersion: 1.0.0 dependencies: codeql/controlflow: - version: 1.0.10 + version: 1.0.11 codeql/csharp-all: - version: 3.0.1 + version: 3.1.0 codeql/csharp-queries: - version: 1.0.10 + version: 1.0.11 codeql/dataflow: - version: 1.1.4 + version: 1.1.5 codeql/mad: - version: 1.0.10 + version: 1.0.11 codeql/ssa: - version: 1.0.10 + version: 1.0.11 codeql/suite-helpers: - version: 1.0.10 + version: 1.0.11 codeql/threat-models: - version: 1.0.10 + version: 1.0.11 codeql/tutorial: - version: 1.0.10 + version: 1.0.11 codeql/typetracking: - version: 1.0.10 + version: 1.0.11 codeql/util: - version: 1.0.10 + version: 1.0.11 codeql/xml: - version: 1.0.10 + version: 1.0.11 compiled: false diff --git a/csharp/test/codeql-pack.lock.yml b/csharp/test/codeql-pack.lock.yml index 7b7bf720..f0c21ff3 100644 --- a/csharp/test/codeql-pack.lock.yml +++ b/csharp/test/codeql-pack.lock.yml @@ -2,27 +2,27 @@ lockVersion: 1.0.0 dependencies: codeql/controlflow: - version: 1.0.10 + version: 1.0.11 codeql/csharp-all: - version: 3.0.1 + version: 3.1.0 codeql/csharp-queries: - version: 1.0.10 + version: 1.0.11 codeql/dataflow: - version: 1.1.4 + version: 1.1.5 codeql/mad: - version: 1.0.10 + version: 1.0.11 codeql/ssa: - version: 1.0.10 + version: 1.0.11 codeql/suite-helpers: - version: 1.0.10 + version: 1.0.11 codeql/threat-models: - version: 1.0.10 + version: 1.0.11 codeql/tutorial: - version: 1.0.10 + version: 1.0.11 codeql/typetracking: - version: 1.0.10 + version: 1.0.11 codeql/util: - version: 1.0.10 + version: 1.0.11 codeql/xml: - version: 1.0.10 + version: 1.0.11 compiled: false From fa7d7f1c02dce866a6d60a3e448fb5a4f9a94bec Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 14:20:33 +0100 Subject: [PATCH 07/15] C#: Update test utilities to be compatible with the new dependencies. --- csharp/test/TestUtilities/PrettyPrintModels.ql | 4 ---- 1 file changed, 4 deletions(-) diff --git a/csharp/test/TestUtilities/PrettyPrintModels.ql b/csharp/test/TestUtilities/PrettyPrintModels.ql index 05e6506e..9d960bc4 100644 --- a/csharp/test/TestUtilities/PrettyPrintModels.ql +++ b/csharp/test/TestUtilities/PrettyPrintModels.ql @@ -5,7 +5,3 @@ import semmle.code.csharp.dataflow.internal.ExternalFlow import codeql.dataflow.test.ProvenancePathGraph import codeql.dataflow.test.ProvenancePathGraph::TestPostProcessing::TranslateProvenanceResults - -from string relation, int row, int column, string data -where results(relation, row, column, data) -select relation, row, column, data From 2d9a1fed4a97ef2c719dfb6a81fa6cecf7939230 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 10:35:59 +0100 Subject: [PATCH 08/15] Go: Update dependencies to those released with 2.19.3. --- go/lib/codeql-pack.lock.yml | 16 +++++++++------- go/src/codeql-pack.lock.yml | 16 +++++++++------- go/test/codeql-pack.lock.yml | 16 +++++++++------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/go/lib/codeql-pack.lock.yml b/go/lib/codeql-pack.lock.yml index fc39297c..8cba7a72 100644 --- a/go/lib/codeql-pack.lock.yml +++ b/go/lib/codeql-pack.lock.yml @@ -2,17 +2,19 @@ lockVersion: 1.0.0 dependencies: codeql/dataflow: - version: 0.2.7 + version: 1.1.5 codeql/go-all: - version: 0.8.1 + version: 2.1.2 codeql/mad: - version: 0.2.16 + version: 1.0.11 codeql/ssa: - version: 0.2.16 + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.2.16 + version: 1.0.11 codeql/typetracking: - version: 0.2.16 + version: 1.0.11 codeql/util: - version: 0.2.16 + version: 1.0.11 compiled: false diff --git a/go/src/codeql-pack.lock.yml b/go/src/codeql-pack.lock.yml index fc39297c..8cba7a72 100644 --- a/go/src/codeql-pack.lock.yml +++ b/go/src/codeql-pack.lock.yml @@ -2,17 +2,19 @@ lockVersion: 1.0.0 dependencies: codeql/dataflow: - version: 0.2.7 + version: 1.1.5 codeql/go-all: - version: 0.8.1 + version: 2.1.2 codeql/mad: - version: 0.2.16 + version: 1.0.11 codeql/ssa: - version: 0.2.16 + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.2.16 + version: 1.0.11 codeql/typetracking: - version: 0.2.16 + version: 1.0.11 codeql/util: - version: 0.2.16 + version: 1.0.11 compiled: false diff --git a/go/test/codeql-pack.lock.yml b/go/test/codeql-pack.lock.yml index fc39297c..8cba7a72 100644 --- a/go/test/codeql-pack.lock.yml +++ b/go/test/codeql-pack.lock.yml @@ -2,17 +2,19 @@ lockVersion: 1.0.0 dependencies: codeql/dataflow: - version: 0.2.7 + version: 1.1.5 codeql/go-all: - version: 0.8.1 + version: 2.1.2 codeql/mad: - version: 0.2.16 + version: 1.0.11 codeql/ssa: - version: 0.2.16 + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.2.16 + version: 1.0.11 codeql/typetracking: - version: 0.2.16 + version: 1.0.11 codeql/util: - version: 0.2.16 + version: 1.0.11 compiled: false From 55b0ea3fdfbab09582b7eafd6583c34d5f7f3107 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 14:22:23 +0100 Subject: [PATCH 09/15] Go: Update test expected output. --- go/test/security/CWE-078/cmdi.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/test/security/CWE-078/cmdi.expected b/go/test/security/CWE-078/cmdi.expected index 95f35dec..d0b7289a 100644 --- a/go/test/security/CWE-078/cmdi.expected +++ b/go/test/security/CWE-078/cmdi.expected @@ -1,6 +1,6 @@ edges -| main.go:20:14:20:20 | selection of URL | main.go:20:14:20:28 | call to Query | provenance | MaD:732 | -| main.go:20:14:20:28 | call to Query | main.go:27:22:27:28 | cmdName | provenance | | +| main.go:20:14:20:20 | selection of URL | main.go:20:14:20:28 | call to Query | provenance | Src:MaD:1004 MaD:1065 | +| main.go:20:14:20:28 | call to Query | main.go:27:22:27:28 | cmdName | provenance | Sink:MaD:1075 | nodes | main.go:20:14:20:20 | selection of URL | semmle.label | selection of URL | | main.go:20:14:20:28 | call to Query | semmle.label | call to Query | From e68db587dfba40c2ae7dc33f12299d9a7fad2f99 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 10:48:17 +0100 Subject: [PATCH 10/15] Javascript: Update dependencies to those released with 2.19.3. --- javascript/lib/codeql-pack.lock.yml | 22 ++++++++++++++++------ javascript/src/codeql-pack.lock.yml | 22 ++++++++++++++++------ javascript/test/codeql-pack.lock.yml | 22 ++++++++++++++++------ 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/javascript/lib/codeql-pack.lock.yml b/javascript/lib/codeql-pack.lock.yml index 3dc9477b..8dfea924 100644 --- a/javascript/lib/codeql-pack.lock.yml +++ b/javascript/lib/codeql-pack.lock.yml @@ -1,16 +1,26 @@ --- lockVersion: 1.0.0 dependencies: + codeql/dataflow: + version: 1.1.5 codeql/javascript-all: - version: 0.7.4 + version: 2.1.0 codeql/mad: - version: 0.1.4 + version: 1.0.11 codeql/regex: - version: 0.1.4 + version: 1.0.11 + codeql/ssa: + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 + codeql/xml: + version: 1.0.11 codeql/yaml: - version: 0.1.4 + version: 1.0.11 compiled: false diff --git a/javascript/src/codeql-pack.lock.yml b/javascript/src/codeql-pack.lock.yml index 3dc9477b..8dfea924 100644 --- a/javascript/src/codeql-pack.lock.yml +++ b/javascript/src/codeql-pack.lock.yml @@ -1,16 +1,26 @@ --- lockVersion: 1.0.0 dependencies: + codeql/dataflow: + version: 1.1.5 codeql/javascript-all: - version: 0.7.4 + version: 2.1.0 codeql/mad: - version: 0.1.4 + version: 1.0.11 codeql/regex: - version: 0.1.4 + version: 1.0.11 + codeql/ssa: + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 + codeql/xml: + version: 1.0.11 codeql/yaml: - version: 0.1.4 + version: 1.0.11 compiled: false diff --git a/javascript/test/codeql-pack.lock.yml b/javascript/test/codeql-pack.lock.yml index 3dc9477b..8dfea924 100644 --- a/javascript/test/codeql-pack.lock.yml +++ b/javascript/test/codeql-pack.lock.yml @@ -1,16 +1,26 @@ --- lockVersion: 1.0.0 dependencies: + codeql/dataflow: + version: 1.1.5 codeql/javascript-all: - version: 0.7.4 + version: 2.1.0 codeql/mad: - version: 0.1.4 + version: 1.0.11 codeql/regex: - version: 0.1.4 + version: 1.0.11 + codeql/ssa: + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 + codeql/xml: + version: 1.0.11 codeql/yaml: - version: 0.1.4 + version: 1.0.11 compiled: false From b91665881628addbb4b9c6ace87455f9d24343c5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 10:58:13 +0100 Subject: [PATCH 11/15] Python: Update dependencies to those released with 2.19.3. --- python/lib/codeql-pack.lock.yml | 22 +++++++++++++--------- python/src/codeql-pack.lock.yml | 22 +++++++++++++--------- python/test/codeql-pack.lock.yml | 26 +++++++++++++++----------- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/python/lib/codeql-pack.lock.yml b/python/lib/codeql-pack.lock.yml index ad530a80..045b0867 100644 --- a/python/lib/codeql-pack.lock.yml +++ b/python/lib/codeql-pack.lock.yml @@ -2,21 +2,25 @@ lockVersion: 1.0.0 dependencies: codeql/dataflow: - version: 0.1.5 + version: 1.1.5 codeql/mad: - version: 0.2.5 + version: 1.0.11 codeql/python-all: - version: 0.11.5 + version: 2.1.2 codeql/regex: - version: 0.2.5 + version: 1.0.11 codeql/ssa: - version: 0.2.5 + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.2.5 + version: 1.0.11 codeql/typetracking: - version: 0.2.5 + version: 1.0.11 codeql/util: - version: 0.2.5 + version: 1.0.11 + codeql/xml: + version: 1.0.11 codeql/yaml: - version: 0.2.5 + version: 1.0.11 compiled: false diff --git a/python/src/codeql-pack.lock.yml b/python/src/codeql-pack.lock.yml index ad530a80..045b0867 100644 --- a/python/src/codeql-pack.lock.yml +++ b/python/src/codeql-pack.lock.yml @@ -2,21 +2,25 @@ lockVersion: 1.0.0 dependencies: codeql/dataflow: - version: 0.1.5 + version: 1.1.5 codeql/mad: - version: 0.2.5 + version: 1.0.11 codeql/python-all: - version: 0.11.5 + version: 2.1.2 codeql/regex: - version: 0.2.5 + version: 1.0.11 codeql/ssa: - version: 0.2.5 + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.2.5 + version: 1.0.11 codeql/typetracking: - version: 0.2.5 + version: 1.0.11 codeql/util: - version: 0.2.5 + version: 1.0.11 + codeql/xml: + version: 1.0.11 codeql/yaml: - version: 0.2.5 + version: 1.0.11 compiled: false diff --git a/python/test/codeql-pack.lock.yml b/python/test/codeql-pack.lock.yml index 26dc953c..8f985b93 100644 --- a/python/test/codeql-pack.lock.yml +++ b/python/test/codeql-pack.lock.yml @@ -2,25 +2,29 @@ lockVersion: 1.0.0 dependencies: codeql/dataflow: - version: 0.1.5 + version: 1.1.5 codeql/mad: - version: 0.2.5 + version: 1.0.11 codeql/python-all: - version: 0.11.5 + version: 2.1.2 codeql/python-queries: - version: 0.9.5 + version: 1.3.2 codeql/regex: - version: 0.2.5 + version: 1.0.11 codeql/ssa: - version: 0.2.5 + version: 1.0.11 codeql/suite-helpers: - version: 0.7.5 + version: 1.0.11 + codeql/threat-models: + version: 1.0.11 codeql/tutorial: - version: 0.2.5 + version: 1.0.11 codeql/typetracking: - version: 0.2.5 + version: 1.0.11 codeql/util: - version: 0.2.5 + version: 1.0.11 + codeql/xml: + version: 1.0.11 codeql/yaml: - version: 0.2.5 + version: 1.0.11 compiled: false From 887df47fbf9d9cb5b83396053867f5781c045381 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 13:02:15 +0100 Subject: [PATCH 12/15] Python: Update queries to be compatible with the new dependencies. --- python/lib/ghsl/DefaultPasswordDB.qll | 61 ++++++------- python/lib/ghsl/HardcodedSecretSinks.qll | 5 +- python/lib/ghsl/InsecurelyStoredPassword.qll | 50 +++++----- python/lib/ghsl/LocalSources.qll | 90 ++++++++++++------ python/lib/ghsl/MassAssignment.qll | 35 ++++--- python/lib/ghsl/XMLLocalLib.qll | 91 +++++++++---------- .../audit/CWE-089/SqlInjectionHeuristic.ql | 18 ++-- python/src/audit/CWE-502/XMLLocalFileAudit.ql | 2 +- .../src/security/CWE-089/SqlInjectionLocal.ql | 20 ++-- python/src/security/CWE-133/format_string.ql | 8 +- python/src/security/CWE-133/format_string.qll | 40 ++++---- .../CWE-502/UnsafeDeserializationLocal.ql | 20 ++-- .../src/security/CWE-502/XMLLocalFileTaint.ql | 6 +- .../security/CWE-502/XMLLocalStringTaint.ql | 7 +- .../CWE-798/HardcodedFrameworkSecrets.ql | 18 ++-- python/src/security/CWE-915/MassAssignment.ql | 8 +- .../security/CWE-915/MassAssignmentLocal.ql | 10 +- .../CWE-915/MassAssignmentLocalProblem.ql | 5 +- .../security/CWE-915/MassAssignmentProblem.ql | 5 +- 19 files changed, 257 insertions(+), 242 deletions(-) diff --git a/python/lib/ghsl/DefaultPasswordDB.qll b/python/lib/ghsl/DefaultPasswordDB.qll index 75f41a81..fd70bb1a 100644 --- a/python/lib/ghsl/DefaultPasswordDB.qll +++ b/python/lib/ghsl/DefaultPasswordDB.qll @@ -1,43 +1,38 @@ private import python // password = db.Column(..., server_default=...) - class DBColumn extends Call { - CallNode call; - string name; - ControlFlowNode object; - Name var; - string id; + CallNode call; + string name; + ControlFlowNode object; + Name var; + string id; - DBColumn() { - call.getFunction().(AttrNode).getObject(name) = object - and name = "Column" - and call = this.getAFlowNode() - and object.getNode() = var.getVariable().getAnAccess() - and var.getId() = id - } + DBColumn() { + call.getFunction().(AttrNode).getObject(name) = object and + name = "Column" and + call = this.getAFlowNode() and + object.getNode() = var.getVariable().getAnAccess() and + var.getId() = id + } - string getDbId() { - result = id - } + string getDbId() { result = id } - predicate hasStaticDefault() { - exists(DictItem arg | - arg = call.getNode().getANamedArg() - and arg.(Keyword).getArg() in ["server_default", "default"] - and arg.(Keyword).getValue() instanceof ImmutableLiteral - ) - } + predicate hasStaticDefault() { + exists(DictItem arg | + arg = call.getNode().getANamedArg() and + arg.(Keyword).getArg() in ["server_default", "default"] and + arg.(Keyword).getValue() instanceof ImmutableLiteral + ) + } - string assignedToVariable() { - exists(AssignStmt assign, Variable v| - assign.defines(v) - and v.getId() = result - and assign.getValue() = this - ) - } + string assignedToVariable() { + exists(AssignStmt assign, Variable v | + assign.defines(v) and + v.getId() = result and + assign.getValue() = this + ) + } - string getColumnName() { - result = call.getNode().getArg(0).(StrConst).getText() - } + string getColumnName() { result = call.getNode().getArg(0).(StringLiteral).getText() } } diff --git a/python/lib/ghsl/HardcodedSecretSinks.qll b/python/lib/ghsl/HardcodedSecretSinks.qll index 6540a474..91ca3cc0 100644 --- a/python/lib/ghsl/HardcodedSecretSinks.qll +++ b/python/lib/ghsl/HardcodedSecretSinks.qll @@ -5,7 +5,6 @@ private import semmle.python.Concepts private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.ApiGraphs -private import DataFlow::PathGraph private import semmle.python.frameworks.Flask abstract class CredentialSink extends DataFlow::Node { } @@ -14,7 +13,7 @@ Expr getDictValueByKey(Dict dict, string key) { exists(KeyValuePair item | // d = {KEY: VALUE} item = dict.getAnItem() and - key = item.getKey().(StrConst).getS() and + key = item.getKey().(StringLiteral).getS() and result = item.getValue() ) } @@ -25,7 +24,7 @@ Expr getAssignStmtByKey(AssignStmt assign, string key) { sub = assign.getASubExpression() and // Make sure the keys match // TODO: What happens if this value itself is not static? - key = sub.getASubExpression().(StrConst).getS() and + key = sub.getASubExpression().(StringLiteral).getS() and // TODO: Only supports static strings, resolve the value?? // result = assign.getASubExpression().(StrConst) result = sub.getValue() diff --git a/python/lib/ghsl/InsecurelyStoredPassword.qll b/python/lib/ghsl/InsecurelyStoredPassword.qll index fb167d0e..c89f3ccb 100644 --- a/python/lib/ghsl/InsecurelyStoredPassword.qll +++ b/python/lib/ghsl/InsecurelyStoredPassword.qll @@ -57,16 +57,16 @@ class User extends ClassDef { predicate hasSecureInit() { this.hasInit() and - not exists(InsecureHashTrackingConfiguration conf, DataFlow::Node source, DataFlow::Node sink | + not exists(DataFlow::Node source, DataFlow::Node sink | this.inInit(sink) and this.isPasswordArg(source) and - conf.hasFlow(source, sink) + InsecureHashTaint::flow(source, sink) ) } predicate usedSecurely() { - not exists(InsecureTaintTrackingConfiguration conf, DataFlow::Node source, DataFlow::Node sink | - conf.hasFlow(source, sink) and + not exists(DataFlow::Node source, DataFlow::Node sink | + InsecurelyStoredPasswordTaint::flow(source, sink) and sink.(PasswordArg).getUser() = this ) } @@ -78,15 +78,13 @@ class User extends ClassDef { } } -class InsecureTaintTrackingConfiguration extends TaintTracking::Configuration { - // is the password used in the init of the User protected by a secure hash? - InsecureTaintTrackingConfiguration() { this = "InsecureTaintTrackingConfiguration" } +// is the password used in the init of the User protected by a secure hash? +module InsecurelyStoredPasswordTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSink(DataFlow::Node sink) { sink instanceof PasswordArg } - override predicate isSink(DataFlow::Node sink) { sink instanceof PasswordArg } - - override predicate isAdditionalTaintStep(DataFlow::Node a, DataFlow::Node b) { + predicate isAdditionalFlowStep(DataFlow::Node a, DataFlow::Node b) { // from a dict key to the dict, if the key is "password" exists(Dict dict, KeyValuePair pair | dict.getAnItem() = pair and @@ -96,25 +94,25 @@ class InsecureTaintTrackingConfiguration extends TaintTracking::Configuration { ) } - override predicate isSanitizer(DataFlow::Node node) { node instanceof HashSanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof HashSanitizer } } -class InsecureHashTrackingConfiguration extends TaintTracking::Configuration { - User user; - - // does the body of the init of the User hash the password? - InsecureHashTrackingConfiguration() { this = "InsecureHashTrackingConfiguration" } +module InsecurelyStoredPasswordTaint = TaintTracking::Global; - override predicate isSource(DataFlow::Node source) { user.isPasswordArg(source) } +// does the body of the init of the User hash the password? +module InsecureHashTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { any(User x).isPasswordArg(source) } - override predicate isSink(DataFlow::Node sink) { - user.passwordAssignedFrom(sink) and + predicate isSink(DataFlow::Node sink) { + any(User x).passwordAssignedFrom(sink) and not sink instanceof HashSanitizer } - override predicate isSanitizer(DataFlow::Node node) { node instanceof HashSanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof HashSanitizer } } +module InsecureHashTaint = TaintTracking::Global; + // assigment to self.password class SelfPasswordAttribute extends DataFlow::Node { Variable self; @@ -204,8 +202,8 @@ private import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowD /** Holds if the `call` is a call to the function `target`. */ private predicate resolveCall(CallNode call, Function target) { - // TODO: This should be exposed better from the standard library API - DataFlowDispatch::resolveCall(call, target, _) + // TODO: This should be exposed better from the standard library API + DataFlowDispatch::resolveCall(call, target, _) } /** @@ -219,9 +217,9 @@ private predicate resolveCall(CallNode call, Function target) { class HashSanitizerWrapperFunction extends HashSanitizer { HashSanitizerWrapperFunction() { exists(CallNode hashCall, Function hashWrapper | - hashWrapper.contains(any(HashSanitizerConcrete hsc).asExpr()) and - resolveCall(hashCall, hashWrapper) and - this.asCfgNode() = hashCall.getArg(0) + hashWrapper.contains(any(HashSanitizerConcrete hsc).asExpr()) and + resolveCall(hashCall, hashWrapper) and + this.asCfgNode() = hashCall.getArg(0) ) } } diff --git a/python/lib/ghsl/LocalSources.qll b/python/lib/ghsl/LocalSources.qll index dcbd8ba2..57a45132 100644 --- a/python/lib/ghsl/LocalSources.qll +++ b/python/lib/ghsl/LocalSources.qll @@ -7,7 +7,6 @@ module LocalSources { private import semmle.python.Concepts private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.ApiGraphs - private import DataFlow::PathGraph abstract class Range extends DataFlow::Node { } @@ -95,18 +94,26 @@ module LocalSources { call = API::moduleImport(["json", "simplejson"]).getMember("load").getACall() or // yaml.load - call = API::moduleImport("yaml").getMember(["load", "load_all", "safe_load", "safe_load_all"]).getACall() + call = + API::moduleImport("yaml") + .getMember(["load", "load_all", "safe_load", "safe_load_all"]) + .getACall() or // msgpack.load call = API::moduleImport("msgpack").getMember("load").getACall() or // pickle.load // dill.load - call = API::moduleImport(["cPickle", "_pickle", "pickle", "dill"]).getMember("load").getACall() + call = + API::moduleImport(["cPickle", "_pickle", "pickle", "dill"]).getMember("load").getACall() or // pickle.Unpickler.load // dill.Unpickler.load - call = API::moduleImport(["cPickle", "pickle", "dill"]).getMember("Unpickler").getACall().getAMethodCall("load") + call = + API::moduleImport(["cPickle", "pickle", "dill"]) + .getMember("Unpickler") + .getACall() + .getAMethodCall("load") or // shelve.open call = API::moduleImport("shelve").getMember("open").getACall() @@ -137,19 +144,18 @@ module LocalSources { // pandas.read_gbq // pandas.read_stata // generate call expressions for each of the above pandas functions including ExcelFile.parse and HDFStore.* that have to be handled separately - call = API::moduleImport("pandas") - .getMember([ - "read_csv", "read_fwf", "read_excel", "read_json", "read_html", "read_xml", - "read_hdf", "read_feather", "read_parquet", "read_orc", "read_sas", "read_spss", "read_sql_table", - "read_sql_query", "read_sql", "read_gbq", "read_stata" - ]) - .getACall() + call = + API::moduleImport("pandas") + .getMember([ + "read_csv", "read_fwf", "read_excel", "read_json", "read_html", "read_xml", + "read_hdf", "read_feather", "read_parquet", "read_orc", "read_sas", "read_spss", + "read_sql_table", "read_sql_query", "read_sql", "read_gbq", "read_stata" + ]) + .getACall() or // pandas.ExcelFile.parse - call = API::moduleImport("pandas") - .getMember("ExcelFile") - .getACall() - .getAMethodCall("parse") + call = + API::moduleImport("pandas").getMember("ExcelFile").getACall().getAMethodCall("parse") or // pandas.HDFStore.get // pandas.HDFStore.select @@ -157,25 +163,38 @@ module LocalSources { // pandas.HDFStore.keys // pandas.HDFStore.groups // pandas.HDFStore.walk - call = API::moduleImport("pandas") - .getMember("HDFStore") - .getACall() - .getAMethodCall(["get", "select", "info", "keys", "groups", "walk"]) + call = + API::moduleImport("pandas") + .getMember("HDFStore") + .getACall() + .getAMethodCall(["get", "select", "info", "keys", "groups", "walk"]) or // polars.read_csv - call = API::moduleImport("polars").getMember(["read_csv", "read_csv_batched", "scan_csv"]).getACall() + call = + API::moduleImport("polars") + .getMember(["read_csv", "read_csv_batched", "scan_csv"]) + .getACall() or // polars.read_ipc - call = API::moduleImport("polars").getMember(["read_ipc", "scan_ipc", "read_ipc_schema"]).getACall() + call = + API::moduleImport("polars") + .getMember(["read_ipc", "scan_ipc", "read_ipc_schema"]) + .getACall() or // polars.read_parquet, polars.scan_parquet, polars.read_parquet_schema - call = API::moduleImport("polars").getMember(["read_parquet", "scan_parquet", "read_parquet_schema"]).getACall() + call = + API::moduleImport("polars") + .getMember(["read_parquet", "scan_parquet", "read_parquet_schema"]) + .getACall() or // polars.read_sql call = API::moduleImport("polars").getMember("read_sql").getACall() or // polars.read_json, polars.read_ndjson, polars.scan_ndjson - call = API::moduleImport("polars").getMember(["read_json", "read_ndjson", "scan_ndjson"]).getACall() + call = + API::moduleImport("polars") + .getMember(["read_json", "read_ndjson", "scan_ndjson"]) + .getACall() or // polars.read_avro call = API::moduleImport("polars").getMember("read_avro").getACall() @@ -186,24 +205,37 @@ module LocalSources { // pyarrow.csv.read_csv // pyarrow.csv.open_csv // pyarrow.csv.CSVStreamingReader - call = API::moduleImport("pyarrow").getMember("csv").getMember(["read_csv", "open_csv", "CSVStreamingReader"]).getACall() + call = + API::moduleImport("pyarrow") + .getMember("csv") + .getMember(["read_csv", "open_csv", "CSVStreamingReader"]) + .getACall() or // pyarrow.feather.read_feather // pyarrow.feather.read_table - call = API::moduleImport("pyarrow").getMember("feather").getMember(["read_feather", "read_table"]).getACall() + call = + API::moduleImport("pyarrow") + .getMember("feather") + .getMember(["read_feather", "read_table"]) + .getACall() or // pyarrow.json.read_json call = API::moduleImport("pyarrow").getMember("json").getMember("read_json").getACall() + or // pyarrow.parquet.ParquetDataset // pyarrow.parquet.ParquetFile // pyarrow.parquet.read_table // pyarrow.parquet.read_metadata // pyarrow.parquet.read_pandas // pyarrow.parquet.read_schema - or - call = API::moduleImport("pyarrow").getMember("parquet").getMember([ - "ParquetDataset", "ParquetFile", "read_table", "read_metadata", "read_pandas", "read_schema" - ]).getACall() + call = + API::moduleImport("pyarrow") + .getMember("parquet") + .getMember([ + "ParquetDataset", "ParquetFile", "read_table", "read_metadata", "read_pandas", + "read_schema" + ]) + .getACall() ) and this = call ) and diff --git a/python/lib/ghsl/MassAssignment.qll b/python/lib/ghsl/MassAssignment.qll index 95c7494e..5d8f1836 100644 --- a/python/lib/ghsl/MassAssignment.qll +++ b/python/lib/ghsl/MassAssignment.qll @@ -32,24 +32,23 @@ module MassAssignment { } } - class MassAssignmentLocalConfig extends TaintTracking::Configuration { - MassAssignmentLocalConfig() { this = "Mass Assignment Config" } - - override predicate isSource(DataFlow::Node source) { source instanceof LocalSources::Range } - - override predicate isSink(DataFlow::Node sink) { sink instanceof MassAssignment::Sinks } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof MassAssignment::Sanitizer } + private module MassAssignmentLocalTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof LocalSources::Range } + + predicate isSink(DataFlow::Node sink) { sink instanceof MassAssignment::Sinks } + + predicate isBarrier(DataFlow::Node node) { node instanceof MassAssignment::Sanitizer } } - - class MassAssignmentConfig extends TaintTracking::Configuration { - MassAssignmentConfig() { this = "Mass Assignment Config" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource::Range } - - override predicate isSink(DataFlow::Node sink) { sink instanceof MassAssignment::Sinks } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof MassAssignment::Sanitizer } + + module MassAssignmentLocalTaint = TaintTracking::Global; + + private module MassAssignmentTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource::Range } + + predicate isSink(DataFlow::Node sink) { sink instanceof MassAssignment::Sinks } + + predicate isBarrier(DataFlow::Node node) { node instanceof MassAssignment::Sanitizer } } - + + module MassAssignmentTaint = TaintTracking::Global; } diff --git a/python/lib/ghsl/XMLLocalLib.qll b/python/lib/ghsl/XMLLocalLib.qll index bed0f860..20949615 100644 --- a/python/lib/ghsl/XMLLocalLib.qll +++ b/python/lib/ghsl/XMLLocalLib.qll @@ -5,101 +5,100 @@ private import semmle.python.Concepts private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.dataflow.new.BarrierGuards private import semmle.python.ApiGraphs - private import ghsl.LocalSources class XmlParseStringCall extends DataFlow::CallCfgNode { XmlParseStringCall() { - this = API::moduleImport(["xml.etree.ElementTree", "xml.etree.cElementTree"]).getMember("fromString").getACall() or + this = + API::moduleImport(["xml.etree.ElementTree", "xml.etree.cElementTree"]) + .getMember("fromString") + .getACall() or this = API::moduleImport(["xml.dom.minidom", "xml.sax"]).getMember("parseString").getACall() or - this = API::moduleImport("xml.sax").getMember("parseStringIO").getACall() - or + this = API::moduleImport("xml.sax").getMember("parseStringIO").getACall() or this.asCfgNode() = xmlParseStringCall() } - DataFlow::Node getSink() { result = this.getArg(0) } + DataFlow::Node getSink() { result = this.getArg(0) } } class XmlParseFileCall extends DataFlow::CallCfgNode { XmlParseFileCall() { - this = API::moduleImport(["xml.etree.ElementTree", "xml.etree.cElementTree", "xml.dom.minidom", "xml.dom.pulldom", "xml.sax"]).getMember("parse").getACall() or - this = API::moduleImport(["xml.etree.ElementTree", "xml.etree.cElementTree"]).getMember("iterparse").getACall() - or + this = + API::moduleImport([ + "xml.etree.ElementTree", "xml.etree.cElementTree", "xml.dom.minidom", "xml.dom.pulldom", + "xml.sax" + ]).getMember("parse").getACall() or + this = + API::moduleImport(["xml.etree.ElementTree", "xml.etree.cElementTree"]) + .getMember("iterparse") + .getACall() or this.asCfgNode() = xmlParseFileCall() } - DataFlow::Node getSink() { result = this.getArg(0) } + DataFlow::Node getSink() { result = this.getArg(0) } DataFlow::Node getSource() { result = this.getArg(0) } } ControlFlowNode xmlParseFileCall() { - exists(string method_name, string package_name| - result = callFromPackage(method_name, package_name) - and ( - (method_name = "parse" and package_name in ["ElementTree", "cElementTree", "minidom", "pulldom", "sax"]) + exists(string method_name, string package_name | + result = callFromPackage(method_name, package_name) and + ( + method_name = "parse" and + package_name in ["ElementTree", "cElementTree", "minidom", "pulldom", "sax"] or - (method_name = "interparse" and package_name in ["ElementTree", "cElementTree"]) + method_name = "interparse" and package_name in ["ElementTree", "cElementTree"] ) ) } ControlFlowNode xmlParseStringCall() { - exists(string method_name, string package_name| - result = callFromPackage(method_name, package_name) - and ( - (method_name = "parseString" and package_name in ["minidom","sax"]) + exists(string method_name, string package_name | + result = callFromPackage(method_name, package_name) and + ( + method_name = "parseString" and package_name in ["minidom", "sax"] or - (method_name = "parseStringIO" and package_name in ["sax"]) + method_name = "parseStringIO" and package_name in ["sax"] or - (method_name = "fromString" and package_name in ["ElementTree", "cElementTree"]) + method_name = "fromString" and package_name in ["ElementTree", "cElementTree"] ) ) } ControlFlowNode callFromPackage(string method_name, string package_name) { exists(Attribute called_attr, Attribute object | - result.isCall() and called_attr.getParent() = result.getNode() and - called_attr.getName() = method_name - and called_attr.getObject() = object - and object.getName() = package_name + result.isCall() and + called_attr.getParent() = result.getNode() and + called_attr.getName() = method_name and + called_attr.getObject() = object and + object.getName() = package_name ) } class LocalUserInput extends DataFlow::Node { - LocalUserInput() { - this instanceof LocalSources::Range - } + LocalUserInput() { this instanceof LocalSources::Range } } class UnsafeStringXmlSink extends DataFlow::ExprNode { - UnsafeStringXmlSink() { - exists(XmlParseStringCall parse | - parse.getSink() = this - ) - } + UnsafeStringXmlSink() { exists(XmlParseStringCall parse | parse.getSink() = this) } } class UnsafeFileXmlSink extends DataFlow::ExprNode { - UnsafeFileXmlSink() { - exists(XmlParseFileCall parse | - parse.getSink() = this - ) - } + UnsafeFileXmlSink() { exists(XmlParseFileCall parse | parse.getSink() = this) } } -class XmlStringConfig extends TaintTracking::Configuration { - XmlStringConfig() { this = "XMLLocal::XmlStringConfig" } +private module XmlStringTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } - override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } - - override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeStringXmlSink } + predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeStringXmlSink } } -class XmlFileConfig extends TaintTracking::Configuration { - XmlFileConfig() { this = "XMLLocal::XmlFileConfig" } +module XmlStringTaint = TaintTracking::Global; - override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } +private module XmlFileTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } - override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeFileXmlSink } + predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeFileXmlSink } } + +module XmlFileTaint = TaintTracking::Global; diff --git a/python/src/audit/CWE-089/SqlInjectionHeuristic.ql b/python/src/audit/CWE-089/SqlInjectionHeuristic.ql index 91427874..a24c0cfa 100644 --- a/python/src/audit/CWE-089/SqlInjectionHeuristic.ql +++ b/python/src/audit/CWE-089/SqlInjectionHeuristic.ql @@ -19,8 +19,8 @@ import semmle.python.dataflow.new.TaintTracking import semmle.python.Concepts import semmle.python.dataflow.new.BarrierGuards import semmle.python.ApiGraphs -import DataFlow::PathGraph private import semmle.python.security.dataflow.SqlInjectionCustomizations +import SqlInjectionHeuristicTaint::PathGraph class DatabaseExtentions extends DataFlow::Node { DatabaseExtentions() { @@ -35,17 +35,17 @@ class DatabaseExtentions extends DataFlow::Node { /** * A taint-tracking configuration for detecting SQL injection vulnerabilities. */ -class SqlInjectionHeuristic extends TaintTracking::Configuration { - SqlInjectionHeuristic() { this = "SqlInjectionHeuristic" } +module SqlInjectionHeuristicTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source } - override predicate isSource(DataFlow::Node source) { source instanceof SqlInjection::Source } + predicate isSink(DataFlow::Node sink) { sink instanceof DatabaseExtentions } - override predicate isSink(DataFlow::Node sink) { sink instanceof DatabaseExtentions } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer } } -from SqlInjectionHeuristic config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +module SqlInjectionHeuristicTaint = TaintTracking::Global; + +from SqlInjectionHeuristicTaint::PathNode source, SqlInjectionHeuristicTaint::PathNode sink +where SqlInjectionHeuristicTaint::flowPath(source, sink) select sink.getNode(), source, sink, "This SQL query depends on $@.", source.getNode(), "a user-provided value" diff --git a/python/src/audit/CWE-502/XMLLocalFileAudit.ql b/python/src/audit/CWE-502/XMLLocalFileAudit.ql index 1ea91539..ee74d59a 100644 --- a/python/src/audit/CWE-502/XMLLocalFileAudit.ql +++ b/python/src/audit/CWE-502/XMLLocalFileAudit.ql @@ -25,4 +25,4 @@ where sink = call ) select sink, "Unsafe parsing of XML from fixed file name $@.", source, - source.asExpr().(StrConst).getLiteralValue().toString() + source.asExpr().(StringLiteral).getLiteralValue().toString() diff --git a/python/src/security/CWE-089/SqlInjectionLocal.ql b/python/src/security/CWE-089/SqlInjectionLocal.ql index 67afb885..5e4cf697 100644 --- a/python/src/security/CWE-089/SqlInjectionLocal.ql +++ b/python/src/security/CWE-089/SqlInjectionLocal.ql @@ -19,24 +19,24 @@ import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.Concepts import semmle.python.dataflow.new.BarrierGuards -import DataFlow::PathGraph import ghsl.LocalSources private import semmle.python.security.dataflow.SqlInjectionCustomizations +import SqlInjectionTaint::PathGraph /** - * A taint-tracking configuration for detecting SQL injection vulnerabilities. + * A configuration for detecting SQL injection vulnerabilities. */ -class SQLInjectionConfiguration extends TaintTracking::Configuration { - SQLInjectionConfiguration() { this = "LocalSQLInjectionConfiguration" } +module SQLInjectionTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof LocalSources::Range } - override predicate isSource(DataFlow::Node source) { source instanceof LocalSources::Range } + predicate isSink(DataFlow::Node sink) { sink instanceof SqlInjection::Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof SqlInjection::Sink } - - override predicate isSanitizer(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer } + predicate isBarrier(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer } } -from SQLInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +module SqlInjectionTaint = TaintTracking::Global; + +from SqlInjectionTaint::PathNode source, SqlInjectionTaint::PathNode sink +where SqlInjectionTaint::flowPath(source, sink) select sink.getNode(), source, sink, "This SQL query depends on $@.", source.getNode(), "a user-provided value" diff --git a/python/src/security/CWE-133/format_string.ql b/python/src/security/CWE-133/format_string.ql index 6bb0644b..bd09d7b0 100644 --- a/python/src/security/CWE-133/format_string.ql +++ b/python/src/security/CWE-133/format_string.ql @@ -14,12 +14,10 @@ private import python private import semmle.python.dataflow.new.DataFlow -private import DataFlow::PathGraph private import format_string +import FormatStringTaint::PathGraph -from - DataFlow::PathNode userdata, DataFlow::PathNode format_string, - FormatStringTaintConfiguration format_string_config -where format_string_config.hasFlowPath(userdata, format_string) +from FormatStringTaint::PathNode userdata, FormatStringTaint::PathNode format_string +where FormatStringTaint::flowPath(userdata, format_string) select format_string.getNode(), userdata, format_string, "$@ used as format string: $@.", userdata.getNode(), "Untrusted data", format_string, format_string.getNode().asExpr().toString() diff --git a/python/src/security/CWE-133/format_string.qll b/python/src/security/CWE-133/format_string.qll index f0503e17..ff5f8e2b 100644 --- a/python/src/security/CWE-133/format_string.qll +++ b/python/src/security/CWE-133/format_string.qll @@ -1,31 +1,29 @@ private import python - private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.RemoteFlowSources - private import ghsl.LocalSources -class FormatStringTaintConfiguration extends TaintTracking::Configuration { - FormatStringTaintConfiguration() { this = "FormatStringTaintConfiguration" } - - override predicate isSource(DataFlow::Node source) { - source instanceof RemoteFlowSource - or - source instanceof LocalSources::Range - } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof FormatString - and not sink.asExpr() instanceof StrConst - } +private module FormatStringTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source instanceof RemoteFlowSource + or + source instanceof LocalSources::Range + } + + predicate isSink(DataFlow::Node sink) { + sink instanceof FormatString and + not sink.asExpr() instanceof StringLiteral + } } +module FormatStringTaint = TaintTracking::Global; + class FormatString extends DataFlow::Node { - FormatString() { - exists(CallNode call | - call.getFunction().(AttrNode).getName() = "format" - and call.getFunction().(AttrNode).getObject() = this.asCfgNode() - ) - } + FormatString() { + exists(CallNode call | + call.getFunction().(AttrNode).getName() = "format" and + call.getFunction().(AttrNode).getObject() = this.asCfgNode() + ) + } } diff --git a/python/src/security/CWE-502/UnsafeDeserializationLocal.ql b/python/src/security/CWE-502/UnsafeDeserializationLocal.ql index 62daa7ba..cda6dd53 100644 --- a/python/src/security/CWE-502/UnsafeDeserializationLocal.ql +++ b/python/src/security/CWE-502/UnsafeDeserializationLocal.ql @@ -20,28 +20,26 @@ import semmle.python.Concepts import semmle.python.dataflow.new.RemoteFlowSources import semmle.python.dataflow.new.BarrierGuards import semmle.python.ApiGraphs -import DataFlow::PathGraph // Extending library import semmle.python.security.dataflow.UnsafeDeserializationCustomizations // Internal library import ghsl.LocalSources +import UnsafeDeserializationLocal::PathGraph /** * A taint-tracking configuration for detecting arbitrary code execution * vulnerabilities due to deserializing user-controlled data. */ -class UnsafeDeserializationConfiguration extends TaintTracking::Configuration { - UnsafeDeserializationConfiguration() { this = "UnsafeDeserializationConfiguration" } +module UnsafeDeserializationLocalTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof LocalSources::Range } - override predicate isSource(DataFlow::Node source) { source instanceof LocalSources::Range } + predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink } - override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserialization::Sink } - - override predicate isSanitizer(DataFlow::Node node) { - node instanceof UnsafeDeserialization::Sanitizer - } + predicate isBarrier(DataFlow::Node node) { node instanceof UnsafeDeserialization::Sanitizer } } -from UnsafeDeserializationConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +module UnsafeDeserializationLocal = TaintTracking::Global; + +from UnsafeDeserializationLocal::PathNode source, UnsafeDeserializationLocal::PathNode sink +where UnsafeDeserializationLocal::flowPath(source, sink) select sink.getNode(), source, sink, "Deserializing of $@.", source.getNode(), "untrusted input" diff --git a/python/src/security/CWE-502/XMLLocalFileTaint.ql b/python/src/security/CWE-502/XMLLocalFileTaint.ql index 464b49d5..4f478bae 100644 --- a/python/src/security/CWE-502/XMLLocalFileTaint.ql +++ b/python/src/security/CWE-502/XMLLocalFileTaint.ql @@ -17,10 +17,10 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.TaintTracking -private import DataFlow::PathGraph private import ghsl.XMLLocalLib +import XmlFileTaint::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink -where any(XmlFileConfig conf).hasFlowPath(source, sink) +from XmlFileTaint::PathNode source, XmlFileTaint::PathNode sink +where XmlFileTaint::flowPath(source, sink) select sink.getNode(), source, sink, "Unsafe parsing of XML from locally-provided filename $@.", source.getNode(), "user input" diff --git a/python/src/security/CWE-502/XMLLocalStringTaint.ql b/python/src/security/CWE-502/XMLLocalStringTaint.ql index a3726c1d..f8f01a45 100644 --- a/python/src/security/CWE-502/XMLLocalStringTaint.ql +++ b/python/src/security/CWE-502/XMLLocalStringTaint.ql @@ -16,11 +16,10 @@ */ private import semmle.python.dataflow.new.DataFlow -private import semmle.python.dataflow.new.TaintTracking -private import DataFlow::PathGraph private import ghsl.XMLLocalLib +import XmlStringTaint::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink -where any(XmlStringConfig conf).hasFlowPath(source, sink) +from XmlStringTaint::PathNode source, XmlStringTaint::PathNode sink +where XmlStringTaint::flowPath(source, sink) select sink.getNode(), source, sink, "Unsafe parsing of XML from local $@.", source.getNode(), "user input" diff --git a/python/src/security/CWE-798/HardcodedFrameworkSecrets.ql b/python/src/security/CWE-798/HardcodedFrameworkSecrets.ql index 030bee7b..6e560bcf 100644 --- a/python/src/security/CWE-798/HardcodedFrameworkSecrets.ql +++ b/python/src/security/CWE-798/HardcodedFrameworkSecrets.ql @@ -20,21 +20,21 @@ import semmle.python.Concepts import semmle.python.dataflow.new.RemoteFlowSources import semmle.python.dataflow.new.BarrierGuards import semmle.python.ApiGraphs -import DataFlow::PathGraph import ghsl.HardcodedSecretSinks +import HarcodedFrameworkSecretsTaint::PathGraph class HardcodedValue extends DataFlow::Node { - HardcodedValue() { exists(StrConst literal | this = DataFlow::exprNode(literal)) } + HardcodedValue() { exists(StringLiteral literal | this = DataFlow::exprNode(literal)) } } -class HardcodedFrameworkSecrets extends TaintTracking::Configuration { - HardcodedFrameworkSecrets() { this = "Hardcoded framework secret configuration" } +module HardcodedFrameworkSecretsTaintConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof HardcodedValue } - override predicate isSource(DataFlow::Node source) { source instanceof HardcodedValue } - - override predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink } + predicate isSink(DataFlow::Node sink) { sink instanceof CredentialSink } } -from HardcodedFrameworkSecrets config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +module HarcodedFrameworkSecretsTaint = TaintTracking::Global; + +from HarcodedFrameworkSecretsTaint::PathNode source, HarcodedFrameworkSecretsTaint::PathNode sink +where HarcodedFrameworkSecretsTaint::flowPath(source, sink) select sink.getNode(), source, sink, "Use of $@.", source.getNode(), "hardcoded credentials" diff --git a/python/src/security/CWE-915/MassAssignment.ql b/python/src/security/CWE-915/MassAssignment.ql index 1b88d757..27fe2997 100644 --- a/python/src/security/CWE-915/MassAssignment.ql +++ b/python/src/security/CWE-915/MassAssignment.ql @@ -13,9 +13,9 @@ */ import python -import DataFlow::PathGraph -import ghsl.MassAssignment +import ghsl.MassAssignment::MassAssignment +import MassAssignmentTaint::PathGraph -from MassAssignment::MassAssignmentConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from MassAssignmentTaint::PathNode source, MassAssignmentTaint::PathNode sink +where MassAssignmentTaint::flowPath(source, sink) select sink.getNode(), source, sink, "Use of $@.", source.getNode(), "mass assignment" diff --git a/python/src/security/CWE-915/MassAssignmentLocal.ql b/python/src/security/CWE-915/MassAssignmentLocal.ql index 04059f6e..a2890517 100644 --- a/python/src/security/CWE-915/MassAssignmentLocal.ql +++ b/python/src/security/CWE-915/MassAssignmentLocal.ql @@ -14,11 +14,9 @@ */ import python -import DataFlow::PathGraph -import ghsl.MassAssignment +import ghsl.MassAssignment::MassAssignment +import MassAssignmentLocalTaint::PathGraph -from - MassAssignment::MassAssignmentLocalConfig config, DataFlow::PathNode source, - DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from MassAssignmentLocalTaint::PathNode source, MassAssignmentLocalTaint::PathNode sink +where MassAssignmentLocalTaint::flowPath(source, sink) select sink.getNode(), source, sink, "Use of $@.", source.getNode(), "mass assignment" diff --git a/python/src/security/CWE-915/MassAssignmentLocalProblem.ql b/python/src/security/CWE-915/MassAssignmentLocalProblem.ql index eaeef632..c0b6dfb1 100644 --- a/python/src/security/CWE-915/MassAssignmentLocalProblem.ql +++ b/python/src/security/CWE-915/MassAssignmentLocalProblem.ql @@ -16,7 +16,8 @@ import python import ghsl.MassAssignment +import MassAssignment -from MassAssignment::MassAssignmentLocalConfig config, DataFlow::Node source, DataFlow::Node sink -where config.hasFlow(source, sink) +from DataFlow::Node source, DataFlow::Node sink +where MassAssignmentLocalTaint::flow(source, sink) select sink, "Use of $@.", source, "mass assignment" diff --git a/python/src/security/CWE-915/MassAssignmentProblem.ql b/python/src/security/CWE-915/MassAssignmentProblem.ql index 5ff36e4b..fce08f27 100644 --- a/python/src/security/CWE-915/MassAssignmentProblem.ql +++ b/python/src/security/CWE-915/MassAssignmentProblem.ql @@ -16,7 +16,8 @@ import python import ghsl.MassAssignment +import MassAssignment -from MassAssignment::MassAssignmentConfig config, DataFlow::Node source, DataFlow::Node sink -where config.hasFlow(source, sink) +from DataFlow::Node source, DataFlow::Node sink +where MassAssignmentTaint::flow(source, sink) select sink, "Use of $@.", source, "mass assignment" From 9d8a8c8bcc532f2847763a4f8f2ebbfbd3268dea Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 13:29:34 +0100 Subject: [PATCH 13/15] Python: Update test expected output. --- .../test/audit/CWE-079/XssFlaskAudit.expected | 12 ++++---- .../audit/CWE-089/SqlInjectionAudit.expected | 24 +++++++-------- .../CWE-078/CommandInjectionLocal.expected | 20 ++++++------- .../CWE-094/CodeInjectionLocal.expected | 18 +++++------ .../UnsafeDeserializationLocal.expected | 12 ++++---- .../HardcodedFrameworkSecrets.expected | 30 +++++++++---------- .../local/MassAssignmentLocal.expected | 3 ++ 7 files changed, 61 insertions(+), 58 deletions(-) diff --git a/python/test/audit/CWE-079/XssFlaskAudit.expected b/python/test/audit/CWE-079/XssFlaskAudit.expected index a5e239b0..4c737640 100644 --- a/python/test/audit/CWE-079/XssFlaskAudit.expected +++ b/python/test/audit/CWE-079/XssFlaskAudit.expected @@ -1,12 +1,12 @@ edges -| app.py:1:26:1:32 | ControlFlowNode for ImportMember | app.py:1:26:1:32 | GSSA Variable request | -| app.py:1:26:1:32 | GSSA Variable request | app.py:12:16:12:22 | ControlFlowNode for request | -| app.py:12:5:12:12 | SSA variable username | app.py:14:51:14:58 | ControlFlowNode for username | -| app.py:12:16:12:22 | ControlFlowNode for request | app.py:12:5:12:12 | SSA variable username | +| app.py:1:26:1:32 | ControlFlowNode for ImportMember | app.py:1:26:1:32 | ControlFlowNode for request | provenance | | +| app.py:1:26:1:32 | ControlFlowNode for request | app.py:12:16:12:22 | ControlFlowNode for request | provenance | | +| app.py:12:5:12:12 | ControlFlowNode for username | app.py:14:51:14:58 | ControlFlowNode for username | provenance | | +| app.py:12:16:12:22 | ControlFlowNode for request | app.py:12:5:12:12 | ControlFlowNode for username | provenance | AdditionalTaintStep | nodes | app.py:1:26:1:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | -| app.py:1:26:1:32 | GSSA Variable request | semmle.label | GSSA Variable request | -| app.py:12:5:12:12 | SSA variable username | semmle.label | SSA variable username | +| app.py:1:26:1:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| app.py:12:5:12:12 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | | app.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | app.py:14:51:14:58 | ControlFlowNode for username | semmle.label | ControlFlowNode for username | subpaths diff --git a/python/test/audit/CWE-089/SqlInjectionAudit.expected b/python/test/audit/CWE-089/SqlInjectionAudit.expected index e19b16ae..c079ae7f 100644 --- a/python/test/audit/CWE-089/SqlInjectionAudit.expected +++ b/python/test/audit/CWE-089/SqlInjectionAudit.expected @@ -1,23 +1,23 @@ edges -| sqli.py:17:1:17:5 | GSSA Variable query | sqli.py:18:16:18:20 | ControlFlowNode for query | -| sqli.py:17:9:17:60 | ControlFlowNode for Fstring | sqli.py:17:1:17:5 | GSSA Variable query | -| sqli.py:21:1:21:5 | GSSA Variable query | sqli.py:22:16:22:20 | ControlFlowNode for query | -| sqli.py:21:9:21:68 | ControlFlowNode for Attribute() | sqli.py:21:1:21:5 | GSSA Variable query | -| sqli.py:25:1:25:5 | GSSA Variable query | sqli.py:26:16:26:20 | ControlFlowNode for query | -| sqli.py:25:9:25:60 | ControlFlowNode for BinaryExpr | sqli.py:25:1:25:5 | GSSA Variable query | -| sqli.py:30:1:30:5 | GSSA Variable query | sqli.py:31:16:31:20 | ControlFlowNode for query | -| sqli.py:30:9:30:58 | ControlFlowNode for BinaryExpr | sqli.py:30:1:30:5 | GSSA Variable query | +| sqli.py:17:1:17:5 | ControlFlowNode for query | sqli.py:18:16:18:20 | ControlFlowNode for query | provenance | | +| sqli.py:17:9:17:60 | ControlFlowNode for Fstring | sqli.py:17:1:17:5 | ControlFlowNode for query | provenance | | +| sqli.py:21:1:21:5 | ControlFlowNode for query | sqli.py:22:16:22:20 | ControlFlowNode for query | provenance | | +| sqli.py:21:9:21:68 | ControlFlowNode for Attribute() | sqli.py:21:1:21:5 | ControlFlowNode for query | provenance | | +| sqli.py:25:1:25:5 | ControlFlowNode for query | sqli.py:26:16:26:20 | ControlFlowNode for query | provenance | | +| sqli.py:25:9:25:60 | ControlFlowNode for BinaryExpr | sqli.py:25:1:25:5 | ControlFlowNode for query | provenance | | +| sqli.py:30:1:30:5 | ControlFlowNode for query | sqli.py:31:16:31:20 | ControlFlowNode for query | provenance | | +| sqli.py:30:9:30:58 | ControlFlowNode for BinaryExpr | sqli.py:30:1:30:5 | ControlFlowNode for query | provenance | | nodes -| sqli.py:17:1:17:5 | GSSA Variable query | semmle.label | GSSA Variable query | +| sqli.py:17:1:17:5 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | sqli.py:17:9:17:60 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | | sqli.py:18:16:18:20 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | -| sqli.py:21:1:21:5 | GSSA Variable query | semmle.label | GSSA Variable query | +| sqli.py:21:1:21:5 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | sqli.py:21:9:21:68 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | sqli.py:22:16:22:20 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | -| sqli.py:25:1:25:5 | GSSA Variable query | semmle.label | GSSA Variable query | +| sqli.py:25:1:25:5 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | sqli.py:25:9:25:60 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | sqli.py:26:16:26:20 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | -| sqli.py:30:1:30:5 | GSSA Variable query | semmle.label | GSSA Variable query | +| sqli.py:30:1:30:5 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | | sqli.py:30:9:30:58 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | | sqli.py:31:16:31:20 | ControlFlowNode for query | semmle.label | ControlFlowNode for query | subpaths diff --git a/python/test/security/CWE-078/CommandInjectionLocal.expected b/python/test/security/CWE-078/CommandInjectionLocal.expected index 5b88c9ca..69b8b10f 100644 --- a/python/test/security/CWE-078/CommandInjectionLocal.expected +++ b/python/test/security/CWE-078/CommandInjectionLocal.expected @@ -1,20 +1,20 @@ edges -| cmdi.py:4:1:4:1 | GSSA Variable i | cmdi.py:7:17:7:17 | ControlFlowNode for i | -| cmdi.py:4:1:4:1 | GSSA Variable i | cmdi.py:9:17:9:30 | ControlFlowNode for Fstring | -| cmdi.py:4:5:4:28 | ControlFlowNode for input() | cmdi.py:4:1:4:1 | GSSA Variable i | -| cmdi.py:14:1:14:2 | GSSA Variable e1 | cmdi.py:15:17:15:43 | ControlFlowNode for BinaryExpr | -| cmdi.py:14:6:14:29 | ControlFlowNode for Subscript | cmdi.py:14:1:14:2 | GSSA Variable e1 | -| cmdi.py:17:1:17:2 | GSSA Variable e2 | cmdi.py:18:17:18:43 | ControlFlowNode for BinaryExpr | -| cmdi.py:17:6:17:33 | ControlFlowNode for Attribute() | cmdi.py:17:1:17:2 | GSSA Variable e2 | +| cmdi.py:4:1:4:1 | ControlFlowNode for i | cmdi.py:7:17:7:17 | ControlFlowNode for i | provenance | | +| cmdi.py:4:1:4:1 | ControlFlowNode for i | cmdi.py:9:17:9:30 | ControlFlowNode for Fstring | provenance | | +| cmdi.py:4:5:4:28 | ControlFlowNode for input() | cmdi.py:4:1:4:1 | ControlFlowNode for i | provenance | Src:MaD:20 | +| cmdi.py:14:1:14:2 | ControlFlowNode for e1 | cmdi.py:15:17:15:43 | ControlFlowNode for BinaryExpr | provenance | | +| cmdi.py:14:6:14:29 | ControlFlowNode for Subscript | cmdi.py:14:1:14:2 | ControlFlowNode for e1 | provenance | | +| cmdi.py:17:1:17:2 | ControlFlowNode for e2 | cmdi.py:18:17:18:43 | ControlFlowNode for BinaryExpr | provenance | | +| cmdi.py:17:6:17:33 | ControlFlowNode for Attribute() | cmdi.py:17:1:17:2 | ControlFlowNode for e2 | provenance | | nodes -| cmdi.py:4:1:4:1 | GSSA Variable i | semmle.label | GSSA Variable i | +| cmdi.py:4:1:4:1 | ControlFlowNode for i | semmle.label | ControlFlowNode for i | | cmdi.py:4:5:4:28 | ControlFlowNode for input() | semmle.label | ControlFlowNode for input() | | cmdi.py:7:17:7:17 | ControlFlowNode for i | semmle.label | ControlFlowNode for i | | cmdi.py:9:17:9:30 | ControlFlowNode for Fstring | semmle.label | ControlFlowNode for Fstring | -| cmdi.py:14:1:14:2 | GSSA Variable e1 | semmle.label | GSSA Variable e1 | +| cmdi.py:14:1:14:2 | ControlFlowNode for e1 | semmle.label | ControlFlowNode for e1 | | cmdi.py:14:6:14:29 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | cmdi.py:15:17:15:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | -| cmdi.py:17:1:17:2 | GSSA Variable e2 | semmle.label | GSSA Variable e2 | +| cmdi.py:17:1:17:2 | ControlFlowNode for e2 | semmle.label | ControlFlowNode for e2 | | cmdi.py:17:6:17:33 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | cmdi.py:18:17:18:43 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr | subpaths diff --git a/python/test/security/CWE-094/CodeInjectionLocal.expected b/python/test/security/CWE-094/CodeInjectionLocal.expected index ac0cbbe1..9c8857a2 100644 --- a/python/test/security/CWE-094/CodeInjectionLocal.expected +++ b/python/test/security/CWE-094/CodeInjectionLocal.expected @@ -1,18 +1,18 @@ edges -| codei.py:3:1:3:1 | GSSA Variable i | codei.py:6:6:6:6 | ControlFlowNode for i | -| codei.py:3:5:3:28 | ControlFlowNode for input() | codei.py:3:1:3:1 | GSSA Variable i | -| codei.py:9:1:9:2 | GSSA Variable e1 | codei.py:10:6:10:7 | ControlFlowNode for e1 | -| codei.py:9:6:9:29 | ControlFlowNode for Subscript | codei.py:9:1:9:2 | GSSA Variable e1 | -| codei.py:12:1:12:2 | GSSA Variable e2 | codei.py:13:6:13:7 | ControlFlowNode for e2 | -| codei.py:12:6:12:33 | ControlFlowNode for Attribute() | codei.py:12:1:12:2 | GSSA Variable e2 | +| codei.py:3:1:3:1 | ControlFlowNode for i | codei.py:6:6:6:6 | ControlFlowNode for i | provenance | | +| codei.py:3:5:3:28 | ControlFlowNode for input() | codei.py:3:1:3:1 | ControlFlowNode for i | provenance | Src:MaD:20 | +| codei.py:9:1:9:2 | ControlFlowNode for e1 | codei.py:10:6:10:7 | ControlFlowNode for e1 | provenance | | +| codei.py:9:6:9:29 | ControlFlowNode for Subscript | codei.py:9:1:9:2 | ControlFlowNode for e1 | provenance | | +| codei.py:12:1:12:2 | ControlFlowNode for e2 | codei.py:13:6:13:7 | ControlFlowNode for e2 | provenance | | +| codei.py:12:6:12:33 | ControlFlowNode for Attribute() | codei.py:12:1:12:2 | ControlFlowNode for e2 | provenance | | nodes -| codei.py:3:1:3:1 | GSSA Variable i | semmle.label | GSSA Variable i | +| codei.py:3:1:3:1 | ControlFlowNode for i | semmle.label | ControlFlowNode for i | | codei.py:3:5:3:28 | ControlFlowNode for input() | semmle.label | ControlFlowNode for input() | | codei.py:6:6:6:6 | ControlFlowNode for i | semmle.label | ControlFlowNode for i | -| codei.py:9:1:9:2 | GSSA Variable e1 | semmle.label | GSSA Variable e1 | +| codei.py:9:1:9:2 | ControlFlowNode for e1 | semmle.label | ControlFlowNode for e1 | | codei.py:9:6:9:29 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | codei.py:10:6:10:7 | ControlFlowNode for e1 | semmle.label | ControlFlowNode for e1 | -| codei.py:12:1:12:2 | GSSA Variable e2 | semmle.label | GSSA Variable e2 | +| codei.py:12:1:12:2 | ControlFlowNode for e2 | semmle.label | ControlFlowNode for e2 | | codei.py:12:6:12:33 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | codei.py:13:6:13:7 | ControlFlowNode for e2 | semmle.label | ControlFlowNode for e2 | subpaths diff --git a/python/test/security/CWE-502/UnsafeDeserializationLocal.expected b/python/test/security/CWE-502/UnsafeDeserializationLocal.expected index dfefea7a..1b1bbc7c 100644 --- a/python/test/security/CWE-502/UnsafeDeserializationLocal.expected +++ b/python/test/security/CWE-502/UnsafeDeserializationLocal.expected @@ -1,13 +1,13 @@ edges -| unsafe.py:5:1:5:1 | GSSA Variable i | unsafe.py:7:14:7:14 | ControlFlowNode for i | -| unsafe.py:5:5:5:11 | ControlFlowNode for input() | unsafe.py:5:1:5:1 | GSSA Variable i | -| unsafe.py:10:1:10:1 | GSSA Variable e | unsafe.py:12:14:12:14 | ControlFlowNode for e | -| unsafe.py:10:5:10:32 | ControlFlowNode for Attribute() | unsafe.py:10:1:10:1 | GSSA Variable e | +| unsafe.py:5:1:5:1 | ControlFlowNode for i | unsafe.py:7:14:7:14 | ControlFlowNode for i | provenance | | +| unsafe.py:5:5:5:11 | ControlFlowNode for input() | unsafe.py:5:1:5:1 | ControlFlowNode for i | provenance | Src:MaD:20 | +| unsafe.py:10:1:10:1 | ControlFlowNode for e | unsafe.py:12:14:12:14 | ControlFlowNode for e | provenance | | +| unsafe.py:10:5:10:32 | ControlFlowNode for Attribute() | unsafe.py:10:1:10:1 | ControlFlowNode for e | provenance | | nodes -| unsafe.py:5:1:5:1 | GSSA Variable i | semmle.label | GSSA Variable i | +| unsafe.py:5:1:5:1 | ControlFlowNode for i | semmle.label | ControlFlowNode for i | | unsafe.py:5:5:5:11 | ControlFlowNode for input() | semmle.label | ControlFlowNode for input() | | unsafe.py:7:14:7:14 | ControlFlowNode for i | semmle.label | ControlFlowNode for i | -| unsafe.py:10:1:10:1 | GSSA Variable e | semmle.label | GSSA Variable e | +| unsafe.py:10:1:10:1 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | | unsafe.py:10:5:10:32 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | unsafe.py:12:14:12:14 | ControlFlowNode for e | semmle.label | ControlFlowNode for e | | unsafe.py:17:22:17:29 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | diff --git a/python/test/security/CWE-798/HardcodedFrameworkSecrets.expected b/python/test/security/CWE-798/HardcodedFrameworkSecrets.expected index e88f7503..32928c2d 100644 --- a/python/test/security/CWE-798/HardcodedFrameworkSecrets.expected +++ b/python/test/security/CWE-798/HardcodedFrameworkSecrets.expected @@ -1,21 +1,21 @@ -| hardcoded_secrets.py:10:18:10:29 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:11:28:11:39 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:12:30:12:41 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:22:30:22:47 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:28:38:28:55 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:34:53:34:69 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:35:50:35:66 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:40:47:40:59 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:41:38:41:50 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:47:72:47:85 | ControlFlowNode for Str | sinks | +| hardcoded_secrets.py:10:18:10:29 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:11:28:11:39 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:12:30:12:41 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:22:30:22:47 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:28:38:28:55 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:34:53:34:69 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:35:50:35:66 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:40:47:40:59 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:41:38:41:50 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:47:72:47:85 | ControlFlowNode for StringLiteral | sinks | | hardcoded_secrets.py:50:72:50:72 | ControlFlowNode for w | sinks | -| hardcoded_secrets.py:56:19:56:36 | ControlFlowNode for Str | sinks | +| hardcoded_secrets.py:56:19:56:36 | ControlFlowNode for StringLiteral | sinks | | hardcoded_secrets.py:59:20:59:20 | ControlFlowNode for p | sinks | | hardcoded_secrets.py:62:20:62:20 | ControlFlowNode for p | sinks | -| hardcoded_secrets.py:70:23:70:40 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:71:27:71:48 | ControlFlowNode for Str | sinks | -| hardcoded_secrets.py:72:23:72:42 | ControlFlowNode for Str | sinks | -| settings.py:5:14:5:29 | ControlFlowNode for Str | sinks | +| hardcoded_secrets.py:70:23:70:40 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:71:27:71:48 | ControlFlowNode for StringLiteral | sinks | +| hardcoded_secrets.py:72:23:72:42 | ControlFlowNode for StringLiteral | sinks | +| settings.py:5:14:5:29 | ControlFlowNode for StringLiteral | sinks | | settings.py:7:14:7:51 | ControlFlowNode for Attribute() | sinks | | settings.py:9:14:9:41 | ControlFlowNode for Attribute() | sinks | | settings.py:13:14:13:26 | ControlFlowNode for RANDOM_STRING | sinks | diff --git a/python/test/security/CWE-915/local/MassAssignmentLocal.expected b/python/test/security/CWE-915/local/MassAssignmentLocal.expected index f558c4cb..c064410f 100644 --- a/python/test/security/CWE-915/local/MassAssignmentLocal.expected +++ b/python/test/security/CWE-915/local/MassAssignmentLocal.expected @@ -1,3 +1,6 @@ +| massassignmentLocal.py:18:26:18:28 | ControlFlowNode for key | Use of $@. | massassignmentLocal.py:8:13:8:31 | ControlFlowNode for Attribute() | mass assignment | | massassignmentLocal.py:18:26:18:28 | ControlFlowNode for key | Use of $@. | massassignmentLocal.py:30:10:30:20 | ControlFlowNode for Attribute | mass assignment | +| massassignmentLocal.py:24:15:24:25 | ControlFlowNode for Attribute | Use of $@. | massassignmentLocal.py:8:13:8:31 | ControlFlowNode for Attribute() | mass assignment | | massassignmentLocal.py:24:15:24:25 | ControlFlowNode for Attribute | Use of $@. | massassignmentLocal.py:24:15:24:25 | ControlFlowNode for Attribute | mass assignment | +| massassignmentLocal.py:27:18:27:28 | ControlFlowNode for Attribute | Use of $@. | massassignmentLocal.py:8:13:8:31 | ControlFlowNode for Attribute() | mass assignment | | massassignmentLocal.py:27:18:27:28 | ControlFlowNode for Attribute | Use of $@. | massassignmentLocal.py:27:18:27:28 | ControlFlowNode for Attribute | mass assignment | From 49adfdc25c5d35713a0ecba9c4ebae98d9752fa4 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 13:09:48 +0100 Subject: [PATCH 14/15] Ruby: Update dependencies to those released with 2.19.3. --- ruby/lib/codeql-pack.lock.yml | 18 ++++++++++-------- ruby/src/codeql-pack.lock.yml | 18 ++++++++++-------- ruby/test/codeql-pack.lock.yml | 22 ++++++++++++---------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/ruby/lib/codeql-pack.lock.yml b/ruby/lib/codeql-pack.lock.yml index 263c1d72..4a8a19de 100644 --- a/ruby/lib/codeql-pack.lock.yml +++ b/ruby/lib/codeql-pack.lock.yml @@ -2,19 +2,21 @@ lockVersion: 1.0.0 dependencies: codeql/controlflow: - version: 0.0.3 + version: 1.0.11 codeql/dataflow: - version: 0.0.3 + version: 1.1.5 codeql/mad: - version: 0.1.4 + version: 1.0.11 codeql/regex: - version: 0.1.4 + version: 1.0.11 codeql/ruby-all: - version: 0.7.4 + version: 2.0.3 codeql/ssa: - version: 0.1.4 + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 compiled: false diff --git a/ruby/src/codeql-pack.lock.yml b/ruby/src/codeql-pack.lock.yml index 263c1d72..4a8a19de 100644 --- a/ruby/src/codeql-pack.lock.yml +++ b/ruby/src/codeql-pack.lock.yml @@ -2,19 +2,21 @@ lockVersion: 1.0.0 dependencies: codeql/controlflow: - version: 0.0.3 + version: 1.0.11 codeql/dataflow: - version: 0.0.3 + version: 1.1.5 codeql/mad: - version: 0.1.4 + version: 1.0.11 codeql/regex: - version: 0.1.4 + version: 1.0.11 codeql/ruby-all: - version: 0.7.4 + version: 2.0.3 codeql/ssa: - version: 0.1.4 + version: 1.0.11 codeql/tutorial: - version: 0.1.4 + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.4 + version: 1.0.11 compiled: false diff --git a/ruby/test/codeql-pack.lock.yml b/ruby/test/codeql-pack.lock.yml index a06a74b5..95b2b8d4 100644 --- a/ruby/test/codeql-pack.lock.yml +++ b/ruby/test/codeql-pack.lock.yml @@ -2,23 +2,25 @@ lockVersion: 1.0.0 dependencies: codeql/controlflow: - version: 0.0.4 + version: 1.0.11 codeql/dataflow: - version: 0.0.4 + version: 1.1.5 codeql/mad: - version: 0.1.5 + version: 1.0.11 codeql/regex: - version: 0.1.5 + version: 1.0.11 codeql/ruby-all: - version: 0.7.5 + version: 2.0.3 codeql/ruby-queries: - version: 0.7.5 + version: 1.1.6 codeql/ssa: - version: 0.1.5 + version: 1.0.11 codeql/suite-helpers: - version: 0.6.5 + version: 1.0.11 codeql/tutorial: - version: 0.1.5 + version: 1.0.11 + codeql/typetracking: + version: 1.0.11 codeql/util: - version: 0.1.5 + version: 1.0.11 compiled: false From d7a0a29e83f42bb9f500bf5642db138e7f6e05c9 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 18 Dec 2024 14:45:02 +0100 Subject: [PATCH 15/15] Ruby: Update test expected output. --- ruby/test/security/CWE-770/UserControlledMaxIterations.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/test/security/CWE-770/UserControlledMaxIterations.expected b/ruby/test/security/CWE-770/UserControlledMaxIterations.expected index 9567b8db..5448c138 100644 --- a/ruby/test/security/CWE-770/UserControlledMaxIterations.expected +++ b/ruby/test/security/CWE-770/UserControlledMaxIterations.expected @@ -2,7 +2,7 @@ edges | UserControlledMaxIterations__bad.rb:3:7:3:11 | limit | UserControlledMaxIterations__bad.rb:11:7:11:11 | limit | provenance | | | UserControlledMaxIterations__bad.rb:3:7:3:11 | limit | UserControlledMaxIterations__bad.rb:16:7:16:11 | limit | provenance | | | UserControlledMaxIterations__bad.rb:3:15:3:20 | call to params | UserControlledMaxIterations__bad.rb:3:15:3:28 | ...[...] | provenance | | -| UserControlledMaxIterations__bad.rb:3:15:3:28 | ...[...] | UserControlledMaxIterations__bad.rb:3:15:3:33 | call to to_i | provenance | | +| UserControlledMaxIterations__bad.rb:3:15:3:28 | ...[...] | UserControlledMaxIterations__bad.rb:3:15:3:33 | call to to_i | provenance | Config | | UserControlledMaxIterations__bad.rb:3:15:3:33 | call to to_i | UserControlledMaxIterations__bad.rb:3:7:3:11 | limit | provenance | | nodes | UserControlledMaxIterations__bad.rb:3:7:3:11 | limit | semmle.label | limit |