Compare commits

..

8 Commits

Author SHA1 Message Date
Kasper Svendsen
1d74d60a5f Java lib qlpack: Enable compileForOverlayEval 2025-06-24 09:18:13 +02:00
Jonas Jensen
c1214db5b3 DataFlow:Run overlay-informed if not diff-informed
To ensure good performance, always run data flow overlay-informed unless
the configuration has opted in to being diff-informed. This change
affects only databases with an overlay and therefore has no immediate
production consequences.
2025-06-24 09:00:56 +02:00
Kasper Svendsen
3c2c871a36 Java: Allow methods with empty bodies for overlay 2025-06-23 14:59:34 +02:00
Kasper Svendsen
ddaf0b2bd8 Java: Add entity discard predicates 2025-06-23 14:59:33 +02:00
Kasper Svendsen
4f497180ea Java: Add manual overlay annotations 2025-06-20 14:15:54 +02:00
Kasper Svendsen
052023efae rename overlay[caller] to overlay[caller?] 2025-06-20 13:58:59 +02:00
Kasper Svendsen
3cbaf51ce1 Run config/sync-files.py 2025-06-20 13:58:58 +02:00
Kasper Svendsen
bceb147d72 Overlay: Add overlay annotations to Java & shared libraries 2025-06-20 13:58:57 +02:00
7431 changed files with 208346 additions and 562487 deletions

View File

@@ -30,9 +30,6 @@ common --registry=https://bcr.bazel.build
common --@rules_dotnet//dotnet/settings:strict_deps=false common --@rules_dotnet//dotnet/settings:strict_deps=false
# we only configure a nightly toolchain
common --@rules_rust//rust/toolchain/channel=nightly
# Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed # Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed
common --incompatible_autoload_externally="+@rules_java,+@rules_shell" common --incompatible_autoload_externally="+@rules_java,+@rules_shell"

View File

@@ -1,4 +0,0 @@
---
applyTo: "**/*.expected"
---
Ignore these files. These are generated to be correct by running the tests, and should not be edited manually.

View File

@@ -1,6 +0,0 @@
---
applyTo: "**/*.ql,**/*.qll"
---
When reviewing these QL files, do not make any comment on the code itself. You don't understand the QL programming language well enough yet. You can only make comments about the following aspects:
* comments (lines starting with `//` or block comments enclosed in `/* ... */`): you can suggest improvements to the clarity of comments, or point out spelling mistakes
* typos in identifiers

View File

@@ -20,7 +20,7 @@ jobs:
os: [ubuntu-22.04, macos-13, windows-2022] os: [ubuntu-22.04, macos-13, windows-2022]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
with: with:
repository: google/ripunzip repository: google/ripunzip
ref: ${{ inputs.ripunzip-version }} ref: ${{ inputs.ripunzip-version }}
@@ -28,7 +28,7 @@ jobs:
# see https://github.com/sfackler/rust-openssl/issues/183 # see https://github.com/sfackler/rust-openssl/issues/183
- if: runner.os == 'Linux' - if: runner.os == 'Linux'
name: checkout openssl name: checkout openssl
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: openssl/openssl repository: openssl/openssl
path: openssl path: openssl

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Check bazel formatting - name: Check bazel formatting
uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
with: with:

View File

@@ -16,6 +16,7 @@ on:
- "shared/**/*.qll" - "shared/**/*.qll"
- "!**/experimental/**" - "!**/experimental/**"
- "!ql/**" - "!ql/**"
- "!rust/**"
- ".github/workflows/check-change-note.yml" - ".github/workflows/check-change-note.yml"
jobs: jobs:

View File

@@ -16,7 +16,7 @@ jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Check that implicit this warnings is enabled for all packs - name: Check that implicit this warnings is enabled for all packs
shell: bash shell: bash
run: | run: |

View File

@@ -1,23 +0,0 @@
name: Check overlay annotations
on:
push:
branches:
- main
- 'rc/*'
pull_request:
branches:
- main
- 'rc/*'
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Check overlay annotations
run: python config/add-overlay-annotations.py --check java

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 2

View File

@@ -19,6 +19,6 @@ jobs:
name: Check query IDs name: Check query IDs
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Check for duplicate query IDs - name: Check for duplicate query IDs
run: python3 misc/scripts/check-query-ids.py run: python3 misc/scripts/check-query-ids.py

View File

@@ -34,10 +34,10 @@ jobs:
- name: Setup dotnet - name: Setup dotnet
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: 9.0.300 dotnet-version: 9.0.100
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View File

@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
with: with:

View File

@@ -28,7 +28,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View File

@@ -39,23 +39,23 @@ jobs:
os: [ubuntu-latest, windows-latest] os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Setup dotnet - name: Setup dotnet
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: 9.0.300 dotnet-version: 9.0.100
- name: Extractor unit tests - name: Extractor unit tests
run: | run: |
dotnet tool restore dotnet tool restore
dotnet test -p:RuntimeFrameworkVersion=9.0.5 extractor/Semmle.Util.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Util.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.5 extractor/Semmle.Extraction.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Extraction.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.5 autobuilder/Semmle.Autobuild.CSharp.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.CSharp.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.5 autobuilder/Semmle.Autobuild.Cpp.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.Cpp.Tests
shell: bash shell: bash
stubgentest: stubgentest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: ./csharp/actions/create-extractor-pack - uses: ./csharp/actions/create-extractor-pack
- name: Run stub generator tests - name: Run stub generator tests
run: | run: |

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Create empty database - name: Create empty database
@@ -51,7 +51,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Create empty database - name: Create empty database

View File

@@ -35,11 +35,11 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - MERGE - name: Clone self (github/codeql) - MERGE
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: merge path: merge
- name: Clone self (github/codeql) - BASE - name: Clone self (github/codeql) - BASE
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 2
path: base path: base

View File

@@ -24,7 +24,7 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:

View File

@@ -12,11 +12,11 @@ jobs:
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: codeqlModels path: codeqlModels
fetch-depth: 0 fetch-depth: 0

View File

@@ -21,7 +21,7 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: ql path: ql
fetch-depth: 0 fetch-depth: 0

View File

@@ -16,11 +16,11 @@ jobs:
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: codeqlModels path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}

View File

@@ -26,7 +26,7 @@ jobs:
exit 1 exit 1
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Git config - name: Git config
shell: bash shell: bash

