Skip to content

IONOS(ci): Add Psalm taint analysis for external apps #37

IONOS(ci): Add Psalm taint analysis for external apps

IONOS(ci): Add Psalm taint analysis for external apps #37

# SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
name: Psalm static code analysis
on:
pull_request:
push:
branches:
- main
- master
- stable*
- kh/dev/static-analysis
- 'rc/**'
paths:
- '.github/workflows/static-code-analysis.yml'
- '**.php'
permissions:
contents: read
concurrency:
group: static-code-analysis-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
static-code-analysis:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'push' && github.repository_owner != 'nextcloud-gmbh' }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
submodules: true
- name: Set up php
uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a #v2.33.0
with:
php-version: '8.1'
extensions: apcu,ctype,curl,dom,fileinfo,ftp,gd,imagick,intl,json,ldap,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
coverage: none
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Composer install
run: composer i
- name: Psalm
run: composer run psalm -- --threads=1 --monochrome --no-progress --output-format=github --update-baseline
- name: Show potential changes in Psalm baseline
if: always()
run: git diff --exit-code -- . ':!lib/composer'
static-code-analysis-security:
runs-on: ubuntu-latest
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
submodules: true
- name: Set up php
uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a #v2.33.0
with:
php-version: '8.1'
extensions: ctype,curl,dom,fileinfo,ftp,gd,imagick,intl,json,ldap,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
coverage: none
- name: Composer install
run: composer i
- name: Psalm taint analysis
run: composer run psalm:security -- --threads=1 --monochrome --no-progress --output-format=github --update-baseline --report=results.sarif
- name: Show potential changes in Psalm baseline
if: always()
run: git diff --exit-code -- . ':!lib/composer'
- name: Upload Security Analysis results to GitHub
if: always()
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3
with:
sarif_file: results.sarif
static-code-analysis-ocp:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'push' && github.repository_owner != 'nextcloud-gmbh' }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
submodules: true
- name: Set up php
uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a #v2.33.0
with:
php-version: '8.1'
extensions: ctype,curl,dom,fileinfo,gd,imagick,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
coverage: none
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Composer install
run: composer i
- name: Psalm
run: composer run psalm:ocp -- --threads=1 --monochrome --no-progress --output-format=github --update-baseline
- name: Show potential changes in Psalm baseline
if: always()
run: git diff --exit-code -- . ':!lib/composer'
static-code-analysis-ncu:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'push' && github.repository_owner != 'nextcloud-gmbh' }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
submodules: true
- name: Set up php
uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a #v2.33.0
with:
php-version: '8.1'
extensions: ctype,curl,dom,fileinfo,gd,imagick,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
coverage: none
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Composer install
run: composer i
- name: Psalm
run: composer run psalm:ncu -- --threads=1 --monochrome --no-progress --output-format=github
# IONOS: Discover apps-external submodules that have psalm.xml for SAST matrix.
generate-sast-matrix:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout with submodules
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
submodules: true
- name: Discover apps with psalm.xml
id: set-matrix
run: |
apps=$(find apps-external -maxdepth 2 -name psalm.xml \
| sed 's|apps-external/||;s|/psalm.xml||' \
| sort | jq -R . | jq -sc .)
echo "matrix=$apps" >> "$GITHUB_OUTPUT"
# IONOS: Psalm taint analysis (security) for all apps-external submodules.
# Runs per-app in a matrix so each app uses its own psalm.xml and vendor.
# Non-blocking (continue-on-error) while baseline findings exist in upstream apps.
static-code-analysis-security-apps:
runs-on: ubuntu-latest
name: Psalm taint analysis - ${{ matrix.app }}
needs: generate-sast-matrix
permissions:
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
app: ${{ fromJson(needs.generate-sast-matrix.outputs.matrix) }}
# Allow upstream apps to have findings without blocking the pipeline.
# Remove continue-on-error once all apps are clean or baselined.
continue-on-error: true
steps:
- name: Checkout with submodules
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
submodules: true
- name: Set up PHP
uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a #v2.33.0
with:
php-version: '8.1'
extensions: ctype,curl,dom,fileinfo,gd,imagick,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
coverage: none
- name: Composer install
working-directory: apps-external/${{ matrix.app }}
run: composer install --no-interaction --prefer-dist
env:
COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GITHUB_TOKEN }}"}}'
- name: Locate psalm binary
id: psalm-bin
working-directory: apps-external/${{ matrix.app }}
run: |
if [ -f vendor/bin/psalm ]; then
echo "bin=vendor/bin/psalm" >> "$GITHUB_OUTPUT"
elif [ -f vendor/bin/psalm.phar ]; then
echo "bin=vendor/bin/psalm.phar" >> "$GITHUB_OUTPUT"
elif [ -f vendor-bin/psalm/vendor/bin/psalm ]; then
echo "bin=vendor-bin/psalm/vendor/bin/psalm" >> "$GITHUB_OUTPUT"
else
echo "::error::Psalm binary not found in apps-external/${{ matrix.app }} after composer install"
exit 1
fi
- name: Psalm taint analysis
working-directory: apps-external/${{ matrix.app }}
run: |
${{ steps.psalm-bin.outputs.bin }} \
--taint-analysis \
--no-cache \
--threads=1 \
--monochrome \
--no-progress \
--output-format=github \
--report=psalm-taint-results.sarif
continue-on-error: true
- name: Fix invalid region values in SARIF
if: always() && hashFiles(format('apps-external/{0}/psalm-taint-results.sarif', matrix.app)) != ''
working-directory: apps-external/${{ matrix.app }}
run: |
jq '[
"startLine", "startColumn", "endLine", "endColumn"
] as $fields |
walk(
if type == "object" then
reduce $fields[] as $f (.; if has($f) and ("number" == (.[$f] | type)) and .[$f] < 1 then .[$f] = 1 else . end)
else . end
)' \
psalm-taint-results.sarif > psalm-taint-results.sarif.tmp \
&& mv psalm-taint-results.sarif.tmp psalm-taint-results.sarif
- name: Upload SARIF to GitHub Security tab
if: always() && hashFiles(format('apps-external/{0}/psalm-taint-results.sarif', matrix.app)) != ''
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3
with:
sarif_file: apps-external/${{ matrix.app }}/psalm-taint-results.sarif
category: psalm-taint-${{ matrix.app }}