Compare commits

..

2 Commits

Author SHA1 Message Date
Calum Grant
60076dc8a8 C++: Remove potential FPs from cpp/integer-multiplication-cast-to-long in BMN 2025-01-23 19:45:44 +00:00
Calum Grant
d3e469f989 C++: Test for buildless IntMultToLong 2025-01-23 16:50:03 +00:00
11737 changed files with 212240 additions and 871410 deletions

View File

@@ -2,9 +2,6 @@ common --enable_platform_specific_config
# because we use --override_module with `%workspace%`, the lock file is not stable
common --lockfile_mode=off
# Build release binaries by default, can be overwritten to in local.bazelrc and set to `fastbuild` or `dbg`
build --compilation_mode opt
# when building from this repository in isolation, the internal repository will not be found at ..
# where `MODULE.bazel` looks for it. The following will get us past the module loading phase, so
# that we can build things that do not rely on that
@@ -12,9 +9,6 @@ common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
build --repo_env=CC=clang --repo_env=CXX=clang++
# print test output, like sembuild does.
# Set to `errors` if this is too verbose.
test --test_output all
# we use transitions that break builds of `...`, so for `test` to work with that we need the following
test --build_tests_only
@@ -30,13 +24,6 @@ common --registry=https://bcr.bazel.build
common --@rules_dotnet//dotnet/settings:strict_deps=false
# we only configure a nightly toolchain
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
common --incompatible_autoload_externally="+@rules_java,+@rules_shell"
@@ -44,6 +31,5 @@ build --java_language_version=17
build --tool_java_language_version=17
build --tool_java_runtime_version=remotejdk_17
build --java_runtime_version=remotejdk_17
build --@rules_python//python/config_settings:python_version=3.12
try-import %workspace%/local.bazelrc

View File

@@ -8,5 +8,3 @@ common --registry=https://bcr.bazel.build
# its implementation packages without providing any code itself.
# We either can depend on internal implementation details, or turn of strict deps.
common --@rules_dotnet//dotnet/settings:strict_deps=false
build --@rules_python//python/config_settings:python_version=3.12

View File

@@ -1 +1 @@
8.1.1
8.0.0

View File

@@ -1,7 +0,0 @@
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
USER root
# Install needed packages according to https://codeql.github.com/docs/codeql-overview/system-requirements/
# most come from the base image, but we need to install some additional ones
RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y sudo man-db python3.12 npm unminimize
RUN yes | unminimize

View File