35
.github/workflows/go-tests-other-os.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: "Go: Run Tests - Other OS"
on:
pull_request:
paths:
- "go/**"
- "!go/documentation/**"
- "!go/ql/**" # don't run other-os if only ql/ files changed
- .github/workflows/go-tests-other-os.yml
- .github/actions/**
- codeql-workspace.yml
- MODULE.bazel
- .bazelrc
- misc/bazel/**
permissions:
contents: read
jobs:
test-mac:
name: Test MacOS
runs-on: macos-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test
test-win:
name: Test Windows
runs-on: windows-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test

22
.github/workflows/go-tests-rtjo.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: "Go: Run RTJO Tests"
on:
pull_request:
types:
- labeled
permissions:
contents: read
jobs:
test-linux:
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
name: RTJO Test Linux (Ubuntu)
runs-on: ubuntu-latest-xl
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test
with:
run-code-checks: true
dynamic-join-order-mode: all

View File

@@ -1,5 +1,16 @@
name: "Go: Run Tests" name: "Go: Run Tests"
on: on:
push:
paths:
- "go/**"
- "!go/documentation/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
branches:
- main
- "rc/*"
pull_request: pull_request:
paths: paths:
- "go/**" - "go/**"
@@ -22,7 +33,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Run tests - name: Run tests
uses: ./go/actions/test uses: ./go/actions/test
with: with:

View File

@@ -20,7 +20,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- run: | - run: |
bazel query //java/kotlin-extractor/... bazel query //java/kotlin-extractor/...
# only build the default version as a quick check that we can build from `codeql` # only build the default version as a quick check that we can build from `codeql`

View File

@@ -28,12 +28,12 @@ jobs:
slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}} slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}}
steps: steps:
- name: Clone github/codeql from PR - name: Clone github/codeql from PR
uses: actions/checkout@v5 uses: actions/checkout@v4
if: github.event.pull_request if: github.event.pull_request
with: with:
path: codeql-pr path: codeql-pr
- name: Clone github/codeql from main - name: Clone github/codeql from main
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: codeql-main path: codeql-main
ref: main ref: main

View File

@@ -30,11 +30,11 @@ jobs:
ref: "placeholder" ref: "placeholder"
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Setup CodeQL binaries - name: Setup CodeQL binaries
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Clone repositories - name: Clone repositories
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: repos/${{ matrix.ref }} path: repos/${{ matrix.ref }}
ref: ${{ matrix.ref }} ref: ${{ matrix.ref }}

View File

@@ -21,7 +21,7 @@ jobs:
check-python-tooling: check-python-tooling:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: '3.12' python-version: '3.12'

View File

@@ -43,7 +43,7 @@ jobs:
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 1
- uses: actions/checkout@v5 - uses: actions/checkout@v4
with: with:
fetch-depth: 2 fetch-depth: 2
persist-credentials: false persist-credentials: false

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
### Build the queries ### ### Build the queries ###
- uses: actions/checkout@v5 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Find codeql - name: Find codeql

View File

@@ -25,7 +25,7 @@ jobs:
- github/codeql - github/codeql
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Find codeql - name: Find codeql
id: find-codeql id: find-codeql
@@ -46,14 +46,14 @@ jobs:
env: env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Checkout ${{ matrix.repo }} - name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: ${{ matrix.repo }} repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo path: ${{ github.workspace }}/repo
- name: Create database - name: Create database
run: | run: |
"${CODEQL}" database create \ "${CODEQL}" database create \
--search-path "${{ github.workspace }}" \ --search-path "${{ github.workspace }}"
--threads 4 \ --threads 4 \
--language ql --source-root "${{ github.workspace }}/repo" \ --language ql --source-root "${{ github.workspace }}/repo" \
"${{ runner.temp }}/database" "${{ runner.temp }}/database"
@@ -75,7 +75,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: measure needs: measure
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: measurements name: measurements

View File

@@ -24,7 +24,7 @@ jobs:
qltest: qltest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Find codeql - name: Find codeql
id: find-codeql id: find-codeql
uses: github/codeql-action/init@main uses: github/codeql-action/init@main
@@ -64,7 +64,7 @@ jobs:
needs: [qltest] needs: [qltest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Install GNU tar - name: Install GNU tar
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: | run: |

View File

@@ -23,7 +23,7 @@ jobs:
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: codeql path: codeql
- name: Set up Python 3.8 - name: Set up Python 3.8
@@ -31,7 +31,7 @@ jobs:
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo # Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
uses: ./codeql/.github/actions/fetch-codeql uses: ./codeql/.github/actions/fetch-codeql
- name: Build code scanning query list - name: Build code scanning query list
run: | run: |

View File

@@ -47,7 +47,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Install GNU tar - name: Install GNU tar
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: | run: |
@@ -113,7 +113,7 @@ jobs:
if: github.repository_owner == 'github' if: github.repository_owner == 'github'
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Cache compilation cache - name: Cache compilation cache
@@ -146,7 +146,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build, compile-queries] needs: [build, compile-queries]
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: ruby.dbscheme name: ruby.dbscheme
@@ -209,7 +209,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [package] needs: [package]
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql

View File

@@ -30,14 +30,14 @@ jobs:
repo: [rails/rails, discourse/discourse, spree/spree, ruby/ruby] repo: [rails/rails, discourse/discourse, spree/spree, ruby/ruby]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack - uses: ./ruby/actions/create-extractor-pack
- name: Checkout ${{ matrix.repo }} - name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: ${{ matrix.repo }} repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo path: ${{ github.workspace }}/repo
@@ -62,7 +62,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: measure needs: measure
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
path: stats path: stats

View File

@@ -25,7 +25,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack - uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache - name: Cache compilation cache

View File

@@ -36,7 +36,7 @@ jobs:
qlupgrade: qlupgrade:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- name: Check DB upgrade scripts - name: Check DB upgrade scripts
run: | run: |
@@ -58,7 +58,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack - uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache - name: Cache compilation cache

View File

@@ -35,7 +35,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Query latest nightly CodeQL bundle - name: Query latest nightly CodeQL bundle
shell: bash shell: bash

View File

@@ -30,7 +30,7 @@ jobs:
working-directory: rust/ast-generator working-directory: rust/ast-generator
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Inject sources - name: Inject sources
shell: bash shell: bash
run: | run: |
@@ -53,7 +53,7 @@ jobs:
working-directory: rust/extractor working-directory: rust/extractor
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Format - name: Format
shell: bash shell: bash
run: | run: |
@@ -69,7 +69,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Install CodeQL - name: Install CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Code generation - name: Code generation

View File

@@ -36,7 +36,7 @@ jobs:
fail-fast: false fail-fast: false
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Setup (Linux) - name: Setup (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: | run: |
@@ -53,7 +53,7 @@ jobs:
clang-format: clang-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted name: Check that python code is properly formatted
with: with:
@@ -61,7 +61,7 @@ jobs:
codegen: codegen:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that QL generated code was checked in name: Check that QL generated code was checked in
@@ -77,6 +77,6 @@ jobs:
check-no-override: check-no-override:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Check that no override is present in load.bzl - name: Check that no override is present in load.bzl
run: bazel test ... --test_tag_filters=override --test_output=errors run: bazel test ... --test_tag_filters=override --test_output=errors

View File

@@ -17,7 +17,7 @@ jobs:
sync: sync:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Check synchronized files - name: Check synchronized files
run: python config/sync-files.py run: python config/sync-files.py
- name: Check dbscheme fragments - name: Check dbscheme fragments

View File

@@ -30,7 +30,7 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Check formatting - name: Check formatting
run: cargo fmt -- --check run: cargo fmt -- --check
- name: Run tests - name: Run tests
@@ -38,12 +38,12 @@ jobs:
fmt: fmt:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Check formatting - name: Check formatting
run: cargo fmt --check run: cargo fmt --check
clippy: clippy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Run clippy - name: Run clippy
run: cargo clippy -- --no-deps -D warnings -A clippy::new_without_default -A clippy::too_many_arguments run: cargo clippy -- --no-deps -D warnings -A clippy::new_without_default -A clippy::too_many_arguments

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql

View File

@@ -18,6 +18,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- run: | - run: |
bazel test //misc/bazel/internal/zipmerge:test --test_output=all bazel test //misc/bazel/internal/zipmerge:test --test_output=all

3
.gitignore vendored
View File

@@ -76,6 +76,3 @@ node_modules/
# some upgrade/downgrade checks create these files # some upgrade/downgrade checks create these files
**/upgrades/*/*.dbscheme.stats **/upgrades/*/*.dbscheme.stats
**/downgrades/*/*.dbscheme.stats **/downgrades/*/*.dbscheme.stats
# Mergetool files
*.orig

View File

@@ -9,7 +9,7 @@ repos:
- id: trailing-whitespace - id: trailing-whitespace
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$ exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- id: end-of-file-fixer - id: end-of-file-fixer
exclude: Cargo.lock$|/test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$ exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- repo: https://github.com/pre-commit/mirrors-clang-format - repo: https://github.com/pre-commit/mirrors-clang-format
rev: v17.0.6 rev: v17.0.6
@@ -20,7 +20,7 @@ repos:
rev: 25.1.0 rev: 25.1.0
hooks: hooks:
- id: black - id: black
files: ^(misc/codegen/.*|misc/scripts/models-as-data/.*)\.py$ files: ^(misc/codegen/.*|misc/scripts/models-as-data/bulk_generate_mad)\.py$
- repo: local - repo: local
hooks: hooks:

View File

@@ -1,7 +1,3 @@
# Catch-all for anything which isn't matched by a line lower down
* @github/code-scanning-alert-coverage
# CodeQL language libraries
/actions/ @github/codeql-dynamic /actions/ @github/codeql-dynamic
/cpp/ @github/codeql-c-analysis /cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp /csharp/ @github/codeql-csharp
@@ -11,10 +7,8 @@
/java/ @github/codeql-java /java/ @github/codeql-java
/javascript/ @github/codeql-javascript /javascript/ @github/codeql-javascript
/python/ @github/codeql-python /python/ @github/codeql-python
/ql/ @github/codeql-ql-for-ql-reviewers
/ruby/ @github/codeql-ruby /ruby/ @github/codeql-ruby
/rust/ @github/codeql-rust /rust/ @github/codeql-rust
/shared/ @github/codeql-shared-libraries-reviewers
/swift/ @github/codeql-swift /swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift /misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin /java/kotlin-extractor/ @github/codeql-kotlin
@@ -31,6 +25,9 @@
/docs/codeql/ql-language-reference/ @github/codeql-frontend-reviewers /docs/codeql/ql-language-reference/ @github/codeql-frontend-reviewers
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers /docs/query-*-style-guide.md @github/codeql-analysis-reviewers
# QL for QL reviewers
/ql/ @github/codeql-ql-for-ql-reviewers
# Bazel (excluding BUILD.bazel files) # Bazel (excluding BUILD.bazel files)
MODULE.bazel @github/codeql-ci-reviewers MODULE.bazel @github/codeql-ci-reviewers
.bazelversion @github/codeql-ci-reviewers .bazelversion @github/codeql-ci-reviewers

1612
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,3 +10,9 @@ members = [
"rust/ast-generator", "rust/ast-generator",
"rust/autobuild", "rust/autobuild",
] ]
exclude = ["mad-generation-build"]
[patch.crates-io]
# patch for build script bug preventing bazel build
# see https://github.com/rust-lang/rustc_apfloat/pull/17
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "32968f16ef1b082243f9bf43a3fbd65c381b3e27" }

View File

@@ -14,21 +14,21 @@ local_path_override(
# see https://registry.bazel.build/ for a list of available packages # see https://registry.bazel.build/ for a list of available packages
bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_go", version = "0.56.1") bazel_dep(name = "rules_go", version = "0.50.1")
bazel_dep(name = "rules_pkg", version = "1.0.1") bazel_dep(name = "rules_pkg", version = "1.0.1")
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1") bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
bazel_dep(name = "rules_python", version = "0.40.0") bazel_dep(name = "rules_python", version = "0.40.0")
bazel_dep(name = "rules_shell", version = "0.5.0") bazel_dep(name = "rules_shell", version = "0.3.0")
bazel_dep(name = "bazel_skylib", version = "1.8.1") bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl") bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json") bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "10.0.0") bazel_dep(name = "fmt", version = "10.0.0")
bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1") bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
bazel_dep(name = "gazelle", version = "0.40.0") bazel_dep(name = "gazelle", version = "0.40.0")
bazel_dep(name = "rules_dotnet", version = "0.19.2-codeql.1") bazel_dep(name = "rules_dotnet", version = "0.17.4")
bazel_dep(name = "googletest", version = "1.14.0.bcr.1") bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
bazel_dep(name = "rules_rust", version = "0.66.0") bazel_dep(name = "rules_rust", version = "0.58.0")
bazel_dep(name = "zstd", version = "1.5.5.bcr.1") bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True) bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
@@ -37,11 +37,7 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies. # the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
RUST_EDITION = "2024" RUST_EDITION = "2024"
# run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo) RUST_VERSION = "1.85.0"
# a nightly toolchain is required to enable experimental_use_cc_common_link, which we require internally
# we prefer to run the same version as internally, even if experimental_use_cc_common_link is not really
# required in this repo
RUST_VERSION = "nightly/2025-08-01"
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain( rust.toolchain(
@@ -51,29 +47,6 @@ rust.toolchain(
"x86_64-apple-darwin", "x86_64-apple-darwin",
"aarch64-apple-darwin", "aarch64-apple-darwin",
], ],
# generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo)
sha256s = {
"2025-08-01/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "9bbeaf5d3fc7247d31463a9083aa251c995cc50662c8219e7a2254d76a72a9a4",
"2025-08-01/rustc-nightly-x86_64-apple-darwin.tar.xz": "c9ea539a8eff0d5d162701f99f9e1aabe14dd0dfb420d62362817a5d09219de7",
"2025-08-01/rustc-nightly-aarch64-apple-darwin.tar.xz": "ae83feebbc39cfd982e4ecc8297731fe79c185173aee138467b334c5404b3773",
"2025-08-01/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "9f170c30d802a349be60cf52ec46260802093cb1013ad667fc0d528b7b10152f",
"2025-08-01/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "9ae5f3cd8f557c4f6df522597c69d14398cf604cfaed2b83e767c4b77a7eaaf6",
"2025-08-01/clippy-nightly-x86_64-apple-darwin.tar.xz": "983cb9ee0b6b968188e04ab2d33743d54764b2681ce565e1b3f2b9135c696a3e",
"2025-08-01/clippy-nightly-aarch64-apple-darwin.tar.xz": "ed2219dbc49d088225e1b7c5c4390fa295066e071fddaa2714018f6bb39ddbf0",
"2025-08-01/clippy-nightly-x86_64-pc-windows-msvc.tar.xz": "911f40ab5cbdd686f40e00965271fe47c4805513a308ed01f30eafb25b448a50",
"2025-08-01/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "106463c284e48e4904c717471eeec2be5cc83a9d2cae8d6e948b52438cad2e69",
"2025-08-01/cargo-nightly-x86_64-apple-darwin.tar.xz": "6ad35c40efc41a8c531ea43235058347b6902d98a9693bf0aed7fc16d5590cef",
"2025-08-01/cargo-nightly-aarch64-apple-darwin.tar.xz": "dd28c365e9d298abc3154c797720ad36a0058f131265c9978b4c8e4e37012c8a",
"2025-08-01/cargo-nightly-x86_64-pc-windows-msvc.tar.xz": "7b431286e12d6b3834b038f078389a00cac73f351e8c3152b2504a3c06420b3b",
"2025-08-01/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "e342e305d7927cc288d386983b2bc253cfad3776b113386e903d0b302648ef47",
"2025-08-01/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "e44dd3506524d85c37b3a54bcc91d01378fd2c590b2db5c5974d12f05c1b84d1",
"2025-08-01/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "0c1b5f46dd81be4a9227b10283a0fcaa39c14fea7e81aea6fd6d9887ff6cdc41",
"2025-08-01/llvm-tools-nightly-x86_64-pc-windows-msvc.tar.xz": "423e5fd11406adccbc31b8456ceb7375ce055cdf45e90d2c3babeb2d7f58383f",
"2025-08-01/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "3c0ceb46a252647a1d4c7116d9ccae684fa5e42aaf3296419febd2c962c3b41d",
"2025-08-01/rust-std-nightly-x86_64-apple-darwin.tar.xz": "3be416003cab10f767390a753d1d16ae4d26c7421c03c98992cf1943e5b0efe8",
"2025-08-01/rust-std-nightly-aarch64-apple-darwin.tar.xz": "4046ac0ef951cb056b5028a399124f60999fa37792eab69d008d8d7965f389b4",
"2025-08-01/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "191ed9d8603c3a4fe5a7bbbc2feb72049078dae2df3d3b7d5dedf3abbf823e6e",
},
versions = [RUST_VERSION], versions = [RUST_VERSION],
) )
use_repo(rust, "rust_toolchains") use_repo(rust, "rust_toolchains")
@@ -89,8 +62,8 @@ use_repo(
"vendor_py__cc-1.2.14", "vendor_py__cc-1.2.14",
"vendor_py__clap-4.5.30", "vendor_py__clap-4.5.30",
"vendor_py__regex-1.11.1", "vendor_py__regex-1.11.1",
"vendor_py__tree-sitter-0.24.7", "vendor_py__tree-sitter-0.20.4",
"vendor_py__tree-sitter-graph-0.12.0", "vendor_py__tree-sitter-graph-0.7.0",
) )
# deps for ruby+rust # deps for ruby+rust
@@ -98,54 +71,54 @@ use_repo(
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r") tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo( use_repo(
tree_sitter_extractors_deps, tree_sitter_extractors_deps,
"vendor_ts__anyhow-1.0.100", "vendor_ts__anyhow-1.0.97",
"vendor_ts__argfile-0.2.1", "vendor_ts__argfile-0.2.1",
"vendor_ts__chalk-ir-0.104.0", "vendor_ts__chalk-ir-0.100.0",
"vendor_ts__chrono-0.4.42", "vendor_ts__chrono-0.4.40",
"vendor_ts__clap-4.5.48", "vendor_ts__clap-4.5.35",
"vendor_ts__dunce-1.0.5", "vendor_ts__dunce-1.0.5",
"vendor_ts__either-1.15.0", "vendor_ts__either-1.15.0",
"vendor_ts__encoding-0.2.33", "vendor_ts__encoding-0.2.33",
"vendor_ts__figment-0.10.19", "vendor_ts__figment-0.10.19",
"vendor_ts__flate2-1.1.2", "vendor_ts__flate2-1.1.0",
"vendor_ts__glob-0.3.3", "vendor_ts__glob-0.3.2",
"vendor_ts__globset-0.4.16", "vendor_ts__globset-0.4.15",
"vendor_ts__itertools-0.14.0", "vendor_ts__itertools-0.14.0",
"vendor_ts__lazy_static-1.5.0", "vendor_ts__lazy_static-1.5.0",
"vendor_ts__mustache-0.9.0", "vendor_ts__mustache-0.9.0",
"vendor_ts__num-traits-0.2.19", "vendor_ts__num-traits-0.2.19",
"vendor_ts__num_cpus-1.17.0", "vendor_ts__num_cpus-1.16.0",
"vendor_ts__proc-macro2-1.0.101", "vendor_ts__proc-macro2-1.0.94",
"vendor_ts__quote-1.0.41", "vendor_ts__quote-1.0.40",
"vendor_ts__ra_ap_base_db-0.0.301", "vendor_ts__ra_ap_base_db-0.0.273",
"vendor_ts__ra_ap_cfg-0.0.301", "vendor_ts__ra_ap_cfg-0.0.273",
"vendor_ts__ra_ap_hir-0.0.301", "vendor_ts__ra_ap_hir-0.0.273",
"vendor_ts__ra_ap_hir_def-0.0.301", "vendor_ts__ra_ap_hir_def-0.0.273",
"vendor_ts__ra_ap_hir_expand-0.0.301", "vendor_ts__ra_ap_hir_expand-0.0.273",
"vendor_ts__ra_ap_hir_ty-0.0.301", "vendor_ts__ra_ap_hir_ty-0.0.273",
"vendor_ts__ra_ap_ide_db-0.0.301", "vendor_ts__ra_ap_ide_db-0.0.273",
"vendor_ts__ra_ap_intern-0.0.301", "vendor_ts__ra_ap_intern-0.0.273",
"vendor_ts__ra_ap_load-cargo-0.0.301", "vendor_ts__ra_ap_load-cargo-0.0.273",
"vendor_ts__ra_ap_parser-0.0.301", "vendor_ts__ra_ap_parser-0.0.273",
"vendor_ts__ra_ap_paths-0.0.301", "vendor_ts__ra_ap_paths-0.0.273",
"vendor_ts__ra_ap_project_model-0.0.301", "vendor_ts__ra_ap_project_model-0.0.273",
"vendor_ts__ra_ap_span-0.0.301", "vendor_ts__ra_ap_span-0.0.273",
"vendor_ts__ra_ap_stdx-0.0.301", "vendor_ts__ra_ap_stdx-0.0.273",
"vendor_ts__ra_ap_syntax-0.0.301", "vendor_ts__ra_ap_syntax-0.0.273",
"vendor_ts__ra_ap_vfs-0.0.301", "vendor_ts__ra_ap_vfs-0.0.273",
"vendor_ts__rand-0.9.2", "vendor_ts__rand-0.9.0",
"vendor_ts__rayon-1.11.0", "vendor_ts__rayon-1.10.0",
"vendor_ts__regex-1.11.3", "vendor_ts__regex-1.11.1",
"vendor_ts__serde-1.0.228", "vendor_ts__serde-1.0.219",
"vendor_ts__serde_json-1.0.145", "vendor_ts__serde_json-1.0.140",
"vendor_ts__serde_with-3.14.1", "vendor_ts__serde_with-3.12.0",
"vendor_ts__syn-2.0.106", "vendor_ts__syn-2.0.100",
"vendor_ts__toml-0.9.7", "vendor_ts__toml-0.8.20",
"vendor_ts__tracing-0.1.41", "vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0", "vendor_ts__tracing-flame-0.2.0",
"vendor_ts__tracing-subscriber-0.3.20", "vendor_ts__tracing-subscriber-0.3.19",
"vendor_ts__tree-sitter-0.25.9", "vendor_ts__tree-sitter-0.24.6",
"vendor_ts__tree-sitter-embedded-template-0.25.0", "vendor_ts__tree-sitter-embedded-template-0.23.2",
"vendor_ts__tree-sitter-json-0.24.8", "vendor_ts__tree-sitter-json-0.24.8",
"vendor_ts__tree-sitter-ql-0.23.1", "vendor_ts__tree-sitter-ql-0.23.1",
"vendor_ts__tree-sitter-ruby-0.23.1", "vendor_ts__tree-sitter-ruby-0.23.1",
@@ -172,7 +145,7 @@ http_archive(
) )
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet") dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
dotnet.toolchain(dotnet_version = "9.0.300") dotnet.toolchain(dotnet_version = "9.0.100")
use_repo(dotnet, "dotnet_toolchains") use_repo(dotnet, "dotnet_toolchains")
register_toolchains("@dotnet_toolchains//:all") register_toolchains("@dotnet_toolchains//:all")
@@ -233,7 +206,6 @@ use_repo(
"kotlin-compiler-2.1.0-Beta1", "kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-2.1.20-Beta1", "kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-2.2.0-Beta1", "kotlin-compiler-2.2.0-Beta1",
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-embeddable-1.6.0", "kotlin-compiler-embeddable-1.6.0",
"kotlin-compiler-embeddable-1.6.20", "kotlin-compiler-embeddable-1.6.20",
"kotlin-compiler-embeddable-1.7.0", "kotlin-compiler-embeddable-1.7.0",
@@ -246,7 +218,6 @@ use_repo(
"kotlin-compiler-embeddable-2.1.0-Beta1", "kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-compiler-embeddable-2.1.20-Beta1", "kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-compiler-embeddable-2.2.0-Beta1", "kotlin-compiler-embeddable-2.2.0-Beta1",
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-stdlib-1.6.0", "kotlin-stdlib-1.6.0",
"kotlin-stdlib-1.6.20", "kotlin-stdlib-1.6.20",
"kotlin-stdlib-1.7.0", "kotlin-stdlib-1.7.0",
@@ -259,11 +230,10 @@ use_repo(
"kotlin-stdlib-2.1.0-Beta1", "kotlin-stdlib-2.1.0-Beta1",
"kotlin-stdlib-2.1.20-Beta1", "kotlin-stdlib-2.1.20-Beta1",
"kotlin-stdlib-2.2.0-Beta1", "kotlin-stdlib-2.2.0-Beta1",
"kotlin-stdlib-2.2.20-Beta2",
) )
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.25.0") go_sdk.download(version = "1.24.0")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod") go_deps.from_file(go_mod = "//go/extractor:go.mod")

View File

@@ -1,17 +1,14 @@
name: "actions" name: "actions"
aliases: []
display_name: "GitHub Actions" display_name: "GitHub Actions"
version: 0.0.1 version: 0.0.1
column_kind: "utf16" column_kind: "utf16"
unicode_newlines: true unicode_newlines: true
build_modes: build_modes:
- none - none
default_queries: file_coverage_languages: []
- codeql/actions-queries
# Actions workflows are not reported separately by the GitHub API, so we can't
# associate them with a specific language.
github_api_languages: [] github_api_languages: []
scc_languages: scc_languages: []
- YAML
file_types: file_types:
- name: workflow - name: workflow
display_name: GitHub Actions workflow files display_name: GitHub Actions workflow files

View File

@@ -1,10 +0,0 @@
{
"paths": [
".github/workflows/*.yml",
".github/workflows/*.yaml",
".github/reusable_workflows/**/*.yml",
".github/reusable_workflows/**/*.yaml",
"**/action.yml",
"**/action.yaml"
]
}

