Merge branch 'main' into redsun82/just2

This commit is contained in:
Paolo Tranquilli
2025-11-14 12:28:00 +01:00
committed by GitHub
3956 changed files with 260244 additions and 92503 deletions

View File

@@ -33,10 +33,6 @@ common --@rules_dotnet//dotnet/settings:strict_deps=false
# we only configure a nightly toolchain # we only configure a nightly toolchain
common --@rules_rust//rust/toolchain/channel=nightly common --@rules_rust//rust/toolchain/channel=nightly
# rust does not like the gold linker, while bazel does by default, so let's avoid using it
common:linux --linkopt=-fuse-ld=lld
common:macos --linkopt=-fuse-ld=lld
# 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 @@
When reviewing code:
* do not review changes in files with `.expected` extension (they are automatically ensured to be correct).
* in `.ql` and `.qll` files, do not try to review the code itself as you don't understand the programming language
well enough to make comments in these languages. You can still check for typos or comment improvements.

View File

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

View File

@@ -0,0 +1,6 @@
---
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

@@ -1,38 +1,67 @@
name: Build runzip name: Build ripunzip
on: on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
ripunzip-version: ripunzip-version:
description: "what reference to checktout from google/runzip" description: What reference to checkout from google/ripunzip. Latest by default
required: false required: false
default: v2.0.2
openssl-version: openssl-version:
description: "what reference to checkout from openssl/openssl for Linux" description: What reference to checkout from openssl/openssl for Linux. Latest by default
required: false required: false
default: openssl-3.5.0 open-pr:
description: Open a pull request updating the ripunzip versions committed to lfs
required: false
default: true # will be false on PRs
pull_request:
paths:
- .github/workflows/build-ripunzip.yml
permissions: {}
jobs: jobs:
versions:
runs-on: ubuntu-slim
outputs:
ripunzip-version: ${{ inputs.ripunzip-version || steps.fetch-ripunzip-version.outputs.version }}
openssl-version: ${{ inputs.openssl-version || steps.fetch-openssl-version.outputs.version }}
steps:
- name: Fetch latest ripunzip version
id: fetch-ripunzip-version
if: "!inputs.ripunzip-version"
run: &fetch-version
echo "version=$(gh release view --repo $REPO --json tagName --jq .tagName)" | tee -a $GITHUB_OUTPUT
env:
REPO: "google/ripunzip"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fetch latest openssl version
id: fetch-openssl-version
if: "!inputs.openssl-version"
run: *fetch-version
env:
REPO: "openssl/openssl"
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build: build:
needs: versions
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-22.04, macos-13, windows-2022] os: [ubuntu-24.04, macos-15, windows-2025]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
repository: google/ripunzip repository: google/ripunzip
ref: ${{ inputs.ripunzip-version }} ref: ${{ needs.versions.outputs.ripunzip-version }}
# we need to avoid ripunzip dynamically linking into libssl # we need to avoid ripunzip dynamically linking into libssl
# 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@v4 uses: actions/checkout@v5
with: with:
repository: openssl/openssl repository: openssl/openssl
path: openssl path: openssl
ref: ${{ inputs.openssl-version }} ref: ${{ needs.versions.outputs.openssl-version }}
- if: runner.os == 'Linux' - if: runner.os == 'Linux'
name: build and install openssl with fPIC name: build and install openssl with fPIC
shell: bash shell: bash
@@ -64,11 +93,74 @@ jobs:
lipo -create -output ripunzip-macos \ lipo -create -output ripunzip-macos \
-arch x86_64 target/x86_64-apple-darwin/release/ripunzip \ -arch x86_64 target/x86_64-apple-darwin/release/ripunzip \
-arch arm64 target/aarch64-apple-darwin/release/ripunzip -arch arm64 target/aarch64-apple-darwin/release/ripunzip
- uses: actions/upload-artifact@v4 - name: Archive
shell: bash
run: |
tar acf ripunzip-$RUNNER_OS.tar.zst ripunzip-$(echo $RUNNER_OS | tr '[:upper:]' '[:lower:]')
- name: Upload built binary
uses: actions/upload-artifact@v4
with: with:
name: ripunzip-${{ runner.os }} name: ripunzip-${{ runner.os }}
path: ripunzip-* path: ripunzip-${{ runner.os }}.tar.zst
retention-days: 5
compression: 0
- name: Check built binary - name: Check built binary
shell: bash shell: bash
run: | run: |
rm -f ripunzip-*.tar.zst
./ripunzip-* --version ./ripunzip-* --version
publish:
needs: [versions, build]
if: inputs.open-pr == 'true'
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-slim
steps:
# workaround for git-lfs not being installed yet on ubuntu-slim runners
- name: Ensure git-lfs is installed
shell: bash
run: |
if which git-lfs &>/dev/null; then
echo "git-lfs is already installed"
exit 0
fi
cd $TMP
gh release download --repo git-lfs/git-lfs --pattern "git-lfs-linux-amd64-*.tar.gz" --clobber
tar xzf git-lfs-linux-amd64-*.tar.gz
rm git-lfs-linux-amd64-*.tar.gz
cd git-lfs-*
pwd | tee -a $GITHUB_PATH
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v5
with:
sparse-checkout: |
.github
misc/ripunzip
lfs: true
- name: Download built binaries
uses: actions/download-artifact@v4
with:
merge-multiple: true
path: misc/ripunzip
- name: Open PR
shell: bash
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git switch -c update-ripunzip
git add misc/ripunzip
git commit -m "Update ripunzip binaries to version $VERSION"
git push --set-upstream origin update-ripunzip --force
TITLE="Update ripunzip binaries to version $VERSION"
gh pr create \
--draft \
--title "$TITLE" \
--body "Automated update of ripunzip binaries." \
--assignee "$ACTOR" ||
(gh pr edit --title "$TITLE" --add-assignee "$ACTOR" && gh pr ready --undo)
env:
ACTOR: ${{ github.actor }}
VERSION: ${{ needs.versions.outputs.ripunzip-version }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

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

View File

@@ -16,7 +16,7 @@ jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- 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

@@ -17,7 +17,7 @@ jobs:
sync: sync:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check overlay annotations - name: Check overlay annotations
run: python config/add-overlay-annotations.py --check java 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@v4 - uses: actions/checkout@v5
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@v4 - uses: actions/checkout@v5
- 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.100 dotnet-version: 9.0.300
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
# 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@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
# 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@v4 - uses: actions/checkout@v5
- name: Setup dotnet - name: Setup dotnet
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
dotnet-version: 9.0.100 dotnet-version: 9.0.300
- name: Extractor unit tests - name: Extractor unit tests
run: | run: |
dotnet tool restore dotnet tool restore
dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Util.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.5 extractor/Semmle.Util.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 extractor/Semmle.Extraction.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.5 extractor/Semmle.Extraction.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.CSharp.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.5 autobuilder/Semmle.Autobuild.CSharp.Tests
dotnet test -p:RuntimeFrameworkVersion=9.0.0 autobuilder/Semmle.Autobuild.Cpp.Tests dotnet test -p:RuntimeFrameworkVersion=9.0.5 autobuilder/Semmle.Autobuild.Cpp.Tests
shell: bash shell: bash
stubgentest: stubgentest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
with: with:
path: merge path: merge
- name: Clone self (github/codeql) - BASE - name: Clone self (github/codeql) - BASE
uses: actions/checkout@v4 uses: actions/checkout@v5
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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v4 uses: actions/checkout@v5
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@v4 uses: actions/checkout@v5
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@v4 uses: actions/checkout@v5
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v4 uses: actions/checkout@v5
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@v4 uses: actions/checkout@v5
- name: Git config - name: Git config
shell: bash shell: bash

View File

@@ -22,7 +22,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@v4 uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
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@v4 uses: actions/checkout@v5
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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
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@v4 - uses: actions/checkout@v5
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@v4 - uses: actions/checkout@v5
- name: Find codeql - name: Find codeql
id: find-codeql id: find-codeql
@@ -46,7 +46,7 @@ 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@v4 uses: actions/checkout@v5
with: with:
repository: ${{ matrix.repo }} repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo path: ${{ github.workspace }}/repo
@@ -75,7 +75,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: measure needs: measure
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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@v4 uses: actions/checkout@v5
- 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@v4 - uses: actions/checkout@v5
- 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,3 +76,6 @@ 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

@@ -1,17 +1,33 @@
# 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
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor /csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage
/csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor /csharp/autobuilder/Semmle.Autobuild.Cpp.Tests @github/codeql-c-extractor @github/code-scanning-language-coverage
/go/ @github/codeql-go /go/ @github/codeql-go
/go/codeql-tools/ @github/codeql-go @github/code-scanning-language-coverage
/go/downgrades/ @github/codeql-go @github/code-scanning-language-coverage
/go/extractor/ @github/codeql-go @github/code-scanning-language-coverage
/go/extractor-smoke-test/ @github/codeql-go @github/code-scanning-language-coverage
/go/ql/test/extractor-tests/ @github/codeql-go @github/code-scanning-language-coverage
/java/ @github/codeql-java /java/ @github/codeql-java
/javascript/ @github/codeql-javascript /javascript/ @github/codeql-javascript
/javascript/extractor/ @github/codeql-javascript @github/code-scanning-language-coverage
/python/ @github/codeql-python /python/ @github/codeql-python
/python/extractor/ @github/codeql-python @github/code-scanning-language-coverage
/ql/ @github/codeql-ql-for-ql-reviewers
/ruby/ @github/codeql-ruby /ruby/ @github/codeql-ruby
/ruby/extractor/ @github/codeql-ruby @github/code-scanning-language-coverage
/rust/ @github/codeql-rust /rust/ @github/codeql-rust
/rust/extractor/ @github/codeql-rust @github/code-scanning-language-coverage
/shared/ @github/codeql-shared-libraries-reviewers
/swift/ @github/codeql-swift /swift/ @github/codeql-swift
/swift/extractor/ @github/codeql-swift @github/code-scanning-language-coverage
/misc/codegen/ @github/codeql-swift /misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin /java/kotlin-extractor/ @github/codeql-kotlin @github/code-scanning-language-coverage
/java/ql/test-kotlin1/ @github/codeql-kotlin /java/ql/test-kotlin1/ @github/codeql-kotlin
/java/ql/test-kotlin2/ @github/codeql-kotlin /java/ql/test-kotlin2/ @github/codeql-kotlin
@@ -25,9 +41,6 @@
/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

1185
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,4 +10,3 @@ members = [
"rust/ast-generator", "rust/ast-generator",
"rust/autobuild", "rust/autobuild",
] ]
exclude = ["mad-generation-build"]

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 = "0.0.11") bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_go", version = "0.56.1") bazel_dep(name = "rules_go", version = "0.56.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.3.0") bazel_dep(name = "rules_shell", version = "0.5.0")
bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "bazel_skylib", version = "1.8.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.17.4") bazel_dep(name = "rules_dotnet", version = "0.19.2-codeql.1")
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.63.0") bazel_dep(name = "rules_rust", version = "0.66.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)
@@ -89,8 +89,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.20.4", "vendor_py__tree-sitter-0.24.7",
"vendor_py__tree-sitter-graph-0.7.0", "vendor_py__tree-sitter-graph-0.12.0",
) )
# deps for ruby+rust # deps for ruby+rust
@@ -98,54 +98,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.98", "vendor_ts__anyhow-1.0.100",
"vendor_ts__argfile-0.2.1", "vendor_ts__argfile-0.2.1",
"vendor_ts__chalk-ir-0.103.0", "vendor_ts__chalk-ir-0.104.0",
"vendor_ts__chrono-0.4.41", "vendor_ts__chrono-0.4.42",
"vendor_ts__clap-4.5.40", "vendor_ts__clap-4.5.48",
"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.0", "vendor_ts__flate2-1.1.2",
"vendor_ts__glob-0.3.2", "vendor_ts__glob-0.3.3",
"vendor_ts__globset-0.4.15", "vendor_ts__globset-0.4.16",
"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.17.0",
"vendor_ts__proc-macro2-1.0.95", "vendor_ts__proc-macro2-1.0.101",
"vendor_ts__quote-1.0.40", "vendor_ts__quote-1.0.41",
"vendor_ts__ra_ap_base_db-0.0.288", "vendor_ts__ra_ap_base_db-0.0.301",
"vendor_ts__ra_ap_cfg-0.0.288", "vendor_ts__ra_ap_cfg-0.0.301",
"vendor_ts__ra_ap_hir-0.0.288", "vendor_ts__ra_ap_hir-0.0.301",
"vendor_ts__ra_ap_hir_def-0.0.288", "vendor_ts__ra_ap_hir_def-0.0.301",
"vendor_ts__ra_ap_hir_expand-0.0.288", "vendor_ts__ra_ap_hir_expand-0.0.301",
"vendor_ts__ra_ap_hir_ty-0.0.288", "vendor_ts__ra_ap_hir_ty-0.0.301",
"vendor_ts__ra_ap_ide_db-0.0.288", "vendor_ts__ra_ap_ide_db-0.0.301",
"vendor_ts__ra_ap_intern-0.0.288", "vendor_ts__ra_ap_intern-0.0.301",
"vendor_ts__ra_ap_load-cargo-0.0.288", "vendor_ts__ra_ap_load-cargo-0.0.301",
"vendor_ts__ra_ap_parser-0.0.288", "vendor_ts__ra_ap_parser-0.0.301",
"vendor_ts__ra_ap_paths-0.0.288", "vendor_ts__ra_ap_paths-0.0.301",
"vendor_ts__ra_ap_project_model-0.0.288", "vendor_ts__ra_ap_project_model-0.0.301",
"vendor_ts__ra_ap_span-0.0.288", "vendor_ts__ra_ap_span-0.0.301",
"vendor_ts__ra_ap_stdx-0.0.288", "vendor_ts__ra_ap_stdx-0.0.301",
"vendor_ts__ra_ap_syntax-0.0.288", "vendor_ts__ra_ap_syntax-0.0.301",
"vendor_ts__ra_ap_vfs-0.0.288", "vendor_ts__ra_ap_vfs-0.0.301",
"vendor_ts__rand-0.9.1", "vendor_ts__rand-0.9.2",
"vendor_ts__rayon-1.10.0", "vendor_ts__rayon-1.11.0",
"vendor_ts__regex-1.11.1", "vendor_ts__regex-1.11.3",
"vendor_ts__serde-1.0.219", "vendor_ts__serde-1.0.228",
"vendor_ts__serde_json-1.0.140", "vendor_ts__serde_json-1.0.145",
"vendor_ts__serde_with-3.13.0", "vendor_ts__serde_with-3.14.1",
"vendor_ts__syn-2.0.103", "vendor_ts__syn-2.0.106",
"vendor_ts__toml-0.8.23", "vendor_ts__toml-0.9.7",
"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.19", "vendor_ts__tracing-subscriber-0.3.20",
"vendor_ts__tree-sitter-0.24.6", "vendor_ts__tree-sitter-0.25.9",
"vendor_ts__tree-sitter-embedded-template-0.23.2", "vendor_ts__tree-sitter-embedded-template-0.25.0",
"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 +172,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.100") dotnet.toolchain(dotnet_version = "9.0.300")
use_repo(dotnet, "dotnet_toolchains") use_repo(dotnet, "dotnet_toolchains")
register_toolchains("@dotnet_toolchains//:all") register_toolchains("@dotnet_toolchains//:all")
@@ -273,19 +273,19 @@ lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive")
lfs_archive( lfs_archive(
name = "ripunzip-linux", name = "ripunzip-linux",
src = "//misc/ripunzip:ripunzip-Linux.zip", src = "//misc/ripunzip:ripunzip-Linux.tar.zst",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel", build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
) )
lfs_archive( lfs_archive(
name = "ripunzip-windows", name = "ripunzip-windows",
src = "//misc/ripunzip:ripunzip-Windows.zip", src = "//misc/ripunzip:ripunzip-Windows.tar.zst",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel", build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
) )
lfs_archive( lfs_archive(
name = "ripunzip-macos", name = "ripunzip-macos",
src = "//misc/ripunzip:ripunzip-macOS.zip", src = "//misc/ripunzip:ripunzip-macOS.tar.zst",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel", build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
) )

