ci(secu): check dependency actions #158
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: dependency-checks | |
| on: | |
| pull_request: | |
| workflow_call: | |
| inputs: | |
| module_directory: | |
| description: 'Component path' | |
| required: false | |
| default: "" | |
| type: string | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| env: | |
| minimum_package_age_hours: 1 # 168 # 7 days | |
| jobs: | |
| dependency-scan: | |
| name: Run PNPM usage analysis | |
| runs-on: ${{ github.repository_visibility != 'public' && 'centreon-security' || 'ubuntu-24.04' }} | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check dependencies type and managers version | |
| run: | | |
| # Check override | |
| if [ "${{ vars.OVERRIDE_ALL_DEPENDENCY_SCAN }}" == "true" ]; then | |
| echo "[DEBUG] - Global scan override enabled" | |
| return 0 | |
| elif [[ "${{ vars.OVERRIDE_PNPM_COMPLIANCE }}" == "true" ]]; then | |
| echo "[DEBUG] - PNPM scan override enabled" | |
| return 0 | |
| fi | |
| # Check date | |
| current_timestamp=$(date +%s) | |
| DUE_DATE="${{ vars.OVERRIDE_DEPENDENCY_ENFORCEMENT_DATE }}" | |
| input_timestamp=$(date -d "$DUE_DATE" +%s) | |
| # Setup vars | |
| ERROR_LOG="error_log.txt" | |
| touch "$ERROR_LOG" | |
| FORCE_FAIL="false" | |
| ENFORCEMENT="false" | |
| SKIP="false" | |
| if [ "$current_timestamp" -ge "$input_timestamp" ]; then | |
| echo "[DEBUG]: Deadline passed." | |
| ENFORCEMENT="true" | |
| fi | |
| function message_type() { | |
| MSG="$1" | |
| if [ $ENFORCEMENT == "true" ]; then | |
| echo "[ERROR] : $MSG" | |
| FORCE_FAIL="true" | |
| else | |
| echo "[WARNING] : $MSG" | |
| fi | |
| echo "$MSG" >> "$ERROR_LOG" | |
| } | |
| # Compare pnpm version used in lockfile | |
| function compare_version() { | |
| SKIP="false" | |
| MIN_LOCKFILE_VERSION="8.9.9" | |
| LOCKFILE_VERSION=$(grep -E '^lockfileVersion:' "$LOC_TYPE" \ | |
| | awk '{print $2}' \ | |
| | tr -d "'\"") | |
| # Compare versions | |
| version_ge() { | |
| [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ] | |
| } | |
| echo "[DEBUG] - 0 - before condition LOCKFILE_VERSION = $LOCKFILE_VERSION / MIN_LOCKFILE_VERSION = $MIN_LOCKFILE_VERSION" | |
| if version_ge "$MIN_LOCKFILE_VERSION" "$LOCKFILE_VERSION"; then | |
| echo "[DEBUG] - 1 - LOCKFILE_VERSION is lower than $MIN_LOCKFILE_VERSION" | |
| message_type "lockfileVersion $LOCKFILE_VERSION < $MIN_LOCKFILE_VERSION found in $LOC_FILE. Lockfile update required" | |
| else | |
| echo "[DEBUG] - 1 - LOCKFILE_VERSION is greater or equal to $MIN_LOCKFILE_VERSION" | |
| SKIP="true" | |
| fi | |
| echo "[DEBUG] - SKIP in compare = $SKIP" | |
| } | |
| # Move to module folder and find manifests | |
| MODULE_FOLDER="${{ inputs.module_directory }}" || "" | |
| if [[ -n "$MODULE_FOLDER" ]]; then | |
| cd $MODULE_FOLDER | |
| fi | |
| echo "[INFO] - Find manifest files" | |
| DEP_FILES=($(find ./ -type f -name "package.json")) | |
| # Scan node manifests | |
| for DEP_FILE in ${DEP_FILES[@]}; do | |
| DEP_DIR=$(dirname $DEP_FILE) | |
| echo "[INFO] - Scanning $DEP_FILE" | |
| echo "[DEBUG] - DEP_FILE = $DEP_FILE" | |
| LOC_FILES=($(find $DEP_DIR -type f -name "package-lock.json" -o -name "pnpm-lock.yaml" -o -name "yarn.lock")) | |
| COUNT=0 | |
| for LOC_FILE in ${LOC_FILES[@]}; do | |
| LOC_TYPE=$(basename $LOC_FILE) | |
| LOC_DIR=$(dirname $LOC_FILE) | |
| #cd $LOC_DIR | |
| case $LOC_TYPE in | |
| "yarn.lock") | |
| COUNT=$((COUNT+1)) | |
| message_type "Yarn is no longer allowed. Kindly replace the lockfile using PNPM. Found in $LOC_FILE" | |
| ;; | |
| "package-lock.json") | |
| COUNT=$((COUNT+1)) | |
| message_type "NPM is no longer allowed. Kindly replace the lockfile using PNPM. Found in $LOC_FILE" | |
| ;; | |
| "pnpm-lock.yaml") | |
| echo "[DEBUG] - compare version start" | |
| SKIP=$(compare_version) | |
| echo "[DEBUG] - SKIP = $SKIP" | |
| if [ "$SKIP" == "true" ] ; then continue; fi | |
| COUNT=$((COUNT+1)) | |
| ;; | |
| "*") | |
| message_type "No lockfile found in $LOC_DIR. A lockfile is required." | |
| ;; | |
| esac | |
| #cd - | |
| done | |
| if [[ $COUNT -gt 1 ]]; then | |
| message_type "$COUNT lockfiles were found. Kindly keep only lockfile generated with PNPM. Found in $LOC_DIR" | |
| fi | |
| echo "[DEBUG] - COUNT = $COUNT" | |
| done | |
| echo "[DEBUG] - FORCE_FAIL = $FORCE_FAIL" | |
| if [ -s "$ERROR_LOG" ]; then | |
| cat "$ERROR_LOG" | |
| if [ "FORCE_FAIL" == "true" ]; then | |
| echo "[FATAL]: Breaking the run." | |
| exit 1 | |
| fi | |
| else | |
| echo "[INFO] - OK nothing found" | |
| fi | |
| echo -e "\n\n[DEBUG] - ERROR_LOG :" | |
| cat $ERROR_LOG | |
| shell: bash | |
| - name: comment_PR | |
| uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 | |
| with: | |
| hide_and_recreate: true | |
| hide_classify: "OUTDATED" | |
| path: "error_log.txt" | |
| dependency-blacklist: | |
| name: Run blacklist analysis | |
| runs-on: ${{ github.repository_visibility != 'public' && 'centreon-security' || 'ubuntu-24.04' }} | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for blacklisted dependencies | |
| run: | | |
| # Check override | |
| if [ "${{ vars.OVERRIDE_DEPENDENCY_SCAN }}" == "true" ]; then | |
| echo "[DEBUG] - Global scan override enabled" | |
| return 0 | |
| elif [[ "${{ vars.OVERRIDE_BLACKLIST_COMPLIANCE }}" == "true" ]]; then | |
| echo "[DEBUG] - Blacklist scan override enabled" | |
| return 0 | |
| fi | |
| function checkPnpmLockfile() { | |
| # Find dependency formated as | |
| # "name@version:" | |
| if grep -qF "$NAME@$VERSION" "$LOCKFILE"; then | |
| echo "$NAME:$VERSION was found in $LOCKFILE" | |
| echo "[ERROR] - $NAME:$VERSION was found in $LOCKFILE" >> "$ERROR_LOG" | |
| else | |
| echo -n "." | |
| fi | |
| } | |
| function checkManifest() { | |
| COUNT=0 | |
| echo "[INFO] - Testing manifest $LOCKFILE" | |
| manifest_type=$(basename "$LOCKFILE") | |
| while IFS=':' read -r NAME VERSION; do | |
| # ignore empty and commented lines | |
| [[ -z "${NAME// }" ]] && continue | |
| [[ "$NAME" =~ ^# ]] && continue | |
| case "$manifest_type" in | |
| "pnpm-lock.yaml") | |
| checkPnpmLockfile | |
| ;; | |
| "yarn.lock") | |
| echo "[ERROR] - dependency manager not allowed. Found in $LOCKFILE" >> "$ERROR_LOG" | |
| ;; | |
| "package-lock.json") | |
| echo "[ERROR] - dependency manager not allowed. Found in $LOCKFILE" >> "$ERROR_LOG" | |
| ;; | |
| "*") | |
| echo "[ERROR] - dependency manager not managed. Found in $LOCKFILE" >> "$ERROR_LOG" | |
| esac | |
| COUNT=$((COUNT+1)) | |
| done < "$DEP_LIST" | |
| echo "[INFO] - Scanned $COUNT IOC" | |
| } | |
| DEP_LIST="compromised-packages.txt" | |
| if [ -f "$DEP_LIST" ]; then rm -f "$DEP_LIST"; fi | |
| wget https://raw.githubusercontent.com/centreon/security-tools/main/blacklist/"$DEP_LIST" | |
| ERROR_LOG="error_log.txt" | |
| touch "$ERROR_LOG" | |
| LOCKFILES=($(find ./ -type f -name "pnpm-lock.yaml")) | |
| for LOCKFILE in "${LOCKFILES[@]}"; do | |
| checkManifest "$LOCKFILE" | |
| done | |
| if [ -s "$ERROR_LOG" ]; then | |
| echo -e "[ERROR]: Breaking the run as following ERRORS were found:" | |
| cat "$ERROR_LOG" | |
| exit 1 | |
| else | |
| echo "[INFO] - OK nothing found" | |
| fi | |
| shell: bash |