View File

@@ -1,2 +0,0 @@
@echo off
type "%CODEQL_EXTRACTOR_ACTIONS_ROOT%\tools\baseline-config.json"

View File

@@ -1,3 +0,0 @@
#!/bin/sh
cat "$CODEQL_EXTRACTOR_ACTIONS_ROOT/tools/baseline-config.json"

View File

@@ -1,4 +1,3 @@
ql/actions/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql
ql/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql ql/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql

View File

@@ -1,5 +1,4 @@
ql/actions/ql/src/Debug/SyntaxError.ql ql/actions/ql/src/Debug/SyntaxError.ql
ql/actions/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql ql/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql

View File

@@ -1,4 +1,3 @@
ql/actions/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql ql/actions/ql/src/Security/CWE-077/EnvPathInjectionMedium.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql ql/actions/ql/src/Security/CWE-077/EnvVarInjectionCritical.ql

View File

@@ -1,45 +1,3 @@
## 0.4.20
No user-facing changes.
## 0.4.19
No user-facing changes.
## 0.4.18
No user-facing changes.
## 0.4.17
No user-facing changes.
## 0.4.16
No user-facing changes.
## 0.4.15
No user-facing changes.
## 0.4.14
No user-facing changes.
## 0.4.13
### Bug Fixes
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
## 0.4.12
### Minor Analysis Improvements
* Fixed performance issues in the parsing of Bash scripts in workflow files,
which led to out-of-disk errors when analysing certain workflow files with
complex interpolations of shell commands or quoted strings.
## 0.4.11 ## 0.4.11
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,6 @@
---
category: minorAnalysis
---
* Fixed performance issues in the parsing of Bash scripts in workflow files,
which led to out-of-disk errors when analysing certain workflow files with
complex interpolations of shell commands or quoted strings.

