Files
cacti/.github/workflows/security.yml
Thomas Vincent 17638efecc ci(security): correct Semgrep request sources and HTML escaping rules (#8452)
* ci(security): treat grv() and gnrv() as Semgrep request sources

The gating XSS rule missed the short request helpers, the header() rule trusted HTML escapers that do not stop an off-site redirect, and the advisory taint rules missed get_request_var().

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci(security): gate Semgrep on new findings for every event

The new sources also match values an earlier gfrv() validated, so a whole-tree result cannot gate pushes; a single job keeps results stable run to run.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
2026-10-23 10:38:03 -06:00

120 lines
4.3 KiB
YAML

# +-------------------------------------------------------------------------+
# | Copyright (C) 2004-2026 The Cacti Group |
# | |
# | This program is free software; you can redistribute it and/or |
# | modify it under the terms of the GNU General Public License |
# | as published by the Free Software Foundation; either version 2 |
# | of the License, or (at your option) any later version. |
# +-------------------------------------------------------------------------+
# | Cacti: The Complete RRDtool-based Graphing Solution |
# +-------------------------------------------------------------------------+
name: Security SAST
on:
push:
branches: [develop, 1.2.x]
pull_request:
branches: [develop, 1.2.x]
merge_group:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: security-sast-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
semgrep:
name: Semgrep taint
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4
with:
fetch-depth: 0
persist-credentials: false
- name: Set up Docker with the public registry cache
uses: ./.github/actions/setup-ci-docker
# Every event gates on new findings only. The grv()/gnrv() sources also
# match request vars that an earlier gfrv() call validated, which Semgrep
# cannot see, so a whole-tree result is not a usable pass/fail gate.
- name: Run Semgrep
env:
EVENT_NAME: ${{ github.event_name }}
MERGE_GROUP_BASE_SHA: ${{ github.event.merge_group.base_sha }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PUSH_BASE_SHA: ${{ github.event.before }}
run: |
set -euo pipefail
case "$EVENT_NAME" in
pull_request)
base_sha="$PR_BASE_SHA"
;;
push)
base_sha="$PUSH_BASE_SHA"
;;
merge_group)
base_sha="$MERGE_GROUP_BASE_SHA"
;;
*)
base_sha=""
;;
esac
if [[ -z "$base_sha" || "$base_sha" =~ ^0+$ ]]; then
base_sha="$(git rev-parse --verify HEAD^ 2>/dev/null || git rev-parse --verify HEAD)"
fi
git cat-file -e "${base_sha}^{commit}"
# Parallel jobs hit taint fixpoint timeouts in Cacti's large files,
# so the same tree can report different findings run to run. One job
# keeps the result stable and still scans the whole tree in seconds.
semgrep_args=(--config .semgrep.yml --error -j 1 --baseline-commit "$base_sha")
docker run --rm \
--user "$(id -u):$(id -g)" \
--env HOME=/tmp \
--volume "${PWD}:/src" \
--workdir /src \
semgrep/semgrep@sha256:e04d2cb132288d90035db8791d64f610cb255b21e727b94db046243b30c01ae9 \
semgrep "${semgrep_args[@]}" .
psalm:
name: Psalm taint
runs-on: ubuntu-24.04
timeout-minutes: 20
env:
COMPOSER_ALLOW_SUPERUSER: 1
PSALM_VERSION: '6.16.1'
PSALM_PHAR_SHA256: '7ace71e4f698466e7e16810679a1895ea623060579aff46fcf9fd0f1c09abe00'
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v4
with:
persist-credentials: false
- name: Setup locked PHP 8.3 dependencies
uses: ./.github/actions/setup-php-composer
with:
php-version: '8.3'
extensions: intl, mysql, gd, ldap, gmp, xml, curl, json, mbstring
coverage: none
dependency-mode: locked-psalm
install-args: --no-dev --prefer-dist --no-progress --no-interaction
- name: Download and verify pinned Psalm phar
run: |
set -euo pipefail
curl --proto '=https' --proto-redir '=https' -fsSL -o psalm.phar \
"https://github.com/vimeo/psalm/releases/download/${PSALM_VERSION}/psalm.phar"
echo "${PSALM_PHAR_SHA256} psalm.phar" | sha256sum -c -
- name: Run Psalm taint analysis
run: php psalm.phar --taint-analysis --no-progress