@@ -1,4 +1,5 @@
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
"extensions": [
"rust-lang.rust-analyzer",
"bungcip.better-toml",
@@ -7,10 +8,6 @@
"ms-vscode.test-adapter-converter",
"slevesque.vscode-zipexplorer"
],
"build": {
// Path is relative to the devcontainer.json file.
"dockerfile": "Dockerfile.codespaces"
},
"settings": {
"files.watcherExclude": {
"**/target/**": true

View File

@@ -0,0 +1,9 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.236.0/containers/cpp/.devcontainer/base.Dockerfile
# [Choice] Debian / Ubuntu version (use Debian 11, Ubuntu 18.04/22.04 on local arm64/Apple Silicon): debian-11, debian-10, ubuntu-22.04, ubuntu-20.04, ubuntu-18.04
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-ubuntu-22.04
USER root
ADD root.sh /tmp/root.sh
ADD update-codeql.sh /usr/local/bin/update-codeql
RUN bash /tmp/root.sh && rm /tmp/root.sh

View File

@@ -0,0 +1,25 @@
{
"extensions": [
"github.vscode-codeql",
"hbenl.vscode-test-explorer",
"ms-vscode.test-adapter-converter",
"slevesque.vscode-zipexplorer",
"ms-vscode.cpptools"
],
"settings": {
"files.watcherExclude": {
"**/target/**": true
},
"codeQL.runningQueries.memory": 2048
},
"build": {
"dockerfile": "Dockerfile",
},
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined"
],
"remoteUser": "vscode",
"onCreateCommand": ".devcontainer/swift/user.sh"
}

34
.devcontainer/swift/root.sh Executable file
View File

@@ -0,0 +1,34 @@
set -xe
BAZELISK_VERSION=v1.12.0
BAZELISK_DOWNLOAD_SHA=6b0bcb2ea15bca16fffabe6fda75803440375354c085480fe361d2cbf32501db
# install git lfs apt source
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
# install gh apt source
(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
apt-get update
export DEBIAN_FRONTEND=noninteractive
apt-get -y install --no-install-recommends \
zlib1g-dev \
uuid-dev \
python3-distutils \
python3-pip \
bash-completion \
git-lfs \
gh
# Install Bazel
curl -fSsL -o /usr/local/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-amd64
echo "${BAZELISK_DOWNLOAD_SHA} */usr/local/bin/bazelisk" | sha256sum --check -
chmod 0755 /usr/local/bin/bazelisk
ln -s bazelisk /usr/local/bin/bazel
# install latest codeql
update-codeql

View File

@@ -0,0 +1,20 @@
#!/bin/bash -e
URL=https://github.com/github/codeql-cli-binaries/releases
LATEST_VERSION=$(curl -L -s -H 'Accept: application/json' $URL/latest | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
CURRENT_VERSION=v$(codeql version 2>/dev/null | sed -ne 's/.*release \([0-9.]*\)\./\1/p')
if [[ $CURRENT_VERSION != $LATEST_VERSION ]]; then
if [[ $UID != 0 ]]; then
echo "update required, please run this script with sudo:"
echo " sudo $0"
exit 1
fi
ZIP=$(mktemp codeql.XXXX.zip)
curl -fSqL -o $ZIP $URL/download/$LATEST_VERSION/codeql-linux64.zip
unzip -q $ZIP -d /opt
rm $ZIP
ln -sf /opt/codeql/codeql /usr/local/bin/codeql
echo installed version $LATEST_VERSION
else
echo current version $CURRENT_VERSION is up-to-date
fi

15
.devcontainer/swift/user.sh Executable file
View File

@@ -0,0 +1,15 @@
set -xe
git lfs install
# add the workspace to the codeql search path
mkdir -p /home/vscode/.config/codeql
echo "--search-path /workspaces/codeql" > /home/vscode/.config/codeql/config
# create a swift extractor pack with the current state
cd /workspaces/codeql
bazel run swift/create-extractor-pack
#install and set up pre-commit
python3 -m pip install pre-commit --no-warn-script-location
$HOME/.local/bin/pre-commit install

View File

@@ -4,13 +4,9 @@ queries:
- uses: security-and-quality
paths-ignore:
- '/actions/ql/test'
- '/cpp/'
- '/java/'
- '/python/'
- '/javascript/ql/test'
- '/javascript/ql/integration-tests'
- '/javascript/extractor/tests'
- '/javascript/extractor/parser-tests'
- '/javascript/ql/src/'
- '/rust/ql'

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.

14
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,14 @@
### Pull Request checklist
#### All query authors
- [ ] A change note is added if necessary. See [the documentation](https://github.com/github/codeql/blob/main/docs/change-notes.md) in this repository.
- [ ] All new queries have appropriate `.qhelp`. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-help-style-guide.md) in this repository.
- [ ] QL tests are added if necessary. See [Testing custom queries](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/testing-custom-queries) in the GitHub documentation.
- [ ] New and changed queries have correct query metadata. See [the documentation](https://github.com/github/codeql/blob/main/docs/query-metadata-style-guide.md) in this repository.
#### Internal query authors only
- [ ] Autofixes generated based on these changes are valid, only needed if this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required).
- [ ] Changes are validated [at scale](https://github.com/github/codeql-dca/) (internal access required).
- [ ] Adding a new query? Consider also [adding the query to autofix](https://github.com/github/codeml-autofix/blob/main/docs/updating-query-support.md#adding-a-new-query-to-the-query-suite).

View File

@@ -6,18 +6,18 @@ on:
ripunzip-version:
description: "what reference to checktout from google/runzip"
required: false
default: v2.0.2
default: v1.2.1
openssl-version:
description: "what reference to checkout from openssl/openssl for Linux"
required: false
default: openssl-3.5.0
default: openssl-3.3.0
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-13, windows-2022]
os: [ubuntu-20.04, macos-13, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

View File

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

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@v4
- name: Check overlay annotations
run: python config/add-overlay-annotations.py --check java

View File

@@ -18,10 +18,6 @@ on:
jobs:
CodeQL-Build:
strategy:
fail-fast: false
matrix:
language: ['actions', 'csharp']
runs-on: ubuntu-latest
@@ -42,8 +38,9 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@main
# Override language selection by uncommenting this and choosing your languages
with:
languages: ${{ matrix.language }}
languages: csharp
config-file: ./.github/codeql/codeql-config.yml
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).

View File

@@ -36,7 +36,7 @@ jobs:
unit-tests:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest, windows-2019]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
@@ -66,6 +66,6 @@ jobs:
# Update existing stubs in the repo with the freshly generated ones
mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/
git status
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
env:
GITHUB_TOKEN: ${{ github.token }}

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/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:
if: github.repository_owner == 'github'
name: Test Windows
runs-on: windows-latest-xl
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run tests
uses: ./go/actions/test

View File

@@ -1,9 +1,18 @@
name: "Go: Run Tests"
on:
push:
paths:
- "go/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "go/**"
- "!go/documentation/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**

View File

@@ -68,7 +68,7 @@ jobs:
DATABASE=$2
cd codeql-$QL_VARIANT
SHORTNAME=`basename $DATABASE`
python misc/scripts/models-as-data/generate_mad.py --language java --with-summaries --with-sinks $DATABASE $SHORTNAME/$QL_VARIANT
python java/ql/src/utils/modelgenerator/GenerateFlowModel.py --with-summaries --with-sinks $DATABASE $SHORTNAME/$QL_VARIANT
mkdir -p $MODELS/$SHORTNAME
mv java/ql/lib/ext/generated/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
cd ..

View File

@@ -1,35 +0,0 @@
name: Python tooling
on:
pull_request:
paths:
- "misc/bazel/**"
- "misc/codegen/**"
- "misc/scripts/models-as-data/bulk_generate_mad.py"
- "*.bazel*"
- .github/workflows/codegen.yml
- .pre-commit-config.yaml
branches:
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
jobs:
check-python-tooling:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
extra_args: black --all-files
- name: Run codegen tests
shell: bash
run: |
bazel test //misc/codegen/...

View File

@@ -53,7 +53,7 @@ jobs:
- name: Create database
run: |
"${CODEQL}" database create \
--search-path "${{ github.workspace }}" \
--search-path "${{ github.workspace }}"
--threads 4 \
--language ql --source-root "${{ github.workspace }}/repo" \
"${{ runner.temp }}/database"

View File

@@ -1,40 +0,0 @@
name: "Ruby: Run RTJO Language Tests"
on:
pull_request:
types:
- opened
- synchronize
- reopened
- labeled
env:
CARGO_TERM_COLOR: always
defaults:
run:
working-directory: ruby
permissions:
contents: read
jobs:
qltest-rtjo:
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
runs-on: ubuntu-latest-xl
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -68,6 +68,6 @@ jobs:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -18,39 +18,51 @@ on:
- main
- rc/*
- codeql-cli-*
push:
paths:
- "swift/**"
- "misc/bazel/**"
- "misc/codegen/**"
- "shared/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/**
- codeql-workspace.yml
- .pre-commit-config.yaml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- main
- rc/*
- codeql-cli-*
permissions:
contents: read
defaults:
run:
shell: bash
working-directory: swift
jobs:
build-and-test:
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks
# without waiting for the macOS build
build-and-test-macos:
if: github.repository_owner == 'github'
strategy:
matrix:
runner: [ubuntu-latest, macos-15-xlarge]
fail-fast: false
runs-on: ${{ matrix.runner }}
runs-on: macos-13-xlarge
steps:
- uses: actions/checkout@v4
- name: Setup (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y uuid-dev zlib1g-dev
- name: Build Swift extractor
shell: bash
run: |
bazel run :install
- name: Run Swift tests
shell: bash
run: |
bazel test ... --test_tag_filters=-override --test_output=errors
- uses: ./swift/actions/build-and-test
build-and-test-linux:
if: github.repository_owner == 'github'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/build-and-test
qltests-macos:
if: ${{ github.repository_owner == 'github' && github.event_name == 'pull_request' }}
needs: build-and-test-macos
runs-on: macos-13-xlarge
steps:
- uses: actions/checkout@v4
- uses: ./swift/actions/run-ql-tests
clang-format:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -59,9 +71,18 @@ jobs:
with:
extra_args: clang-format --all-files
codegen:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted
with:
extra_args: autopep8 --all-files
- uses: ./.github/actions/fetch-codeql
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that QL generated code was checked in
@@ -69,14 +90,22 @@ jobs:
extra_args: swift-codegen --all-files
- name: Generate C++ files
run: |
bazel run codegen -- --generate=trap,cpp --cpp-output=$PWD/generated-cpp-files
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/generated-cpp-files
- uses: actions/upload-artifact@v4
with:
name: swift-generated-cpp-files
path: generated-cpp-files/**
check-no-override:
database-upgrade-scripts:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check that no override is present in load.bzl
run: bazel test ... --test_tag_filters=override --test_output=errors
- uses: ./.github/actions/fetch-codeql
- uses: ./swift/actions/database-upgrade-scripts
check-no-override:
if : github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- shell: bash
run: bazel test //swift/... --test_tag_filters=override --test_output=errors

View File

@@ -31,4 +31,4 @@ jobs:
- name: Fail if there are any errors with existing change notes
run: |
codeql pack release --groups actions,cpp,csharp,go,java,javascript,python,ruby,shared,swift -examples,-test,-experimental
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental

5
.gitignore vendored
View File

@@ -62,7 +62,6 @@ node_modules/
# Temporary folders for working with generated models
.model-temp
/mad-generation-build
# bazel-built in-tree extractor packs
/*/extractor-pack
@@ -72,7 +71,3 @@ node_modules/
# cargo build directory
/target
# some upgrade/downgrade checks create these files
**/upgrades/*/*.dbscheme.stats
**/downgrades/*/*.dbscheme.stats

View File

@@ -1,7 +1,5 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
default_language_version:
python: python3.12
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
@@ -9,18 +7,18 @@ repos:
- id: trailing-whitespace
exclude: /test/.*$(?<!\.qlref)|.*\.patch$|.*\.qll?$
- 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
rev: v17.0.6
hooks:
- id: clang-format
- repo: https://github.com/psf/black
rev: 25.1.0
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.4
hooks:
- id: black
files: ^(misc/codegen/.*|misc/scripts/models-as-data/.*)\.py$
- id: autopep8
files: ^misc/codegen/.*\.py
- repo: local
hooks:
@@ -74,7 +72,7 @@ repos:
- id: rust-codegen
name: Run Rust checked in code generation
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list|ast-generator/)
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list)
language: system
entry: bazel run //rust/codegen -- --quiet
pass_filenames: false

10
.vscode/tasks.json vendored
View File

@@ -50,11 +50,6 @@
"${input:name}",
"${input:categoryQuery}"
],
"options": {
"env": {
"EDITOR": "code -r",
}
},
"presentation": {
"reveal": "never",
"close": true
@@ -72,11 +67,6 @@
"${input:name}",
"${input:categoryLibrary}"
],
"options": {
"env": {
"EDITOR": "code -r"
}
},
"presentation": {
"reveal": "never",
"close": true

View File

@@ -8,17 +8,12 @@
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/ruby/ @github/codeql-ruby
/rust/ @github/codeql-rust
/swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin
/java/ql/test-kotlin1/ @github/codeql-kotlin
/java/ql/test-kotlin2/ @github/codeql-kotlin
# Experimental CodeQL cryptography
**/experimental/**/quantum/ @github/ps-codeql
/shared/quantum/ @github/ps-codeql
# CodeQL tools and associated docs
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
@@ -43,7 +38,6 @@ MODULE.bazel @github/codeql-ci-reviewers
/.github/workflows/go-* @github/codeql-go
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby
/.github/workflows/rust.yml @github/codeql-rust
/.github/workflows/swift.yml @github/codeql-swift
# Misc

1334
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,4 +10,8 @@ members = [
"rust/ast-generator",
"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 = "096d585100636bc2e9f09d7eefec38c5b334d47b" }

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2006-2025 GitHub, Inc.
Copyright (c) 2006-2020 GitHub, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -14,8 +14,8 @@ local_path_override(
# see https://registry.bazel.build/ for a list of available packages
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_go", version = "0.56.1")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_go", version = "0.50.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_python", version = "0.40.0")
@@ -24,24 +24,20 @@ bazel_dep(name = "bazel_skylib", version = "1.7.1")
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 = "fmt", version = "10.0.0")
bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
bazel_dep(name = "rules_kotlin", version = "2.0.0-codeql.1")
bazel_dep(name = "gazelle", version = "0.40.0")
bazel_dep(name = "rules_dotnet", version = "0.17.4")
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.52.2")
bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
# Keep edition and version approximately in sync with internal repo.
# 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 = "2021"
# run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo)
# 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_VERSION = "1.82.0"
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
rust.toolchain(
@@ -51,46 +47,35 @@ rust.toolchain(
"x86_64-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],
)
use_repo(rust, "rust_toolchains")
register_toolchains("@rust_toolchains//:all")
rust_host_tools = use_extension("@rules_rust//rust:extensions.bzl", "rust_host_tools")
# Don't download a second toolchain as host toolchain, make sure this is the same version as above
# The host toolchain is used for vendoring dependencies.
rust_host_tools.host_tools(
edition = RUST_EDITION,
version = RUST_VERSION,
)
# deps for python extractor
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
py_deps = use_extension("//misc/bazel/3rdparty:py_deps_extension.bzl", "p")
use_repo(
py_deps,
"vendor_py__anyhow-1.0.95",
"vendor_py__cc-1.2.14",
"vendor_py__clap-4.5.30",
"vendor_py__regex-1.11.1",
"vendor_py__tree-sitter-0.20.4",
"vendor_py__tree-sitter-graph-0.7.0",
"vendor__anyhow-1.0.44",
"vendor__cc-1.0.70",
"vendor__clap-2.33.3",
"vendor__regex-1.5.5",
"vendor__smallvec-1.6.1",
"vendor__string-interner-0.12.2",
"vendor__thiserror-1.0.29",
"vendor__tree-sitter-0.20.4",
"vendor__tree-sitter-graph-0.7.0",
)
# deps for ruby+rust
@@ -98,60 +83,58 @@ use_repo(
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(
tree_sitter_extractors_deps,
"vendor_ts__anyhow-1.0.98",
"vendor_ts__argfile-0.2.1",
"vendor_ts__chalk-ir-0.103.0",
"vendor_ts__chrono-0.4.41",
"vendor_ts__clap-4.5.40",
"vendor_ts__dunce-1.0.5",
"vendor_ts__either-1.15.0",
"vendor_ts__encoding-0.2.33",
"vendor_ts__figment-0.10.19",
"vendor_ts__flate2-1.1.0",
"vendor_ts__glob-0.3.2",
"vendor_ts__globset-0.4.15",
"vendor_ts__itertools-0.14.0",
"vendor_ts__lazy_static-1.5.0",
"vendor_ts__mustache-0.9.0",
"vendor_ts__num-traits-0.2.19",
"vendor_ts__num_cpus-1.17.0",
"vendor_ts__proc-macro2-1.0.95",
"vendor_ts__quote-1.0.40",
"vendor_ts__ra_ap_base_db-0.0.288",
"vendor_ts__ra_ap_cfg-0.0.288",
"vendor_ts__ra_ap_hir-0.0.288",
"vendor_ts__ra_ap_hir_def-0.0.288",
"vendor_ts__ra_ap_hir_expand-0.0.288",
"vendor_ts__ra_ap_hir_ty-0.0.288",
"vendor_ts__ra_ap_ide_db-0.0.288",
"vendor_ts__ra_ap_intern-0.0.288",
"vendor_ts__ra_ap_load-cargo-0.0.288",
"vendor_ts__ra_ap_parser-0.0.288",
"vendor_ts__ra_ap_paths-0.0.288",
"vendor_ts__ra_ap_project_model-0.0.288",
"vendor_ts__ra_ap_span-0.0.288",
"vendor_ts__ra_ap_stdx-0.0.288",
"vendor_ts__ra_ap_syntax-0.0.288",
"vendor_ts__ra_ap_vfs-0.0.288",
"vendor_ts__rand-0.9.1",
"vendor_ts__rayon-1.10.0",
"vendor_ts__regex-1.11.1",
"vendor_ts__serde-1.0.219",
"vendor_ts__serde_json-1.0.140",
"vendor_ts__serde_with-3.13.0",
"vendor_ts__syn-2.0.103",
"vendor_ts__toml-0.8.23",
"vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0",
"vendor_ts__tracing-subscriber-0.3.19",
"vendor_ts__tree-sitter-0.24.6",
"vendor_ts__tree-sitter-embedded-template-0.23.2",
"vendor_ts__tree-sitter-json-0.24.8",
"vendor_ts__tree-sitter-ql-0.23.1",
"vendor_ts__tree-sitter-ruby-0.23.1",
"vendor_ts__triomphe-0.1.14",
"vendor_ts__ungrammar-1.16.1",
"vendor_ts__zstd-0.13.3",
"vendor__anyhow-1.0.95",
"vendor__argfile-0.2.1",
"vendor__chrono-0.4.39",
"vendor__clap-4.5.26",
"vendor__dunce-1.0.5",
"vendor__either-1.13.0",
"vendor__encoding-0.2.33",
"vendor__figment-0.10.19",
"vendor__flate2-1.0.35",
"vendor__glob-0.3.2",
"vendor__globset-0.4.15",
"vendor__itertools-0.14.0",
"vendor__lazy_static-1.5.0",
"vendor__log-0.4.22",
"vendor__mustache-0.9.0",
"vendor__num-traits-0.2.19",
"vendor__num_cpus-1.16.0",
"vendor__proc-macro2-1.0.93",
"vendor__quote-1.0.38",
"vendor__ra_ap_base_db-0.0.258",
"vendor__ra_ap_cfg-0.0.258",
"vendor__ra_ap_hir-0.0.258",
"vendor__ra_ap_hir_def-0.0.258",
"vendor__ra_ap_hir_expand-0.0.258",
"vendor__ra_ap_ide_db-0.0.258",
"vendor__ra_ap_intern-0.0.258",
"vendor__ra_ap_load-cargo-0.0.258",
"vendor__ra_ap_parser-0.0.258",
"vendor__ra_ap_paths-0.0.258",
"vendor__ra_ap_project_model-0.0.258",
"vendor__ra_ap_span-0.0.258",
"vendor__ra_ap_stdx-0.0.258",
"vendor__ra_ap_syntax-0.0.258",
"vendor__ra_ap_vfs-0.0.258",
"vendor__rand-0.8.5",
"vendor__rayon-1.10.0",
"vendor__regex-1.11.1",
"vendor__serde-1.0.217",
"vendor__serde_json-1.0.135",
"vendor__serde_with-3.12.0",
"vendor__stderrlog-0.6.0",
"vendor__syn-2.0.96",
"vendor__toml-0.8.19",
"vendor__tracing-0.1.41",
"vendor__tracing-subscriber-0.3.19",
"vendor__tree-sitter-0.24.6",
"vendor__tree-sitter-embedded-template-0.23.2",
"vendor__tree-sitter-json-0.24.8",
"vendor__tree-sitter-ql-0.23.1",
"vendor__tree-sitter-ruby-0.23.1",
"vendor__triomphe-0.1.14",
"vendor__ungrammar-1.16.1",
)
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
@@ -183,7 +166,7 @@ use_repo(csharp_main_extension, "paket.main")
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "codegen_deps",
python_version = "3.12",
python_version = "3.11",
requirements_lock = "//misc/codegen:requirements_lock.txt",
)
use_repo(pip, "codegen_deps")
@@ -221,6 +204,10 @@ use_repo(
kotlin_extractor_deps,
"codeql_kotlin_defaults",
"codeql_kotlin_embeddable",
"kotlin-compiler-1.5.0",
"kotlin-compiler-1.5.10",
"kotlin-compiler-1.5.20",
"kotlin-compiler-1.5.30",
"kotlin-compiler-1.6.0",
"kotlin-compiler-1.6.20",
"kotlin-compiler-1.7.0",
@@ -232,8 +219,10 @@ use_repo(
"kotlin-compiler-2.0.20-Beta2",
"kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-2.2.0-Beta1",
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-embeddable-1.5.0",
"kotlin-compiler-embeddable-1.5.10",
"kotlin-compiler-embeddable-1.5.20",
"kotlin-compiler-embeddable-1.5.30",
"kotlin-compiler-embeddable-1.6.0",
"kotlin-compiler-embeddable-1.6.20",
"kotlin-compiler-embeddable-1.7.0",
@@ -245,8 +234,10 @@ use_repo(
"kotlin-compiler-embeddable-2.0.20-Beta2",
"kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-compiler-embeddable-2.2.0-Beta1",
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-stdlib-1.5.0",
"kotlin-stdlib-1.5.10",
"kotlin-stdlib-1.5.20",
"kotlin-stdlib-1.5.30",
"kotlin-stdlib-1.6.0",
"kotlin-stdlib-1.6.20",
"kotlin-stdlib-1.7.0",
@@ -258,35 +249,33 @@ use_repo(
"kotlin-stdlib-2.0.20-Beta2",
"kotlin-stdlib-2.1.0-Beta1",
"kotlin-stdlib-2.1.20-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.download(version = "1.25.0")
go_sdk.download(version = "1.23.1")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod")
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive")
lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
lfs_archive(
lfs_files(
name = "ripunzip-linux",
src = "//misc/ripunzip:ripunzip-Linux.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
srcs = ["//misc/ripunzip:ripunzip-linux"],
executable = True,
)
lfs_archive(
lfs_files(
name = "ripunzip-windows",
src = "//misc/ripunzip:ripunzip-Windows.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
srcs = ["//misc/ripunzip:ripunzip-windows.exe"],
executable = True,
)
lfs_archive(
lfs_files(
name = "ripunzip-macos",
src = "//misc/ripunzip:ripunzip-macOS.zip",
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
srcs = ["//misc/ripunzip:ripunzip-macos"],
executable = True,
)
register_toolchains(

View File

@@ -4,9 +4,7 @@ codeql_pkg_files(
name = "extractor",
srcs = [
"codeql-extractor.yml",
"//:LICENSE",
],
exes = glob(["tools/**"]),
] + glob(["tools/**"]),
strip_prefix = strip_prefix.from_pkg(),
visibility = ["//actions:__pkg__"],
)

View File

@@ -1,34 +1,21 @@
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/*.yml',
'include:.github/workflows/*.yaml',
'include:.github/reusable_workflows/**/*.yml',
'include:.github/reusable_workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)
if ($null -ne $env:LGTM_INDEX_FILTERS) {
Write-Output 'LGTM_INDEX_FILTERS set. Using the default filters together with the user-provided filters, and passing through to the JavaScript extractor.'
# Begin with the default path inclusions only,
# followed by the user-provided filters.
# If the user provided `paths`, those patterns override the default inclusions
# (because `LGTM_INDEX_FILTERS` will begin with `exclude:**/*`).
# If the user provided `paths-ignore`, those patterns are excluded.
$PathFilters = ($DefaultPathFilters -join "`n") + "`n" + $env:LGTM_INDEX_FILTERS
$env:LGTM_INDEX_FILTERS = $PathFilters
if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE) -or ($null -ne $env:LGTM_INDEX_FILTERS)) {
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
} else {
Write-Output 'LGTM_INDEX_FILTERS not set. Using the default filters, and passing through to the JavaScript extractor.'
Write-Output 'No path filters set. Using the default filters.'
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/**/*.yml',
'include:.github/workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)
$env:LGTM_INDEX_FILTERS = $DefaultPathFilters -join "`n"
}
# Find the JavaScript extractor directory via `codeql resolve extractor`.
$CodeQL = Join-Path $env:CODEQL_DIST 'codeql.exe'
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &"$CodeQL" resolve extractor --language javascript
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &$CodeQL resolve extractor --language javascript
if ($LASTEXITCODE -ne 0) {
throw 'Failed to resolve JavaScript extractor.'
}
@@ -47,7 +34,7 @@ $env:CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = $env:CODEQL_EXTRACTOR_ACTI
$env:CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = $env:CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE
&"$JavaScriptAutoBuild"
&$JavaScriptAutoBuild
if ($LASTEXITCODE -ne 0) {
throw "JavaScript autobuilder failed."
}

View File

@@ -1,4 +1,3 @@
@echo off
rem All of the work is done in the PowerShell script
echo "Running PowerShell script at '%~dp0autobuild-impl.ps1'"
powershell.exe -File "%~dp0autobuild-impl.ps1"
powershell.exe %~dp0autobuild-impl.ps1

View File

@@ -2,43 +2,25 @@
set -eu
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
DEFAULT_PATH_FILTERS=$(cat << END
exclude:**/*
include:.github/workflows/*.yml
include:.github/workflows/*.yaml
include:.github/reusable_workflows/**/*.yml
include:.github/reusable_workflows/**/*.yaml
include:.github/workflows/**/*.yml
include:.github/workflows/**/*.yaml
include:**/action.yml
include:**/action.yaml
END
)
if [ -n "${LGTM_INDEX_FILTERS:-}" ]; then
echo "LGTM_INDEX_FILTERS set. Using the default filters together with the user-provided filters, and passing through to the JavaScript extractor."
# Begin with the default path inclusions only,
# followed by the user-provided filters.
# If the user provided `paths`, those patterns override the default inclusions
# (because `LGTM_INDEX_FILTERS` will begin with `exclude:**/*`).
# If the user provided `paths-ignore`, those patterns are excluded.
PATH_FILTERS="$(cat << END
${DEFAULT_PATH_FILTERS}
${LGTM_INDEX_FILTERS}
END
)"
LGTM_INDEX_FILTERS="${PATH_FILTERS}"
export LGTM_INDEX_FILTERS
if [ -n "${LGTM_INDEX_INCLUDE:-}" ] || [ -n "${LGTM_INDEX_EXCLUDE:-}" ] || [ -n "${LGTM_INDEX_FILTERS:-}" ] ; then
echo "Path filters set. Passing them through to the JavaScript extractor."
else
echo "LGTM_INDEX_FILTERS not set. Using the default filters, and passing through to the JavaScript extractor."
echo "No path filters set. Using the default filters."
LGTM_INDEX_FILTERS="${DEFAULT_PATH_FILTERS}"
export LGTM_INDEX_FILTERS
fi
# Find the JavaScript extractor directory via `codeql resolve extractor`.
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$("${CODEQL_DIST}/codeql" resolve extractor --language javascript)"
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$($CODEQL_DIST/codeql resolve extractor --language javascript)"
export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT
echo "Found JavaScript extractor at '${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
@@ -54,4 +36,4 @@ env CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="${CODEQL_EXTRACTOR_ACTIONS_DIAGN
CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="${CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="${CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="${CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE}" \
"${JAVASCRIPT_AUTO_BUILD}"
${JAVASCRIPT_AUTO_BUILD}

View File

@@ -1,28 +0,0 @@
extensions:
- addsTo:
pack: codeql/actions-all
extensible: immutableActionsDataModel
data:
- ["actions/checkout"]
- ["actions/cache"]
- ["actions/setup-node"]
- ["actions/upload-artifact"]
- ["actions/setup-python"]
- ["actions/download-artifact"]
- ["actions/github-script"]
- ["actions/setup-java"]
- ["actions/setup-go"]
- ["actions/upload-pages-artifact"]
- ["actions/deploy-pages"]
- ["actions/setup-dotnet"]
- ["actions/stale"]
- ["actions/labeler"]
- ["actions/create-github-app-token"]
- ["actions/configure-pages"]
- ["github/codeql-action/analyze"]
- ["github/codeql-action/autobuild"]
- ["github/codeql-action/init"]
- ["github/codeql-action/resolve-environment"]
- ["github/codeql-action/start-proxy"]
- ["github/codeql-action/upload-sarif"]
- ["octokit/request-action"]

View File

@@ -1,14 +0,0 @@
# Model pack containing the list of known immutable actions. The Immutable Actions feature is not
# yet released, so this pack will only be used within GitHub. Once the feature is available to
# customers, we will move the contents of this pack back into the standard library pack.
name: codeql/immutable-actions-list
version: 0.0.1-dev
library: true
warnOnImplicitThis: true
extensionTargets:
# We expect to need this model pack even after GA of Actions analysis, so make it compatible with
# all future prereleases plus 1.x.x. We should be able to remove this back before we need to
# bump the major version to 2.
codeql/actions-all: ">=0.4.3 <2.0.0"
dataExtensions:
- ext/**/*.yml

View File

@@ -1,5 +0,0 @@
import actions
from AstNode n
where n instanceof Workflow or n instanceof CompositeAction
select n

View File

@@ -1,6 +0,0 @@
| src/.github/action.yaml:1:1:11:32 | name: ' ... action' |
| src/.github/actions/action-name/action.yml:1:1:11:32 | name: ' ... action' |
| src/.github/workflows/workflow.yml:1:1:12:33 | name: A workflow |
| src/action.yml:1:1:11:32 | name: ' ... action' |
| src/excluded/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/action.yml:1:1:11:32 | name: ' ... action' |

View File

@@ -1,2 +0,0 @@
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/unreachable-workflow.yml:1:1:12:33 | name: A ... orkflow |

View File

@@ -1,5 +0,0 @@
| src/.github/action.yaml:1:1:11:32 | name: ' ... action' |
| src/.github/actions/action-name/action.yml:1:1:11:32 | name: ' ... action' |
| src/.github/workflows/workflow.yml:1:1:12:33 | name: A workflow |
| src/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/action.yml:1:1:11:32 | name: ' ... action' |

View File

@@ -1,2 +0,0 @@
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/unreachable-workflow.yml:1:1:12:33 | name: A ... orkflow |

View File

@@ -1,5 +0,0 @@
import actions
from AstNode n
where n instanceof Workflow or n instanceof CompositeAction
select n

View File

@@ -1,4 +0,0 @@
paths:
- 'included'
paths-ignore:
- 'excluded'

View File

@@ -1,2 +0,0 @@
paths-ignore:
- 'excluded'

View File

@@ -1,2 +0,0 @@
paths:
- 'included'

View File

@@ -1,6 +0,0 @@
src/.github/action.yaml
src/.github/actions/action-name/action.yml
src/.github/workflows/workflow.yml
src/action.yml
src/excluded/action.yml
src/included/action.yml

View File

@@ -1,3 +0,0 @@
src/included/action.yml
src/included/not-an-action.yml
src/included/unreachable-workflow.yml

View File

@@ -1,5 +0,0 @@
src/.github/action.yaml
src/.github/actions/action-name/action.yml
src/.github/workflows/workflow.yml
src/action.yml
src/included/action.yml

View File

@@ -1,3 +0,0 @@
src/included/action.yml
src/included/not-an-action.yml
src/included/unreachable-workflow.yml

View File

@@ -1,11 +0,0 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -1,11 +0,0 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -1,12 +0,0 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -1,12 +0,0 @@
name: A workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -1,11 +0,0 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -1,11 +0,0 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -1,12 +0,0 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -1,11 +0,0 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -1 +0,0 @@
name: 'Not an action, just a YAML file'

View File

@@ -1,12 +0,0 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -1,12 +0,0 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -1,18 +0,0 @@
import pytest
@pytest.mark.ql_test(expected=".default-filters.expected")
def test_default_filters(codeql, actions, check_source_archive):
check_source_archive.expected_suffix = ".default-filters.expected"
codeql.database.create(source_root="src")
@pytest.mark.ql_test(expected=".paths-only.expected")
def test_config_paths_only(codeql, actions):
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-only.yml")
@pytest.mark.ql_test(expected=".paths-ignore-only.expected")
def test_config_paths_ignore_only(codeql, actions):
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-ignore-only.yml")
@pytest.mark.ql_test(expected=".paths-and-paths-ignore.expected")
def test_config_paths_and_paths_ignore(codeql, actions):
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-and-paths-ignore.yml")

View File

@@ -1,17 +0,0 @@
ql/actions/ql/src/Security/CWE-077/EnvPathInjectionCritical.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-1395/UseOfKnownVulnerableAction.ql
ql/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql
ql/actions/ql/src/Security/CWE-285/ImproperAccessControl.ql
ql/actions/ql/src/Security/CWE-312/ExcessiveSecretsExposure.ql
ql/actions/ql/src/Security/CWE-312/SecretsInArtifacts.ql
ql/actions/ql/src/Security/CWE-312/UnmaskedSecretExposure.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql
ql/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql
ql/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUHigh.ql
ql/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.ql

View File

@@ -1,27 +0,0 @@
ql/actions/ql/src/Debug/SyntaxError.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/EnvVarInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionMedium.ql
ql/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql
ql/actions/ql/src/Security/CWE-094/CodeInjectionMedium.ql
ql/actions/ql/src/Security/CWE-1395/UseOfKnownVulnerableAction.ql
ql/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql
ql/actions/ql/src/Security/CWE-285/ImproperAccessControl.ql
ql/actions/ql/src/Security/CWE-312/ExcessiveSecretsExposure.ql
ql/actions/ql/src/Security/CWE-312/SecretsInArtifacts.ql
ql/actions/ql/src/Security/CWE-312/UnmaskedSecretExposure.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql
ql/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql
ql/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUHigh.ql
ql/actions/ql/src/Security/CWE-571/ExpressionIsAlwaysTrueCritical.ql
ql/actions/ql/src/Security/CWE-571/ExpressionIsAlwaysTrueHigh.ql
ql/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql
ql/actions/ql/src/Security/CWE-829/ArtifactPoisoningMedium.ql
ql/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.ql
ql/actions/ql/src/Violations Of Best Practice/CodeQL/UnnecessaryUseOfAdvancedConfig.ql

View File

@@ -1,23 +0,0 @@
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/EnvVarInjectionCritical.ql
ql/actions/ql/src/Security/CWE-077/EnvVarInjectionMedium.ql
ql/actions/ql/src/Security/CWE-094/CodeInjectionCritical.ql
ql/actions/ql/src/Security/CWE-094/CodeInjectionMedium.ql
ql/actions/ql/src/Security/CWE-1395/UseOfKnownVulnerableAction.ql
ql/actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql
ql/actions/ql/src/Security/CWE-285/ImproperAccessControl.ql
ql/actions/ql/src/Security/CWE-312/ExcessiveSecretsExposure.ql
ql/actions/ql/src/Security/CWE-312/SecretsInArtifacts.ql
ql/actions/ql/src/Security/CWE-312/UnmaskedSecretExposure.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaCodeInjection.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaDirectCache.ql
ql/actions/ql/src/Security/CWE-349/CachePoisoningViaPoisonableStep.ql
ql/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUCritical.ql
ql/actions/ql/src/Security/CWE-367/UntrustedCheckoutTOCTOUHigh.ql
ql/actions/ql/src/Security/CWE-829/ArtifactPoisoningCritical.ql
ql/actions/ql/src/Security/CWE-829/ArtifactPoisoningMedium.ql
ql/actions/ql/src/Security/CWE-829/UnpinnedActionsTag.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutCritical.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutHigh.ql
ql/actions/ql/src/Security/CWE-829/UntrustedCheckoutMedium.ql

View File

@@ -1,17 +0,0 @@
ql/actions/ql/src/Debug/partial.ql
ql/actions/ql/src/Models/CompositeActionsSinks.ql
ql/actions/ql/src/Models/CompositeActionsSources.ql
ql/actions/ql/src/Models/CompositeActionsSummaries.ql
ql/actions/ql/src/Models/ReusableWorkflowsSinks.ql
ql/actions/ql/src/Models/ReusableWorkflowsSources.ql
ql/actions/ql/src/Models/ReusableWorkflowsSummaries.ql
ql/actions/ql/src/experimental/Security/CWE-074/OutputClobberingHigh.ql
ql/actions/ql/src/experimental/Security/CWE-078/CommandInjectionCritical.ql
ql/actions/ql/src/experimental/Security/CWE-078/CommandInjectionMedium.ql
ql/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionCritical.ql
ql/actions/ql/src/experimental/Security/CWE-088/ArgumentInjectionMedium.ql
ql/actions/ql/src/experimental/Security/CWE-200/SecretExfiltration.ql
ql/actions/ql/src/experimental/Security/CWE-284/CodeExecutionOnSelfHostedRunner.ql
ql/actions/ql/src/experimental/Security/CWE-829/ArtifactPoisoningPathTraversal.ql
ql/actions/ql/src/experimental/Security/CWE-829/UnversionedImmutableAction.ql
ql/actions/ql/src/experimental/Security/CWE-918/RequestForgery.ql

View File

@@ -1,14 +0,0 @@
import runs_on
import pytest
from query_suites import *
well_known_query_suites = ['actions-code-quality.qls', 'actions-code-quality-extended.qls', 'actions-security-and-quality.qls', 'actions-security-extended.qls', 'actions-code-scanning.qls']
@runs_on.posix
@pytest.mark.parametrize("query_suite", well_known_query_suites)
def test(codeql, actions, check_query_suite, query_suite):
check_query_suite(query_suite)
@runs_on.posix
def test_not_included_queries(codeql, actions, check_queries_not_included):
check_queries_not_included('actions', well_known_query_suites)

View File

@@ -1,75 +1,3 @@
## 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
No user-facing changes.
## 0.4.10
No user-facing changes.
## 0.4.9
No user-facing changes.
## 0.4.8
No user-facing changes.
## 0.4.7
### New Features
* CodeQL and Copilot Autofix support for GitHub Actions is now Generally Available.
## 0.4.6
### Bug Fixes
* The query `actions/code-injection/medium` now produces alerts for injection
vulnerabilities on `pull_request` events.
## 0.4.5
No user-facing changes.
## 0.4.4
No user-facing changes.
## 0.4.3
### New Features
* The "Unpinned tag for a non-immutable Action in workflow" query (`actions/unpinned-tag`) now supports expanding the trusted action owner list using data extensions (`extensible: trustedActionsOwnerDataModel`). If you trust an Action publisher, you can include the owner name/organization in a model pack to add it to the allow list for this query. This addition will prevent security alerts when using unpinned tags for Actions published by that owner. For more information on creating a model pack, see [Creating a CodeQL Model Pack](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-codeql-model-pack).
## 0.4.2
### Bug Fixes
* Fixed data for vulnerable versions of `actions/download-artifact` and `rlespinasse/github-slug-action` (following GHSA-cxww-7g56-2vh6 and GHSA-6q4m-7476-932w).
* Improved `untrustedGhCommandDataModel` regex for `gh pr view` and Bash taint analysis in GitHub Actions.
## 0.4.1
No user-facing changes.

View File

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

View File

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

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,6 +0,0 @@
## 0.4.2
### Bug Fixes
* Fixed data for vulnerable versions of `actions/download-artifact` and `rlespinasse/github-slug-action` (following GHSA-cxww-7g56-2vh6 and GHSA-6q4m-7476-932w).
* Improved `untrustedGhCommandDataModel` regex for `gh pr view` and Bash taint analysis in GitHub Actions.

View File

@@ -1,5 +0,0 @@
## 0.4.3
### New Features
* The "Unpinned tag for a non-immutable Action in workflow" query (`actions/unpinned-tag`) now supports expanding the trusted action owner list using data extensions (`extensible: trustedActionsOwnerDataModel`). If you trust an Action publisher, you can include the owner name/organization in a model pack to add it to the allow list for this query. This addition will prevent security alerts when using unpinned tags for Actions published by that owner. For more information on creating a model pack, see [Creating a CodeQL Model Pack](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-codeql-model-pack).

View File

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

View File

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

View File

@@ -1,6 +0,0 @@
## 0.4.6
### Bug Fixes
* The query `actions/code-injection/medium` now produces alerts for injection
vulnerabilities on `pull_request` events.

View File

@@ -1,5 +0,0 @@
## 0.4.7
### New Features
* CodeQL and Copilot Autofix support for GitHub Actions is now Generally Available.

View File

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

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.15
lastReleaseVersion: 0.4.1

View File

@@ -50,8 +50,8 @@ class Expression extends AstNode instanceof ExpressionImpl {
string getNormalizedExpression() { result = normalizeExpr(expression) }
}
/** An `env` in workflow, job or step. */
class Env extends AstNode instanceof EnvImpl {
/** A common class for `env` in workflow, job or step. */
abstract class Env extends AstNode instanceof EnvImpl {
/** Gets an environment variable value given its name. */
ScalarValueImpl getEnvVarValue(string name) { result = super.getEnvVarValue(name) }

View File

@@ -8,64 +8,35 @@ class BashShellScript extends ShellScript {
)
}
/**
* Gets the line at 0-based index `lineIndex` within this shell script,
* assuming newlines as separators.
*/
private string lineProducer(int lineIndex) {
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", lineIndex)
private string lineProducer(int i) {
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
}
private predicate cmdSubstitutionReplacement(string command, string id, int lineIndex) {
this.commandInSubstitution(lineIndex, command, id)
or
this.commandInBackticks(lineIndex, command, id)
}
/**
* Holds if there is a command substitution `$(command)` in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this command.
*/
private predicate commandInSubstitution(int lineIndex, string command, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
command =
// Look for the command inside a $(...) command substitution
this.lineProducer(lineIndex)
.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", occurrenceIndex,
occurrenceOffset)
// trim starting $( - TODO do this in first regex
.regexpReplaceAll("^\\$\\(", "")
// trim ending ) - TODO do this in first regex
.regexpReplaceAll("\\)$", "") and
id = "cmdsubs:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
private predicate cmdSubstitutionReplacement(string cmdSubs, string id, int k) {
exists(string line | line = this.lineProducer(k) |
exists(int i, int j |
cmdSubs =
// $() cmd substitution
line.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", i, j)
.regexpReplaceAll("^\\$\\(", "")
.regexpReplaceAll("\\)$", "") and
id = "cmdsubs:" + k + ":" + i + ":" + j
)
or
exists(int i, int j |
// `...` cmd substitution
cmdSubs =
line.regexpFind("\\`[^\\`]+\\`", i, j)
.regexpReplaceAll("^\\`", "")
.regexpReplaceAll("\\`$", "") and
id = "cmd:" + k + ":" + i + ":" + j
)
)
}
/**
* Holds if `command` is a command in backticks `` `...` `` in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this command.
*/
private predicate commandInBackticks(int lineIndex, string command, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
command =
this.lineProducer(lineIndex)
.regexpFind("\\`[^\\`]+\\`", occurrenceIndex, occurrenceOffset)
// trim leading backtick - TODO do this in first regex
.regexpReplaceAll("^\\`", "")
// trim trailing backtick - TODO do this in first regex
.regexpReplaceAll("\\`$", "") and
id = "cmd:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
)
}
private predicate rankedCmdSubstitutionReplacements(int i, string command, string commandId) {
// rank commands by their unique IDs
commandId = rank[i](string c, string id | this.cmdSubstitutionReplacement(c, id, _) | id) and
// since we cannot output (command, ID) tuples from the rank operation,
// we need to work out the specific command associated with the resulting ID
this.cmdSubstitutionReplacement(command, commandId, _)
private predicate rankedCmdSubstitutionReplacements(int i, string old, string new) {
old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
this.cmdSubstitutionReplacement(old, new, _)
}
private predicate doReplaceCmdSubstitutions(int line, int round, string old, string new) {
@@ -93,56 +64,29 @@ class BashShellScript extends ShellScript {
this.cmdSubstitutionReplacement(result, _, i)
}
/**
* Holds if `quotedStr` is a string in double quotes in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this quoted string.
*/
private predicate doubleQuotedString(int lineIndex, string quotedStr, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
// double quoted string
quotedStr =
this.cmdSubstitutedLineProducer(lineIndex)
.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", occurrenceIndex, occurrenceOffset) and
id =
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
}
/**
* Holds if `quotedStr` is a string in single quotes in
* the line at `lineIndex` in the shell script,
* and `id` is a unique identifier for this quoted string.
*/
private predicate singleQuotedString(int lineIndex, string quotedStr, string id) {
exists(int occurrenceIndex, int occurrenceOffset |
// single quoted string
quotedStr =
this.cmdSubstitutedLineProducer(lineIndex)
.regexpFind("'((?:\\\\.|[^'\\\\])*)'", occurrenceIndex, occurrenceOffset) and
id =
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
}
private predicate quotedStringReplacement(string quotedStr, string id) {
exists(int lineIndex |
this.doubleQuotedString(lineIndex, quotedStr, id)
exists(string line, int k | line = this.cmdSubstitutedLineProducer(k) |
exists(int i, int j |
// double quoted string
quotedStr = line.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", i, j) and
id =
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
or
this.singleQuotedString(lineIndex, quotedStr, id)
) and
// Only do this for strings that might otherwise disrupt subsequent parsing
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
exists(int i, int j |
// single quoted string
quotedStr = line.regexpFind("'((?:\\\\.|[^'\\\\])*)'", i, j) and
id =
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
)
)
}
private predicate rankedQuotedStringReplacements(int i, string quotedString, string quotedStringId) {
// rank quoted strings by their nearly-unique IDs
quotedStringId = rank[i](string s, string id | this.quotedStringReplacement(s, id) | id) and
// since we cannot output (string, ID) tuples from the rank operation,
// we need to work out the specific string associated with the resulting ID
this.quotedStringReplacement(quotedString, quotedStringId)
private predicate rankedQuotedStringReplacements(int i, string old, string new) {
old = rank[i](string old2 | this.quotedStringReplacement(old2, _) | old2) and
this.quotedStringReplacement(old, new)
}
private predicate doReplaceQuotedStrings(int line, int round, string old, string new) {
@@ -751,19 +695,6 @@ module Bash {
not varMatchesRegexTest(script, var2, alphaNumericRegex())
)
or
exists(string var2, string value2, string var3, string value3 |
// VAR2=$(cmd)
// VAR3=$VAR2
// echo "FIELD=${VAR3:-default}" >> $GITHUB_ENV (field, file_write_value)
containsCmdSubstitution(value2, cmd) and
script.getAnAssignment(var2, value2) and
containsParameterExpansion(value3, var2, _, _) and
script.getAnAssignment(var3, value3) and
containsParameterExpansion(expr, var3, _, _) and
not varMatchesRegexTest(script, var2, alphaNumericRegex()) and
not varMatchesRegexTest(script, var3, alphaNumericRegex())
)
or
// var reaches the file write directly
// echo "FIELD=$(cmd)" >> $GITHUB_ENV (field, file_write_value)
containsCmdSubstitution(expr, cmd)

View File

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

View File

@@ -126,15 +126,6 @@ predicate vulnerableActionsDataModel(
*/
predicate immutableActionsDataModel(string action) { Extensions::immutableActionsDataModel(action) }
/**
* MaD models for trusted actions owners
* Fields:
* - owner: owner name
*/
predicate trustedActionsOwnerDataModel(string owner) {
Extensions::trustedActionsOwnerDataModel(owner)
}
/**
* MaD models for untrusted git commands
* Fields:
@@ -154,13 +145,3 @@ predicate untrustedGitCommandDataModel(string cmd_regex, string flag) {
predicate untrustedGhCommandDataModel(string cmd_regex, string flag) {
Extensions::untrustedGhCommandDataModel(cmd_regex, flag)
}
/**
* MaD models for permissions needed by actions
* Fields:
* - action: action name, e.g. `actions/checkout`
* - permission: permission name, e.g. `contents: read`
*/
predicate actionsPermissionsDataModel(string action, string permission) {
Extensions::actionsPermissionsDataModel(action, permission)
}

View File

@@ -63,11 +63,6 @@ extensible predicate vulnerableActionsDataModel(
*/
extensible predicate immutableActionsDataModel(string action);
/**
* Holds for trusted Actions owners.
*/
extensible predicate trustedActionsOwnerDataModel(string owner);
/**
* Holds for git commands that may introduce untrusted data when called on an attacker controlled branch.
*/
@@ -77,14 +72,3 @@ extensible predicate untrustedGitCommandDataModel(string cmd_regex, string flag)
* Holds for gh commands that may introduce untrusted data
*/
extensible predicate untrustedGhCommandDataModel(string cmd_regex, string flag);
/**
* Holds if `action` needs `permission` to run.
* - 'action' is the name of the action without any version information.
* E.g. for the action selector `actions/checkout@v2`, `action` is `actions/checkout`.
* - `permission` is of the form `scope-name: read|write`, for example `contents: read`.
* - see https://github.com/actions/checkout?tab=readme-ov-file#recommended-permissions
* for an example of recommended permissions.
* - see https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token for documentation of token permissions.
*/
extensible predicate actionsPermissionsDataModel(string action, string permission);

View File

@@ -134,10 +134,6 @@ private module Implementation implements CfgShared::InputSig<Location> {
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
predicate isAbnormalExitType(SuccessorType t) { none() }
int idOfAstNode(AstNode node) { none() }
int idOfCfgScope(CfgScope scope) { none() }
}
module CfgImpl = CfgShared::Make<Location, Implementation>;

View File

@@ -1,7 +1,6 @@
private import actions
private import codeql.actions.TaintTracking
private import codeql.actions.dataflow.ExternalFlow
private import codeql.actions.security.ControlChecks
import codeql.actions.dataflow.FlowSources
import codeql.actions.DataFlow
@@ -66,16 +65,6 @@ class ArgumentInjectionFromMaDSink extends ArgumentInjectionSink {
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
* that is used to construct and evaluate a code script.
@@ -99,16 +88,6 @@ private module ArgumentInjectionConfig implements DataFlow::ConfigSig {
run.getScript().getAnEnvReachingArgumentInjectionSink(var, _, _)
)
}
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 code script. */

View File

@@ -4,7 +4,6 @@ import codeql.actions.DataFlow
import codeql.actions.dataflow.FlowSources
import codeql.actions.security.PoisonableSteps
import codeql.actions.security.UntrustedCheckoutQuery
import codeql.actions.security.ControlChecks
string unzipRegexp() { result = "(unzip|tar)\\s+.*" }
@@ -263,10 +262,8 @@ class ArtifactPoisoningSink extends DataFlow::Node {
ArtifactPoisoningSink() {
download.getAFollowingStep() = poisonable and
// excluding artifacts downloaded to the temporary directory
// excluding artifacts downloaded to /tmp
not download.getPath().regexpMatch("^/tmp.*") and
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*") and
(
poisonable.(Run).getScript() = this.asExpr() and
(
@@ -293,16 +290,6 @@ class ArtifactPoisoningSink extends DataFlow::Node {
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
* that is used may lead to artifact poisoning
@@ -329,16 +316,6 @@ private module ArtifactPoisoningConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand())
)
}
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 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
import codeql.actions.dataflow.FlowSources
import codeql.actions.DataFlow
import codeql.actions.security.ControlChecks
import codeql.actions.security.CachePoisoningQuery
class CodeInjectionSink extends DataFlow::Node {
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
* that is used to construct and evaluate a code script.
@@ -77,18 +35,6 @@ private module CodeInjectionConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand())
)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
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. */

View File

@@ -3,20 +3,11 @@ private import codeql.actions.TaintTracking
private import codeql.actions.dataflow.ExternalFlow
import codeql.actions.dataflow.FlowSources
import codeql.actions.DataFlow
import codeql.actions.security.ControlChecks
private class CommandInjectionSink extends DataFlow::Node {
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
* 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 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. */

View File

@@ -72,25 +72,6 @@ class EnvPathInjectionFromMaDSink extends EnvPathInjectionSink {
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
* that is used to construct and evaluate an environment variable.
@@ -127,18 +108,6 @@ private module EnvPathInjectionConfig implements DataFlow::ConfigSig {
exists(run.getScript().getAFileReadCommand())
)
}
predicate observeDiffInformedIncrementalMode() { any() }
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
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. */

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