View File

@@ -1,7 +0,0 @@
## 0.4.12
### Minor Analysis Improvements
* Fixed performance issues in the parsing of Bash scripts in workflow files,
which led to out-of-disk errors when analysing certain workflow files with
complex interpolations of shell commands or quoted strings.

View File

@@ -1,5 +0,0 @@
## 0.4.13
### Bug Fixes
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.

View File

@@ -1,3 +0,0 @@
## 0.4.14
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.15
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.16
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.17
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.18
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.19
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 0.4.20
No user-facing changes.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.20 lastReleaseVersion: 0.4.11

View File

@@ -70,8 +70,8 @@ class Location extends TLocation, TBaseLocation {
/** /**
* Holds if this element is at the specified location. * Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to * The location spans column `startcolumn` of line `startline` to
* column `ec` of line `el` in file `p`. * column `endcolumn` of line `endline` in file `filepath`.
* For more information, see * For more information, see
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). * [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/ */

View File

@@ -261,7 +261,7 @@ class If extends AstNode instanceof IfImpl {
} }
/** /**
* An Environment node representing a deployment environment. * An Environemnt node representing a deployment environment.
*/ */
class Environment extends AstNode instanceof EnvironmentImpl { class Environment extends AstNode instanceof EnvironmentImpl {
string getName() { result = super.getName() } string getName() { result = super.getName() }

View File

@@ -72,7 +72,7 @@ string normalizePath(string path) {
then result = path then result = path
else else
// foo -> GITHUB_WORKSPACE/foo // foo -> GITHUB_WORKSPACE/foo
if path.regexpMatch("^[^$/~].*") if path.regexpMatch("^[^/~].*")
then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "") then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "")
else else
// ~/foo -> ~/foo // ~/foo -> ~/foo

View File

@@ -125,11 +125,12 @@ abstract class AstNodeImpl extends TAstNode {
* Gets the enclosing Step. * Gets the enclosing Step.
*/ */
StepImpl getEnclosingStep() { StepImpl getEnclosingStep() {
this instanceof StepImpl and if this instanceof StepImpl
result = this then result = this
or else
this instanceof ScalarValueImpl and if this instanceof ScalarValueImpl
result.getAChildNode*() = this.getParentNode() then result.getAChildNode*() = this.getParentNode()
else none()
} }
/** /**
@@ -1415,8 +1416,9 @@ class ExternalJobImpl extends JobImpl, UsesImpl {
override string getVersion() { override string getVersion() {
exists(YamlString name | exists(YamlString name |
n.lookup("uses") = name and n.lookup("uses") = name and
not name.getValue().matches("\\.%") and if not name.getValue().matches("\\.%")
result = name.getValue().regexpCapture(repoUsesParser(), 4) then result = name.getValue().regexpCapture(repoUsesParser(), 4)
else none()
) )
} }
} }

View File

@@ -286,7 +286,7 @@ private module Cached {
/** /**
* Holds if `cfn` is the `i`th node in basic block `bb`. * Holds if `cfn` is the `i`th node in basic block `bb`.
* *
* In other words, `i` is the shortest distance from a node `bbStart` * In other words, `i` is the shortest distance from a node `bb`
* that starts a basic block to `cfn` along the `intraBBSucc` relation. * that starts a basic block to `cfn` along the `intraBBSucc` relation.
*/ */
cached cached

View File

@@ -3,8 +3,6 @@ private import codeql.controlflow.Cfg as CfgShared
private import codeql.Locations private import codeql.Locations
module Completion { module Completion {
import codeql.controlflow.SuccessorType
private newtype TCompletion = private newtype TCompletion =
TSimpleCompletion() or TSimpleCompletion() or
TBooleanCompletion(boolean b) { b in [false, true] } or TBooleanCompletion(boolean b) { b in [false, true] } or
@@ -27,7 +25,7 @@ module Completion {
override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) } override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) }
override DirectSuccessor getAMatchingSuccessorType() { any() } override NormalSuccessor getAMatchingSuccessorType() { any() }
} }
class BooleanCompletion extends NormalCompletion, TBooleanCompletion { class BooleanCompletion extends NormalCompletion, TBooleanCompletion {
@@ -51,6 +49,34 @@ module Completion {
override ReturnSuccessor getAMatchingSuccessorType() { any() } override ReturnSuccessor getAMatchingSuccessorType() { any() }
} }
cached
private newtype TSuccessorType =
TNormalSuccessor() or
TBooleanSuccessor(boolean b) { b in [false, true] } or
TReturnSuccessor()
class SuccessorType extends TSuccessorType {
string toString() { none() }
}
class NormalSuccessor extends SuccessorType, TNormalSuccessor {
override string toString() { result = "successor" }
}
class BooleanSuccessor extends SuccessorType, TBooleanSuccessor {
boolean value;
BooleanSuccessor() { this = TBooleanSuccessor(value) }
override string toString() { result = value.toString() }
boolean getValue() { result = value }
}
class ReturnSuccessor extends SuccessorType, TReturnSuccessor {
override string toString() { result = "return" }
}
} }
module CfgScope { module CfgScope {
@@ -101,8 +127,14 @@ private module Implementation implements CfgShared::InputSig<Location> {
last(scope.(CompositeAction), e, c) last(scope.(CompositeAction), e, c)
} }
predicate successorTypeIsSimple(SuccessorType t) { t instanceof NormalSuccessor }
predicate successorTypeIsCondition(SuccessorType t) { t instanceof BooleanSuccessor }
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() } SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
predicate isAbnormalExitType(SuccessorType t) { none() }
int idOfAstNode(AstNode node) { none() } int idOfAstNode(AstNode node) { none() }
int idOfCfgScope(CfgScope scope) { none() } int idOfCfgScope(CfgScope scope) { none() }

