diff --git a/.github/labeler.yml b/.github/labeler.yml index 0e43646c7ba2..65f820799716 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -38,6 +38,10 @@ Swift: - swift/**/* - change-notes/**/*swift* +Actions: + - actions/**/* + - change-notes/**/*actions* + documentation: - "**/*.qhelp" - "**/*.md" diff --git a/actions/extractor/codeql-extractor.yml b/actions/extractor/codeql-extractor.yml new file mode 100644 index 000000000000..ab7374910054 --- /dev/null +++ b/actions/extractor/codeql-extractor.yml @@ -0,0 +1,44 @@ +name: "actions" +aliases: [] +display_name: "GitHub Actions" +version: 0.0.1 +column_kind: "utf16" +unicode_newlines: true +build_modes: + - none +file_coverage_languages: [] +github_api_languages: [] +scc_languages: [] +file_types: + - name: workflow + display_name: GitHub Actions workflow files + extensions: + - .yml + - .yaml +forwarded_extractor_name: javascript +options: + trap: + title: TRAP options + description: Options about how the extractor handles TRAP files + type: object + visibility: 3 + properties: + cache: + title: TRAP cache options + description: Options about how the extractor handles its TRAP cache + type: object + properties: + dir: + title: TRAP cache directory + description: The directory of the TRAP cache to use + type: string + bound: + title: TRAP cache bound + description: A soft limit (in MB) on the size of the TRAP cache + type: string + pattern: "[0-9]+" + write: + title: TRAP cache writeable + description: Whether to write to the TRAP cache as well as reading it + type: string + pattern: "(true|TRUE|false|FALSE)" diff --git a/actions/extractor/tools/autobuild-impl.ps1 b/actions/extractor/tools/autobuild-impl.ps1 new file mode 100644 index 000000000000..6ae433f2599c --- /dev/null +++ b/actions/extractor/tools/autobuild-impl.ps1 @@ -0,0 +1,40 @@ +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 '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 +if ($LASTEXITCODE -ne 0) { + throw 'Failed to resolve JavaScript extractor.' +} + +Write-Output "Found JavaScript extractor at '${env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'." + +# Run the JavaScript autobuilder. +$JavaScriptAutoBuild = Join-Path $env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT 'tools\autobuild.cmd' +Write-Output "Running JavaScript autobuilder at '${JavaScriptAutoBuild}'." + +# Copy the values of the Actions extractor environment variables to the JavaScript extractor environment variables. +$env:CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_DIAGNOSTIC_DIR +$env:CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_LOG_DIR +$env:CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_SCRATCH_DIR +$env:CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR +$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 +if ($LASTEXITCODE -ne 0) { + throw "JavaScript autobuilder failed." +} diff --git a/actions/extractor/tools/autobuild.cmd b/actions/extractor/tools/autobuild.cmd new file mode 100644 index 000000000000..ff5ca89d94a4 --- /dev/null +++ b/actions/extractor/tools/autobuild.cmd @@ -0,0 +1,3 @@ +@echo off +rem All of the work is done in the PowerShell script +powershell.exe %~dp0autobuild-impl.ps1 diff --git a/actions/extractor/tools/autobuild.sh b/actions/extractor/tools/autobuild.sh new file mode 100755 index 000000000000..656e0f356352 --- /dev/null +++ b/actions/extractor/tools/autobuild.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +set -eu + +DEFAULT_PATH_FILTERS=$(cat << END +exclude:**/* +include:.github/workflows/**/*.yml +include:.github/workflows/**/*.yaml +include:**/action.yml +include:**/action.yaml +END +) + +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 "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)" +export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT + +echo "Found JavaScript extractor at '${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'." + +# Run the JavaScript autobuilder +JAVASCRIPT_AUTO_BUILD="${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}/tools/autobuild.sh" +echo "Running JavaScript autobuilder at '${JAVASCRIPT_AUTO_BUILD}'." + +# Copy the values of the Actions extractor environment variables to the JavaScript extractor environment variables. +env CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="${CODEQL_EXTRACTOR_ACTIONS_DIAGNOSTIC_DIR}" \ + CODEQL_EXTRACTOR_JAVASCRIPT_LOG_DIR="${CODEQL_EXTRACTOR_ACTIONS_LOG_DIR}" \ + CODEQL_EXTRACTOR_JAVASCRIPT_SCRATCH_DIR="${CODEQL_EXTRACTOR_ACTIONS_SCRATCH_DIR}" \ + 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} diff --git a/actions/ql/lib/actions.qll b/actions/ql/lib/actions.qll new file mode 100644 index 000000000000..073277dcace0 --- /dev/null +++ b/actions/ql/lib/actions.qll @@ -0,0 +1 @@ +predicate placeholder(int x) { x = 0 } diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml new file mode 100644 index 000000000000..4f674220c885 --- /dev/null +++ b/actions/ql/lib/qlpack.yml @@ -0,0 +1,12 @@ +name: codeql/actions-all +version: 0.0.1-dev +library: true +warnOnImplicitThis: true +dependencies: + codeql/util: ${workspace} + codeql/yaml: ${workspace} + codeql/controlflow: ${workspace} + codeql/dataflow: ${workspace} + codeql/javascript-all: ${workspace} +extractor: actions +groups: actions diff --git a/actions/ql/src/Placeholder.ql b/actions/ql/src/Placeholder.ql new file mode 100644 index 000000000000..63e32f04dfb3 --- /dev/null +++ b/actions/ql/src/Placeholder.ql @@ -0,0 +1,16 @@ +/** + * @name Placeholder Query + * @description Placeholder + * @kind problem + * @problem.severity warning + * @security-severity 9.3 + * @precision high + * @id actions/placeholder + * @tags actions security + */ + +import actions +import javascript + +from File f +select f, "Analyzed a file." diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml new file mode 100644 index 000000000000..0cede827207b --- /dev/null +++ b/actions/ql/src/qlpack.yml @@ -0,0 +1,8 @@ +name: codeql/actions-queries +version: 0.0.1-dev +library: false +groups: [actions, queries] +extractor: actions +dependencies: + codeql/actions-all: ${workspace} +warnOnImplicitThis: true diff --git a/actions/ql/test/library-tests/.github/workflows/shell.yml b/actions/ql/test/library-tests/.github/workflows/shell.yml new file mode 100644 index 000000000000..9392b81c6ab2 --- /dev/null +++ b/actions/ql/test/library-tests/.github/workflows/shell.yml @@ -0,0 +1,23 @@ +on: push + +jobs: + job1: + runs-on: ubuntu-latest + steps: + - shell: pwsh + run: Write-Output "foo" + job2: + runs-on: ubuntu-latest + steps: + - run: echo "foo" + + job3: + runs-on: windows-latest + steps: + - shell: bash + run: echo "foo" + job4: + runs-on: windows-latest + steps: + - run: Write-Output "foo" + diff --git a/actions/ql/test/library-tests/Placeholder.expected b/actions/ql/test/library-tests/Placeholder.expected new file mode 100644 index 000000000000..2a4f078a25fc --- /dev/null +++ b/actions/ql/test/library-tests/Placeholder.expected @@ -0,0 +1 @@ +| 1 | diff --git a/actions/ql/test/library-tests/Placeholder.ql b/actions/ql/test/library-tests/Placeholder.ql new file mode 100644 index 000000000000..82198eaf87be --- /dev/null +++ b/actions/ql/test/library-tests/Placeholder.ql @@ -0,0 +1 @@ +select 1 diff --git a/actions/ql/test/qlpack.yml b/actions/ql/test/qlpack.yml new file mode 100644 index 000000000000..12711bee904b --- /dev/null +++ b/actions/ql/test/qlpack.yml @@ -0,0 +1,8 @@ +name: codeql/actions-tests +groups: [codeql, test] +dependencies: + codeql/actions-all: ${workspace} + codeql/actions-queries: ${workspace} +extractor: actions +tests: . +warnOnImplicitThis: true diff --git a/actions/ql/test/query-tests/Placeholder/.github/workflows/shell.yml b/actions/ql/test/query-tests/Placeholder/.github/workflows/shell.yml new file mode 100644 index 000000000000..9392b81c6ab2 --- /dev/null +++ b/actions/ql/test/query-tests/Placeholder/.github/workflows/shell.yml @@ -0,0 +1,23 @@ +on: push + +jobs: + job1: + runs-on: ubuntu-latest + steps: + - shell: pwsh + run: Write-Output "foo" + job2: + runs-on: ubuntu-latest + steps: + - run: echo "foo" + + job3: + runs-on: windows-latest + steps: + - shell: bash + run: echo "foo" + job4: + runs-on: windows-latest + steps: + - run: Write-Output "foo" + diff --git a/actions/ql/test/query-tests/Placeholder/Placeholder.expected b/actions/ql/test/query-tests/Placeholder/Placeholder.expected new file mode 100644 index 000000000000..46bd70296bd9 --- /dev/null +++ b/actions/ql/test/query-tests/Placeholder/Placeholder.expected @@ -0,0 +1 @@ +| .github/workflows/shell.yml:0:0:0:0 | .github/workflows/shell.yml | File | diff --git a/actions/ql/test/query-tests/Placeholder/Placeholder.qlref b/actions/ql/test/query-tests/Placeholder/Placeholder.qlref new file mode 100644 index 000000000000..2ad15e688e23 --- /dev/null +++ b/actions/ql/test/query-tests/Placeholder/Placeholder.qlref @@ -0,0 +1 @@ +Placeholder.ql