View File

@@ -1,14 +1,17 @@
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
file_coverage_languages: [] default_queries:
- 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

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

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
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,4 +1,5 @@
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,3 +1,4 @@
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,3 +1,27 @@
## 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 ## 0.4.14
No user-facing changes. No user-facing changes.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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 `startcolumn` of line `startline` to * The location spans column `sc` of line `sl` to
* column `endcolumn` of line `endline` in file `filepath`. * column `ec` of line `el` in file `p`.
* 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 Environemnt node representing a deployment environment. * An Environment 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

@@ -125,12 +125,11 @@ abstract class AstNodeImpl extends TAstNode {
* Gets the enclosing Step. * Gets the enclosing Step.
*/ */
StepImpl getEnclosingStep() { StepImpl getEnclosingStep() {
if this instanceof StepImpl this instanceof StepImpl and
then result = this result = this
else or
if this instanceof ScalarValueImpl this instanceof ScalarValueImpl and
then result.getAChildNode*() = this.getParentNode() result.getAChildNode*() = this.getParentNode()
else none()
} }
/** /**
@@ -1416,9 +1415,8 @@ 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
if not name.getValue().matches("\\.%") not name.getValue().matches("\\.%") and
then result = name.getValue().regexpCapture(repoUsesParser(), 4) 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 `bb` * In other words, `i` is the shortest distance from a node `bbStart`
* 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,6 +3,8 @@ 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
@@ -25,7 +27,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 NormalSuccessor getAMatchingSuccessorType() { any() } override DirectSuccessor getAMatchingSuccessorType() { any() }
} }
class BooleanCompletion extends NormalCompletion, TBooleanCompletion { class BooleanCompletion extends NormalCompletion, TBooleanCompletion {
@@ -49,34 +51,6 @@ 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 {
@@ -127,14 +101,8 @@ 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 (
if fieldName.trim().matches("output.%") fieldName.trim().matches("output.%") and
then source.asExpr() = uses 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() {
this.asExpr() = e and exists(GitHubExpression e |
// github.head_ref this.asExpr() = e and
e.getFieldName() = "head_ref" and // github.head_ref
flag = "branch" and e.getFieldName() = "head_ref" and
( flag = "branch"
|
event = e.getATriggerEvent().getName() and event = e.getATriggerEvent().getName() and
event = "pull_request_target" event = "pull_request_target"
or or
@@ -148,7 +148,6 @@ 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
@@ -163,7 +162,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 | exists(string regexp, string access_path |
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,6 +1,7 @@
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
@@ -18,7 +19,6 @@ 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, argument) run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, _)
) )
} }
@@ -43,13 +43,12 @@ 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, argument) run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, _)
) )
} }
@@ -65,6 +64,16 @@ 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.
@@ -88,6 +97,14 @@ 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,6 +4,7 @@ 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+.*" }
@@ -124,8 +125,6 @@ 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
@@ -148,12 +147,14 @@ 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
this.getArgument("script") = script and exists(string script |
script.matches("%listWorkflowRunArtifacts(%") and this.getArgument("script") = script and
script.matches("%downloadArtifact(%") and script.matches("%listWorkflowRunArtifacts(%") and
script.matches("%writeFileSync(%") and script.matches("%downloadArtifact(%") and
// Filter out artifacts that were created by pull-request. script.matches("%writeFileSync(%") and
not script.matches("%exclude_pull_requests: true%") // Filter out artifacts that were created by pull-request.
not script.matches("%exclude_pull_requests: true%")
)
} }
override string getPath() { override string getPath() {
@@ -170,10 +171,10 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
.getScript() .getScript()
.getACommand() .getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3))) .regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else else (
if this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) and
then result = "GITHUB_WORKSPACE/" result = "GITHUB_WORKSPACE/"
else none() )
} }
} }
@@ -206,12 +207,13 @@ 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())
then result = "GITHUB_WORKSPACE/" ) and
else none() result = "GITHUB_WORKSPACE/"
)
} }
} }
@@ -258,15 +260,15 @@ class DirectArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
class ArtifactPoisoningSink extends DataFlow::Node { class ArtifactPoisoningSink extends DataFlow::Node {
UntrustedArtifactDownloadStep download; UntrustedArtifactDownloadStep download;
PoisonableStep poisonable;
ArtifactPoisoningSink() { ArtifactPoisoningSink() {
download.getAFollowingStep() = poisonable and exists(PoisonableStep poisonable |
// excluding artifacts downloaded to the temporary directory download.getAFollowingStep() = poisonable and
not download.getPath().regexpMatch("^/tmp.*") and // excluding artifacts downloaded to the temporary directory
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and not download.getPath().regexpMatch("^/tmp.*") and
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*") 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
@@ -292,6 +294,16 @@ 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
@@ -318,6 +330,14 @@ 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,6 +3,8 @@ 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() {
@@ -11,6 +13,46 @@ 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.
@@ -35,6 +77,16 @@ 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,11 +3,20 @@ 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.
@@ -16,6 +25,16 @@ 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,11 +159,8 @@ 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() {
condition = normalizeExpr(this.getCondition()) and exists(string condition | condition = normalizeExpr(this.getCondition()) |
(
// 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,6 +72,25 @@ 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.
@@ -108,6 +127,16 @@ 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,12 +55,8 @@ 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 | exists(Run run, CommandSource inCommand, string injectedVar, string command |
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
@@ -86,12 +82,8 @@ 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 | exists(Run run, string inVar, string injectedVar, string command |
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
@@ -126,6 +118,32 @@ 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.
@@ -163,6 +181,16 @@ 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,18 +99,14 @@ 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 | exists(Run run, string workflow_cmd_stmt, string clobbering_stmt, string clobbering_var |
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
clobbered_value = exists(trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1)))
trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1))
) )
} }
} }
@@ -216,8 +212,6 @@ private module OutputClobberingConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
/** 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

@@ -18,8 +18,6 @@ private module RequestForgeryConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink } predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
/** 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

@@ -17,8 +17,6 @@ private module SecretExfiltrationConfig implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) { sink instanceof SecretExfiltrationSink } predicate isSink(DataFlow::Node sink) { sink instanceof SecretExfiltrationSink }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
/** Tracks flow of unsafe user input that is used in a context where it may lead to a secret exfiltration. */ /** Tracks flow of unsafe user input that is used in a context where it may lead to a secret exfiltration. */

View File

@@ -1,10 +1,8 @@
import actions import actions
class UnversionedImmutableAction extends UsesStep { class UnversionedImmutableAction extends UsesStep {
string immutable_action;
UnversionedImmutableAction() { UnversionedImmutableAction() {
isImmutableAction(this, immutable_action) and isImmutableAction(this, _) 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.15-dev version: 0.4.21-dev
library: true library: true
warnOnImplicitThis: true warnOnImplicitThis: true
dependencies: dependencies:

View File

@@ -1,3 +1,29 @@
## 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 ## 0.6.6
No user-facing changes. No user-facing changes.

View File

@@ -0,0 +1,13 @@
/**
* @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

@@ -26,8 +26,6 @@ private module MyConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
module MyFlow = TaintTracking::Global<MyConfig>; module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -36,8 +36,6 @@ private module MyConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
module MyFlow = TaintTracking::Global<MyConfig>; module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -27,8 +27,6 @@ private module MyConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
module MyFlow = TaintTracking::Global<MyConfig>; module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -26,8 +26,6 @@ private module MyConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
module MyFlow = TaintTracking::Global<MyConfig>; module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -36,8 +36,6 @@ private module MyConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
module MyFlow = TaintTracking::Global<MyConfig>; module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -27,8 +27,6 @@ private module MyConfig implements DataFlow::ConfigSig {
} }
predicate observeDiffInformedIncrementalMode() { any() } predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
} }
module MyFlow = TaintTracking::Global<MyConfig>; module MyFlow = TaintTracking::Global<MyConfig>;

View File

@@ -21,18 +21,12 @@ 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
not exists(ControlCheck check | event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode())
check.protects(sink.getNode().asExpr(), event, "code-injection")
)
or or
source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and source.getNode().(RemoteFlowSource).getSourceType() = "artifact" and
not exists(ControlCheck check | event = getRelevantArtifactEventInPrivilegedContext(sink.getNode())
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

@@ -22,26 +22,15 @@ 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
not exists(ControlCheck check | event = getRelevantNonArtifactEventInPrivilegedContext(sink.getNode())
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
not exists(ControlCheck check | event = getRelevantArtifactEventInPrivilegedContext(sink.getNode())
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

@@ -22,15 +22,8 @@ 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
inPrivilegedContext(sink.getNode().asExpr(), event) and event = getRelevantCriticalEventForSink(sink.getNode()) and
source.getNode().(RemoteFlowSource).getEventName() = event.getName() and source.getNode().(RemoteFlowSource).getEventName() = event.getName()
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

@@ -18,30 +18,13 @@ import codeql.actions.security.CachePoisoningQuery
import CodeInjectionFlow::PathGraph import CodeInjectionFlow::PathGraph
import codeql.actions.security.ControlChecks import codeql.actions.security.ControlChecks
from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, LocalJob job, Event event from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink, Event event
where where
CodeInjectionFlow::flowPath(source, sink) and CodeInjectionFlow::flowPath(source, sink) and
job = sink.getNode().asExpr().getEnclosingJob() and event = getRelevantCachePoisoningEventForSink(sink.getNode()) and
job.getATriggerEvent() = event and
// job can be triggered by an external user
event.isExternallyTriggerable() and
// the checkout is not controlled by an access check // the checkout is not controlled by an access check
not exists(ControlCheck check | not exists(ControlCheck check |
check.protects(source.getNode().asExpr(), event, "code-injection") check.protects(source.getNode().asExpr(), event, "code-injection")
) and
// excluding privileged workflows since they can be exploited in easier circumstances
// which is covered by `actions/code-injection/critical`
not job.isPrivilegedExternallyTriggerable(event) and
(
// the workflow runs in the context of the default branch
runsOnDefaultBranch(event)
or
// the workflow caller runs in the context of the default branch
event.getName() = "workflow_call" and
exists(ExternalJob caller |
caller.getCallee() = job.getLocation().getFile().getRelativePath() and
runsOnDefaultBranch(caller.getATriggerEvent())
)
) )
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"Unprivileged code injection in $@, which may lead to cache poisoning ($@).", sink, "Unprivileged code injection in $@, which may lead to cache poisoning ($@).", sink,

View File

@@ -19,10 +19,7 @@ import codeql.actions.security.ControlChecks
from ArtifactPoisoningFlow::PathNode source, ArtifactPoisoningFlow::PathNode sink, Event event from ArtifactPoisoningFlow::PathNode source, ArtifactPoisoningFlow::PathNode sink, Event event
where where
ArtifactPoisoningFlow::flowPath(source, sink) and ArtifactPoisoningFlow::flowPath(source, sink) and
inPrivilegedContext(sink.getNode().asExpr(), event) and event = getRelevantEventInPrivilegedContext(sink.getNode())
not exists(ControlCheck check |
check.protects(sink.getNode().asExpr(), event, "artifact-poisoning")
)
select sink.getNode(), source, sink, select sink.getNode(), source, sink,
"Potential artifact poisoning in $@, which may be controlled by an external user ($@).", sink, "Potential artifact poisoning in $@, which may be controlled by an external user ($@).", sink,
sink.getNode().toString(), event, event.getName() sink.getNode().toString(), event, event.getName()

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
- run: | - run: |
npm install # scripts in package.json from PR would be executed here npm install # scripts in package.json from PR would be executed here
npm build npm build
- uses: completely/fakeaction@v2 - uses: completely/fakeaction@v2

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
- run: | - run: |
npm install # scripts in package.json from PR would be executed here npm install # scripts in package.json from PR would be executed here
npm build npm build
- uses: completely/fakeaction@v2 - uses: completely/fakeaction@v2

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
- run: | - run: |
npm install # scripts in package.json from PR would be executed here npm install # scripts in package.json from PR would be executed here
npm build npm build
- uses: completely/fakeaction@v2 - uses: completely/fakeaction@v2

View File

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

View File

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

View File

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

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