View File

@@ -63,10 +63,10 @@ predicate madSource(DataFlow::Node source, string kind, string fieldName) {
( (
if fieldName.trim().matches("env.%") if fieldName.trim().matches("env.%")
then source.asExpr() = uses.getInScopeEnvVarExpr(fieldName.trim().replaceAll("env.", "")) then source.asExpr() = uses.getInScopeEnvVarExpr(fieldName.trim().replaceAll("env.", ""))
else ( else
fieldName.trim().matches("output.%") and if fieldName.trim().matches("output.%")
source.asExpr() = uses then source.asExpr() = uses
) else none()
) )
) )
} }

View File

@@ -31,14 +31,14 @@ abstract class RemoteFlowSource extends SourceNode {
class GitHubCtxSource extends RemoteFlowSource { class GitHubCtxSource extends RemoteFlowSource {
string flag; string flag;
string event; string event;
GitHubExpression e;
GitHubCtxSource() { GitHubCtxSource() {
exists(GitHubExpression e | this.asExpr() = e and
this.asExpr() = e and // github.head_ref
// github.head_ref e.getFieldName() = "head_ref" and
e.getFieldName() = "head_ref" and flag = "branch" and
flag = "branch" (
|
event = e.getATriggerEvent().getName() and event = e.getATriggerEvent().getName() and
event = "pull_request_target" event = "pull_request_target"
or or
@@ -148,6 +148,7 @@ class GhCLICommandSource extends RemoteFlowSource, CommandSource {
class GitHubEventPathSource extends RemoteFlowSource, CommandSource { class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
string cmd; string cmd;
string flag; string flag;
string access_path;
Run run; Run run;
// Examples // Examples
@@ -162,7 +163,7 @@ class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
run.getScript().getACommand() = cmd and run.getScript().getACommand() = cmd and
cmd.matches("jq%") and cmd.matches("jq%") and
cmd.matches("%GITHUB_EVENT_PATH%") and cmd.matches("%GITHUB_EVENT_PATH%") and
exists(string regexp, string access_path | exists(string regexp |
untrustedEventPropertiesDataModel(regexp, flag) and untrustedEventPropertiesDataModel(regexp, flag) and
not flag = "json" and not flag = "json" and
access_path = "github.event" + cmd.regexpCapture(".*\\s+([^\\s]+)\\s+.*", 1) and access_path = "github.event" + cmd.regexpCapture(".*\\s+([^\\s]+)\\s+.*", 1) and

View File

@@ -1,7 +1,6 @@
private import actions private import actions
private import codeql.actions.TaintTracking private import codeql.actions.TaintTracking
private import codeql.actions.dataflow.ExternalFlow private import codeql.actions.dataflow.ExternalFlow
private import codeql.actions.security.ControlChecks
import codeql.actions.dataflow.FlowSources import codeql.actions.dataflow.FlowSources
import codeql.actions.DataFlow import codeql.actions.DataFlow
@@ -19,6 +18,7 @@ abstract class ArgumentInjectionSink extends DataFlow::Node {
*/ */
class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink { class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
string command; string command;
string argument;
ArgumentInjectionFromEnvVarSink() { ArgumentInjectionFromEnvVarSink() {
exists(Run run, string var | exists(Run run, string var |
@@ -27,7 +27,7 @@ class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
exists(run.getInScopeEnvVarExpr(var)) or exists(run.getInScopeEnvVarExpr(var)) or
var = "GITHUB_HEAD_REF" var = "GITHUB_HEAD_REF"
) and ) and
run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, _) run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, argument)
) )
} }
@@ -43,12 +43,13 @@ class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
*/ */
class ArgumentInjectionFromCommandSink extends ArgumentInjectionSink { class ArgumentInjectionFromCommandSink extends ArgumentInjectionSink {
string command; string command;
string argument;
ArgumentInjectionFromCommandSink() { ArgumentInjectionFromCommandSink() {
exists(CommandSource source, Run run | exists(CommandSource source, Run run |
run = source.getEnclosingRun() and run = source.getEnclosingRun() and
this.asExpr() = run.getScript() and this.asExpr() = run.getScript() and
run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, _) run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, argument)
) )
} }
@@ -64,16 +65,6 @@ class ArgumentInjectionFromMaDSink extends ArgumentInjectionSink {
override string getCommand() { result = "unknown" } override string getCommand() { result = "unknown" }
} }
/**
* Gets the event that is relevant for the given node in the context of argument injection.
*
* This is used to highlight the event in the query results when an alert is raised.
*/
Event getRelevantEventInPrivilegedContext(DataFlow::Node node) {
inPrivilegedContext(node.asExpr(), result) and
not exists(ControlCheck check | check.protects(node.asExpr(), result, "argument-injection"))
}
/** /**
* A taint-tracking configuration for unsafe user input * A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a code script. * that is used to construct and evaluate a code script.
@@ -97,14 +88,6 @@ private module ArgumentInjectionConfig implements DataFlow::ConfigSig {
run.getScript().getAnEnvReachingArgumentInjectionSink(var, _, _) run.getScript().getAnEnvReachingArgumentInjectionSink(var, _, _)
) )
} }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
result = getRelevantEventInPrivilegedContext(sink).getLocation()
}
} }
/** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */ /** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */

View File

@@ -4,7 +4,6 @@ import codeql.actions.DataFlow
import codeql.actions.dataflow.FlowSources import codeql.actions.dataflow.FlowSources
import codeql.actions.security.PoisonableSteps import codeql.actions.security.PoisonableSteps
import codeql.actions.security.UntrustedCheckoutQuery import codeql.actions.security.UntrustedCheckoutQuery
import codeql.actions.security.ControlChecks
string unzipRegexp() { result = "(unzip|tar)\\s+.*" } string unzipRegexp() { result = "(unzip|tar)\\s+.*" }
@@ -125,6 +124,8 @@ class LegitLabsDownloadArtifactActionStep extends UntrustedArtifactDownloadStep,
} }
class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, UsesStep { class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, UsesStep {
string script;
ActionsGitHubScriptDownloadStep() { ActionsGitHubScriptDownloadStep() {
// eg: // eg:
// - uses: actions/github-script@v6 // - uses: actions/github-script@v6
@@ -147,14 +148,12 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
// var fs = require('fs'); // var fs = require('fs');
// fs.writeFileSync('${{github.workspace}}/test-results.zip', Buffer.from(download.data)); // fs.writeFileSync('${{github.workspace}}/test-results.zip', Buffer.from(download.data));
this.getCallee() = "actions/github-script" and this.getCallee() = "actions/github-script" and
exists(string script | this.getArgument("script") = script and
this.getArgument("script") = script and script.matches("%listWorkflowRunArtifacts(%") and
script.matches("%listWorkflowRunArtifacts(%") and script.matches("%downloadArtifact(%") and
script.matches("%downloadArtifact(%") and script.matches("%writeFileSync(%") and
script.matches("%writeFileSync(%") and // Filter out artifacts that were created by pull-request.
// Filter out artifacts that were created by pull-request. not script.matches("%exclude_pull_requests: true%")
not script.matches("%exclude_pull_requests: true%")
)
} }
override string getPath() { override string getPath() {
@@ -171,10 +170,10 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
.getScript() .getScript()
.getACommand() .getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3))) .regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else ( else
this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) and if this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp())
result = "GITHUB_WORKSPACE/" then result = "GITHUB_WORKSPACE/"
) else none()
} }
} }
@@ -207,13 +206,12 @@ class GHRunArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
.getScript() .getScript()
.getACommand() .getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3))) .regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else ( else
( if
this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) or this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) or
this.getScript().getACommand().regexpMatch(unzipRegexp()) this.getScript().getACommand().regexpMatch(unzipRegexp())
) and then result = "GITHUB_WORKSPACE/"
result = "GITHUB_WORKSPACE/" else none()
)
} }
} }
@@ -260,15 +258,13 @@ class DirectArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
class ArtifactPoisoningSink extends DataFlow::Node { class ArtifactPoisoningSink extends DataFlow::Node {
UntrustedArtifactDownloadStep download; UntrustedArtifactDownloadStep download;
PoisonableStep poisonable;
ArtifactPoisoningSink() { ArtifactPoisoningSink() {
exists(PoisonableStep poisonable | download.getAFollowingStep() = poisonable and
download.getAFollowingStep() = poisonable and // excluding artifacts downloaded to /tmp
// excluding artifacts downloaded to the temporary directory not download.getPath().regexpMatch("^/tmp.*") and
not download.getPath().regexpMatch("^/tmp.*") and (
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*")
|
poisonable.(Run).getScript() = this.asExpr() and poisonable.(Run).getScript() = this.asExpr() and
( (
// Check if the poisonable step is a local script execution step // Check if the poisonable step is a local script execution step
@@ -294,16 +290,6 @@ class ArtifactPoisoningSink extends DataFlow::Node {
string getPath() { result = download.getPath() } string getPath() { result = download.getPath() }
} }
/**
* Gets the event that is relevant for the given node in the context of artifact poisoning.
*
* This is used to highlight the event in the query results when an alert is raised.
*/
Event getRelevantEventInPrivilegedContext(DataFlow::Node node) {
inPrivilegedContext(node.asExpr(), result) and
not exists(ControlCheck check | check.protects(node.asExpr(), result, "artifact-poisoning"))
}
/** /**
* A taint-tracking configuration for unsafe artifacts * A taint-tracking configuration for unsafe artifacts
* that is used may lead to artifact poisoning * that is used may lead to artifact poisoning
@@ -330,14 +316,6 @@ private module ArtifactPoisoningConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand()) exists(run.getScript().getAFileReadCommand())
) )
} }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
result = getRelevantEventInPrivilegedContext(sink).getLocation()
}
} }
/** Tracks flow of unsafe artifacts that is used in an insecure way. */ /** Tracks flow of unsafe artifacts that is used in an insecure way. */

View File

@@ -3,8 +3,6 @@ private import codeql.actions.TaintTracking
private import codeql.actions.dataflow.ExternalFlow private import codeql.actions.dataflow.ExternalFlow
import codeql.actions.dataflow.FlowSources import codeql.actions.dataflow.FlowSources
import codeql.actions.DataFlow import codeql.actions.DataFlow
import codeql.actions.security.ControlChecks
import codeql.actions.security.CachePoisoningQuery
class CodeInjectionSink extends DataFlow::Node { class CodeInjectionSink extends DataFlow::Node {
CodeInjectionSink() { CodeInjectionSink() {
@@ -13,46 +11,6 @@ class CodeInjectionSink extends DataFlow::Node {
} }
} }
/**
* Get the relevant event for the sink in CodeInjectionCritical.ql.
*/
Event getRelevantCriticalEventForSink(DataFlow::Node sink) {
inPrivilegedContext(sink.asExpr(), result) and
not exists(ControlCheck check | check.protects(sink.asExpr(), result, "code-injection")) and
// exclude cases where the sink is a JS script and the expression uses toJson
not exists(UsesStep script |
script.getCallee() = "actions/github-script" and
script.getArgumentExpr("script") = sink.asExpr() and
exists(getAToJsonReferenceExpression(sink.asExpr().(Expression).getExpression(), _))
)
}
/**
* Get the relevant event for the sink in CachePoisoningViaCodeInjection.ql.
*/
Event getRelevantCachePoisoningEventForSink(DataFlow::Node sink) {
exists(LocalJob job |
job = sink.asExpr().getEnclosingJob() and
job.getATriggerEvent() = result and
// job can be triggered by an external user
result.isExternallyTriggerable() and
// excluding privileged workflows since they can be exploited in easier circumstances
// which is covered by `actions/code-injection/critical`
not job.isPrivilegedExternallyTriggerable(result) and
(
// the workflow runs in the context of the default branch
runsOnDefaultBranch(result)
or
// the workflow caller runs in the context of the default branch
result.getName() = "workflow_call" and
exists(ExternalJob caller |
caller.getCallee() = job.getLocation().getFile().getRelativePath() and
runsOnDefaultBranch(caller.getATriggerEvent())
)
)
)
}
/** /**
* A taint-tracking configuration for unsafe user input * A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a code script. * that is used to construct and evaluate a code script.
@@ -77,16 +35,6 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand()) exists(run.getScript().getAFileReadCommand())
) )
} }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
result = getRelevantCriticalEventForSink(sink).getLocation()
or
result = getRelevantCachePoisoningEventForSink(sink).getLocation()
}
} }
/** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */ /** Tracks flow of unsafe user input that is used to construct and evaluate a code script. */

View File

@@ -3,20 +3,11 @@ private import codeql.actions.TaintTracking
private import codeql.actions.dataflow.ExternalFlow private import codeql.actions.dataflow.ExternalFlow
import codeql.actions.dataflow.FlowSources import codeql.actions.dataflow.FlowSources
import codeql.actions.DataFlow import codeql.actions.DataFlow
import codeql.actions.security.ControlChecks
private class CommandInjectionSink extends DataFlow::Node { private class CommandInjectionSink extends DataFlow::Node {
CommandInjectionSink() { madSink(this, "command-injection") } CommandInjectionSink() { madSink(this, "command-injection") }
} }
/** Get the relevant event for the sink in CommandInjectionCritical.ql. */
Event getRelevantEventInPrivilegedContext(DataFlow::Node sink) {
inPrivilegedContext(sink.asExpr(), result) and
not exists(ControlCheck check |
check.protects(sink.asExpr(), result, ["command-injection", "code-injection"])
)
}
/** /**
* A taint-tracking configuration for unsafe user input * A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate a system command. * that is used to construct and evaluate a system command.
@@ -25,16 +16,6 @@ private module CommandInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjectionSink } predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjectionSink }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
result = getRelevantEventInPrivilegedContext(sink).getLocation()
}
} }
/** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */ /** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */

View File

@@ -159,8 +159,11 @@ abstract class CommentVsHeadDateCheck extends ControlCheck {
/* Specific implementations of control checks */ /* Specific implementations of control checks */
class LabelIfCheck extends LabelCheck instanceof If { class LabelIfCheck extends LabelCheck instanceof If {
string condition;
LabelIfCheck() { LabelIfCheck() {
exists(string condition | condition = normalizeExpr(this.getCondition()) | condition = normalizeExpr(this.getCondition()) and
(
// eg: contains(github.event.pull_request.labels.*.name, 'safe to test') // eg: contains(github.event.pull_request.labels.*.name, 'safe to test')
condition.regexpMatch(".*(^|[^!])contains\\(\\s*github\\.event\\.pull_request\\.labels\\b.*") condition.regexpMatch(".*(^|[^!])contains\\(\\s*github\\.event\\.pull_request\\.labels\\b.*")
or or

View File

@@ -72,25 +72,6 @@ class EnvPathInjectionFromMaDSink extends EnvPathInjectionSink {
EnvPathInjectionFromMaDSink() { madSink(this, "envpath-injection") } EnvPathInjectionFromMaDSink() { madSink(this, "envpath-injection") }
} }
/**
* Get the relevant event for a sink in EnvPathInjectionCritical.ql where the source type is "artifact".
*/
Event getRelevantArtifactEventInPrivilegedContext(DataFlow::Node sink) {
inPrivilegedContext(sink.asExpr(), result) and
not exists(ControlCheck check |
check.protects(sink.asExpr(), result, ["untrusted-checkout", "artifact-poisoning"])
) and
sink instanceof EnvPathInjectionFromFileReadSink
}
/**
* Get the relevant event for a sink in EnvPathInjectionCritical.ql where the source type is not "artifact".
*/
Event getRelevantNonArtifactEventInPrivilegedContext(DataFlow::Node sink) {
inPrivilegedContext(sink.asExpr(), result) and
not exists(ControlCheck check | check.protects(sink.asExpr(), result, "code-injection"))
}
/** /**
* A taint-tracking configuration for unsafe user input * A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate an environment variable. * that is used to construct and evaluate an environment variable.
@@ -127,16 +108,6 @@ private module EnvPathInjectionConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand()) exists(run.getScript().getAFileReadCommand())
) )
} }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
result = getRelevantArtifactEventInPrivilegedContext(sink).getLocation()
or
result = getRelevantNonArtifactEventInPrivilegedContext(sink).getLocation()
}
} }
/** Tracks flow of unsafe user input that is used to construct and evaluate the PATH environment variable. */ /** Tracks flow of unsafe user input that is used to construct and evaluate the PATH environment variable. */

View File

@@ -55,8 +55,12 @@ class EnvVarInjectionFromFileReadSink extends EnvVarInjectionSink {
* echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV * echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV
*/ */
class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink { class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink {
CommandSource inCommand;
string injectedVar;
string command;
EnvVarInjectionFromCommandSink() { EnvVarInjectionFromCommandSink() {
exists(Run run, CommandSource inCommand, string injectedVar, string command | exists(Run run |
this.asExpr() = inCommand.getEnclosingRun().getScript() and this.asExpr() = inCommand.getEnclosingRun().getScript() and
run = inCommand.getEnclosingRun() and run = inCommand.getEnclosingRun() and
run.getScript().getACmdReachingGitHubEnvWrite(inCommand.getCommand(), injectedVar) and run.getScript().getACmdReachingGitHubEnvWrite(inCommand.getCommand(), injectedVar) and
@@ -82,8 +86,12 @@ class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink {
* echo "FOO=$BODY" >> $GITHUB_ENV * echo "FOO=$BODY" >> $GITHUB_ENV
*/ */
class EnvVarInjectionFromEnvVarSink extends EnvVarInjectionSink { class EnvVarInjectionFromEnvVarSink extends EnvVarInjectionSink {
string inVar;
string injectedVar;
string command;
EnvVarInjectionFromEnvVarSink() { EnvVarInjectionFromEnvVarSink() {
exists(Run run, string inVar, string injectedVar, string command | exists(Run run |
run.getScript() = this.asExpr() and run.getScript() = this.asExpr() and
exists(run.getInScopeEnvVarExpr(inVar)) and exists(run.getInScopeEnvVarExpr(inVar)) and
run.getScript().getAnEnvReachingGitHubEnvWrite(inVar, injectedVar) and run.getScript().getAnEnvReachingGitHubEnvWrite(inVar, injectedVar) and
@@ -118,32 +126,6 @@ class EnvVarInjectionFromMaDSink extends EnvVarInjectionSink {
EnvVarInjectionFromMaDSink() { madSink(this, "envvar-injection") } EnvVarInjectionFromMaDSink() { madSink(this, "envvar-injection") }
} }
/**
* Get the relevant event for a sink in EnvVarInjectionCritical.ql where the source type is "artifact".
*/
Event getRelevantArtifactEventInPrivilegedContext(DataFlow::Node sink) {
inPrivilegedContext(sink.asExpr(), result) and
not exists(ControlCheck check |
check
.protects(sink.asExpr(), result,
["envvar-injection", "untrusted-checkout", "artifact-poisoning"])
) and
(
sink instanceof EnvVarInjectionFromFileReadSink or
madSink(sink, "envvar-injection")
)
}
/**
* Get the relevant event for a sink in EnvVarInjectionCritical.ql where the source type is not "artifact".
*/
Event getRelevantNonArtifactEventInPrivilegedContext(DataFlow::Node sink) {
inPrivilegedContext(sink.asExpr(), result) and
not exists(ControlCheck check |
check.protects(sink.asExpr(), result, ["envvar-injection", "code-injection"])
)
}
/** /**
* A taint-tracking configuration for unsafe user input * A taint-tracking configuration for unsafe user input
* that is used to construct and evaluate an environment variable. * that is used to construct and evaluate an environment variable.
@@ -181,16 +163,6 @@ private module EnvVarInjectionConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand()) exists(run.getScript().getAFileReadCommand())
) )
} }
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSinkLocation(DataFlow::Node sink) {
result = sink.getLocation()
or
result = getRelevantArtifactEventInPrivilegedContext(sink).getLocation()
or
result = getRelevantNonArtifactEventInPrivilegedContext(sink).getLocation()
}
} }
/** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */ /** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */

View File

@@ -99,14 +99,18 @@ class OutputClobberingFromEnvVarSink extends OutputClobberingSink {
* echo $BODY * echo $BODY
*/ */
class WorkflowCommandClobberingFromEnvVarSink extends OutputClobberingSink { class WorkflowCommandClobberingFromEnvVarSink extends OutputClobberingSink {
string clobbering_var;
string clobbered_value;
WorkflowCommandClobberingFromEnvVarSink() { WorkflowCommandClobberingFromEnvVarSink() {
exists(Run run, string workflow_cmd_stmt, string clobbering_stmt, string clobbering_var | exists(Run run, string workflow_cmd_stmt, string clobbering_stmt |
run.getScript() = this.asExpr() and run.getScript() = this.asExpr() and
run.getScript().getAStmt() = clobbering_stmt and run.getScript().getAStmt() = clobbering_stmt and
clobbering_stmt.regexpMatch("echo\\s+(-e\\s+)?(\"|')?\\$(\\{)?" + clobbering_var + ".*") and clobbering_stmt.regexpMatch("echo\\s+(-e\\s+)?(\"|')?\\$(\\{)?" + clobbering_var + ".*") and
exists(run.getInScopeEnvVarExpr(clobbering_var)) and exists(run.getInScopeEnvVarExpr(clobbering_var)) and
run.getScript().getAStmt() = workflow_cmd_stmt and run.getScript().getAStmt() = workflow_cmd_stmt and
exists(trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1))) clobbered_value =
trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1))
) )
} }
} }

View File

@@ -1,8 +1,10 @@
import actions import actions
class UnversionedImmutableAction extends UsesStep { class UnversionedImmutableAction extends UsesStep {
string immutable_action;
UnversionedImmutableAction() { UnversionedImmutableAction() {
isImmutableAction(this, _) and isImmutableAction(this, immutable_action) and
not isSemVer(this.getVersion()) not isSemVer(this.getVersion())
} }
} }

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all name: codeql/actions-all
version: 0.4.20 version: 0.4.12-dev
library: true library: true
warnOnImplicitThis: true warnOnImplicitThis: true
dependencies: dependencies:

View File

@@ -1,41 +1,3 @@
## 0.6.12
No user-facing changes.
## 0.6.11
No user-facing changes.
## 0.6.10
No user-facing changes.
## 0.6.9
### Minor Analysis Improvements
* Actions analysis now reports file coverage information on the CodeQL status page.
## 0.6.8
No user-facing changes.
## 0.6.7
No user-facing changes.
## 0.6.6
No user-facing changes.
## 0.6.5
No user-facing changes.
## 0.6.4
No user-facing changes.
## 0.6.3 ## 0.6.3
No user-facing changes. No user-facing changes.

View File

@@ -1,13 +0,0 @@
/**
* @id actions/diagnostics/successfully-extracted-files
* @name Extracted files
* @description List all files that were extracted.
* @kind diagnostic
* @tags successfully-extracted-files
*/
private import codeql.Locations
from File f
where exists(f.getRelativePath())
select f, ""

View File

@@ -1,4 +1,6 @@
## Overview # Environment Path Injection
## Description
GitHub Actions allow to define the system PATH variable by writing to a file pointed to by the `GITHUB_PATH` environment variable. Writing to this file appends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job. GitHub Actions allow to define the system PATH variable by writing to a file pointed to by the `GITHUB_PATH` environment variable. Writing to this file appends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job.
@@ -10,11 +12,11 @@ echo "$HOME/.local/bin" >> $GITHUB_PATH
If an attacker can control the contents of the system PATH, they are able to influence what commands are run in subsequent steps of the same job. If an attacker can control the contents of the system PATH, they are able to influence what commands are run in subsequent steps of the same job.
## Recommendation ## Recommendations
Do not allow untrusted data to influence the system PATH: Avoid using untrusted data sources (e.g., artifact content) to define the system PATH. Do not allow untrusted data to influence the system PATH: Avoid using untrusted data sources (e.g., artifact content) to define the system PATH.
## Example ## Examples
### Incorrect Usage ### Incorrect Usage
@@ -34,4 +36,4 @@ If an attacker can manipulate the value being set, such as through artifact down
## References ## References
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions). - [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)

View File

@@ -21,12 +21,18 @@ import codeql.actions.security.ControlChecks
from EnvPathInjectionFlow::PathNode source, EnvPathInjectionFlow::PathNode sink, Event event from EnvPathInjectionFlow::PathNode source, EnvPathInjectionFlow::PathNode sink, Event event
where where
EnvPathInjectionFlow::flowPath(source, sink) and EnvPathInjectionFlow::flowPath(source, sink) and
inPrivilegedContext(sink.getNode().asExpr(), event) and
( (
not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode()) not exists(ControlCheck check |
check.protects(sink.getNode().asExpr(), event, "code-injection")
)
or or
source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
event = getRelevantArtifactEventInPrivilegedContext(sink.getNode()) not exists(ControlCheck check |
check.protects(sink.getNode().asExpr(), event, ["untrusted-checkout", "artifact-poisoning"])
) and
sink.getNode() instanceof EnvPathInjectionFromFileReadSink
) )
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"Potential PATH environment variable injection in $@, which may be controlled by an external user ($@).", "Potential PATH environment variable injection in $@, which may be controlled by an external user ($@).",

View File

@@ -1,4 +1,6 @@
## Overview # Environment Path Injection
## Description
GitHub Actions allow to define the system PATH variable by writing to a file pointed to by the `GITHUB_PATH` environment variable. Writing to this file appends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job. GitHub Actions allow to define the system PATH variable by writing to a file pointed to by the `GITHUB_PATH` environment variable. Writing to this file appends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job.
@@ -10,11 +12,11 @@ echo "$HOME/.local/bin" >> $GITHUB_PATH
If an attacker can control the contents of the system PATH, they are able to influence what commands are run in subsequent steps of the same job. If an attacker can control the contents of the system PATH, they are able to influence what commands are run in subsequent steps of the same job.
## Recommendation ## Recommendations
Do not allow untrusted data to influence the system PATH: Avoid using untrusted data sources (e.g., artifact content) to define the system PATH. Do not allow untrusted data to influence the system PATH: Avoid using untrusted data sources (e.g., artifact content) to define the system PATH.
## Example ## Examples
### Incorrect Usage ### Incorrect Usage
@@ -34,4 +36,4 @@ If an attacker can manipulate the value being set, such as through artifact down
## References ## References
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions). - [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)

View File

@@ -1,4 +1,6 @@
## Overview # Environment Variable Injection
## Description
GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable: GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable:
@@ -35,7 +37,7 @@ steps:
If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`. If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`.
## Recommendation ## Recommendations
1. **Do not allow untrusted data to influence environment variables**: 1. **Do not allow untrusted data to influence environment variables**:
@@ -62,7 +64,7 @@ If an attacker can control the values assigned to environment variables and ther
} >> "$GITHUB_ENV" } >> "$GITHUB_ENV"
``` ```
## Example ## Examples
### Example of Vulnerability ### Example of Vulnerability
@@ -111,5 +113,5 @@ An attacker is be able to run arbitrary code by injecting environment variables
## References ## References
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions). - [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)
- Synacktiv: [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation). - [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation)

View File

@@ -22,15 +22,26 @@ import codeql.actions.security.ControlChecks
from EnvVarInjectionFlow::PathNode source, EnvVarInjectionFlow::PathNode sink, Event event from EnvVarInjectionFlow::PathNode source, EnvVarInjectionFlow::PathNode sink, Event event
where where
EnvVarInjectionFlow::flowPath(source, sink) and EnvVarInjectionFlow::flowPath(source, sink) and
inPrivilegedContext(sink.getNode().asExpr(), event) and
// exclude paths to file read sinks from non-artifact sources // exclude paths to file read sinks from non-artifact sources
( (
// source is text // source is text
not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and not source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode()) not exists(ControlCheck check |
check.protects(sink.getNode().asExpr(), event, ["envvar-injection", "code-injection"])
)
or or
// source is an artifact or a file from an untrusted checkout // source is an artifact or a file from an untrusted checkout
source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
event = getRelevantArtifactEventInPrivilegedContext(sink.getNode()) not exists(ControlCheck check |
check
.protects(sink.getNode().asExpr(), event,
["envvar-injection", "untrusted-checkout", "artifact-poisoning"])
) and
(
sink.getNode() instanceof EnvVarInjectionFromFileReadSink or
madSink(sink.getNode(), "envvar-injection")
)
) )
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"Potential environment variable injection in $@, which may be controlled by an external user ($@).", "Potential environment variable injection in $@, which may be controlled by an external user ($@).",

View File

@@ -1,4 +1,6 @@
## Overview # Environment Variable Injection
## Description
GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable: GitHub Actions allow to define environment variables by writing to a file pointed to by the `GITHUB_ENV` environment variable:
@@ -35,7 +37,7 @@ steps:
If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`. If an attacker can control the values assigned to environment variables and there is no sanitization in place, the attacker will be able to inject additional variables by injecting new lines or `{delimiters}`.
## Recommendation ## Recommendations
1. **Do not allow untrusted data to influence environment variables**: 1. **Do not allow untrusted data to influence environment variables**:
@@ -62,7 +64,7 @@ If an attacker can control the values assigned to environment variables and ther
} >> "$GITHUB_ENV" } >> "$GITHUB_ENV"
``` ```
## Example ## Examples
### Example of Vulnerability ### Example of Vulnerability
@@ -111,5 +113,5 @@ An attacker would be able to run arbitrary code by injecting environment variabl
## References ## References
- GitHub Docs: [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions). - [Workflow commands for GitHub Actions](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions)
- Synacktiv: [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation). - [GitHub Actions Exploitation: Repo Jacking and Environment Manipulation](https://www.synacktiv.com/publications/github-actions-exploitation-repo-jacking-and-environment-manipulation)

View File

@@ -1,16 +1,18 @@
## Overview # Code Injection in GitHub Actions
## Description
Using user-controlled input in GitHub Actions may lead to code injection in contexts like _run:_ or _script:_. Using user-controlled input in GitHub Actions may lead to code injection in contexts like _run:_ or _script:_.
Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing an attacker to make changes to the repository. Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing an attacker to make changes to the repository.
## Recommendation ## Recommendations
The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not _${{ env.VAR }}_). The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not _${{ env.VAR }}_).
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN. It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
## Example ## Examples
### Incorrect Usage ### Incorrect Usage

View File

@@ -22,8 +22,15 @@ import codeql.actions.security.ControlChecks
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event
where where
CodeInjectionFlow::flowPath(source, sink) and CodeInjectionFlow::flowPath(source, sink) and
event = getRelevantCriticalEventForSink(sink.getNode()) and inPrivilegedContext(sink.getNode().asExpr(), event) and
source.getNode().(RemoteFlowSource).getEventName() = event.getName() source.getNode().(RemoteFlowSource).getEventName() = event.getName() and
not exists(ControlCheck check | check.protects(sink.getNode().asExpr(), event, "code-injection")) and
// exclude cases where the sink is a JS script and the expression uses toJson
not exists(UsesStep script |
script.getCallee() = "actions/github-script" and
script.getArgumentExpr("script") = sink.getNode().asExpr() and
exists(getAToJsonReferenceExpression(sink.getNode().asExpr().(Expression).getExpression(), _))
)
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"Potential code injection in $@, which may be controlled by an external user ($@).", sink, "Potential code injection in $@, which may be controlled by an external user ($@).", sink,
sink.getNode().asExpr().(Expression).getRawExpression(), event, event.getName() sink.getNode().asExpr().(Expression).getRawExpression(), event, event.getName()

View File

@@ -1,16 +1,18 @@
## Overview # Code Injection in GitHub Actions
## Description
Using user-controlled input in GitHub Actions may lead to code injection in contexts like _run:_ or _script:_. Using user-controlled input in GitHub Actions may lead to code injection in contexts like _run:_ or _script:_.
Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing an attacker to make changes to the repository. Code injection in GitHub Actions may allow an attacker to exfiltrate any secrets used in the workflow and the temporary GitHub repository authorization token. The token may have write access to the repository, allowing an attacker to make changes to the repository.
## Recommendation ## Recommendations
The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not _${{ env.VAR }}_). The best practice to avoid code injection vulnerabilities in GitHub workflows is to set the untrusted input value of the expression to an intermediate environment variable and then use the environment variable using the native syntax of the shell/script interpreter (that is, not _${{ env.VAR }}_).
It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN. It is also recommended to limit the permissions of any tokens used by a workflow such as the GITHUB_TOKEN.
## Example ## Examples
### Incorrect Usage ### Incorrect Usage

View File

@@ -1,11 +1,13 @@
## Overview # Use of Actions with known vulnerabilities
## Description
The security of the workflow and the repository could be compromised by GitHub Actions workflows that utilize GitHub Actions with known vulnerabilities. The security of the workflow and the repository could be compromised by GitHub Actions workflows that utilize GitHub Actions with known vulnerabilities.
## Recommendation ## Recommendations
Either remove the component from the workflow or upgrade it to a version that is not vulnerable. Either remove the component from the workflow or upgrade it to a version that is not vulnerable.
## References ## References
- GitHub Docs: [Keeping your actions up to date with Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot). - [GitHub Docs: Keeping your actions up to date with Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot)

View File

@@ -1,21 +1,12 @@
## Overview # Actions Job and Workflow Permissions are not set
## Description
If a GitHub Actions job or workflow has no explicit permissions set, then the repository permissions are used. Repositories created under organizations inherit the organization permissions. The organizations or repositories created before February 2023 have the default permissions set to read-write. Often these permissions do not adhere to the principle of least privilege and can be reduced to read-only, leaving the `write` permission only to a specific types as `issues: write` or `pull-requests: write`. If a GitHub Actions job or workflow has no explicit permissions set, then the repository permissions are used. Repositories created under organizations inherit the organization permissions. The organizations or repositories created before February 2023 have the default permissions set to read-write. Often these permissions do not adhere to the principle of least privilege and can be reduced to read-only, leaving the `write` permission only to a specific types as `issues: write` or `pull-requests: write`.
## Recommendation ## Recommendations
Add the `permissions` key to the job or the root of workflow (in this case it is applied to all jobs in the workflow that do not have their own `permissions` key) and assign the least privileges required to complete the task. Add the `permissions` key to the job or the root of workflow (in this case it is applied to all jobs in the workflow that do not have their own `permissions` key) and assign the least privileges required to complete the task:
## Example
### Incorrect Usage
```yaml
name: "My workflow"
# No permissions block
```
### Correct Usage
```yaml ```yaml
name: "My workflow" name: "My workflow"
@@ -36,4 +27,4 @@ jobs:
## References ## References
- GitHub Docs: [Assigning permissions to jobs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/assigning-permissions-to-jobs). - [Assigning permissions to jobs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/assigning-permissions-to-jobs)

Some files were not shown because too many files have changed in this diff Show More