Skip to content

ci(secu): check dependency actions #136

ci(secu): check dependency actions

ci(secu): check dependency actions #136

name: dependency-checks
on:
pull_request:
workflow_call:
inputs:
module_directory:
description: 'Component path'
required: false
default: ""
type: string
permissions:
contents: read
env:
minimum_package_age_hours: 1 # 168 # 7 days
jobs:
dependency-scan:
name: Run safe-chain 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: Setup Pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
with:
version: 10
- name: Setup Node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: 22
package-manager-cache: true
- name: Install safe-chain
run: |
max_retries=5
retry_delay=5
for ((i=1; i<=max_retries; i++)); do
if curl -fsSL https://github.com/AikidoSec/safe-chain/releases/latest/download/install-safe-chain.sh | sh -s -- --ci; then
echo "Success on attempt $i"
exit 0
else
echo "Attempt $i failed. Retrying in $retry_delay seconds..."
sleep $retry_delay
fi
done
echo "All $max_retries attempts failed."
exit 1
shell: bash
- name: Check dependencies and managers
run: |
set +x
# 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
export SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS=${{ env.minimum_package_age_hours }}
export SAFE_CHAIN_LOGGING="silent"
ERROR_LOG="error_log.txt"
FORCE_FAIL="false"
ENFORCEMENT="false"
if [ "$current_timestamp" -ge "$input_timestamp" ]; then
echo "[DEBUG]: Deadline passed."
ENFORCEMENT="true"
fi
function message_type() {
if [ $ENFORCEMENT == "true" ]; then
echo "[ERROR] : $1" >> "$ERROR_LOG"
FORCE_FAIL="true"
else
echo "[WARNING] : $1" >> "$ERROR_LOG"
fi
}
# Compare pnpm version used in lockfile
function compare_version() {
SKIP="false"
MIN_LOCKFILE_VERSION="9.0.0"
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 LOC-VERSION = $LOCKFILE_VERSION"
if version_ge "$MIN_LOCKFILE_VERSION" "$LOCKFILE_VERSION"; then
echo "[DEBUG] - 1 - LOCKFILE_VERSION is lower than $MIN_LOCKFILE_VERSION"
echo "[DEBUG] - 1b - Analysis skipped"
message_type "lockfileVersion $LOCKFILE_VERSION < $MIN_LOCKFILE_VERSION in $LOC_FILE"
SKIP="true"
fi
}
# Move to module folder and find manifests
MODULE_FOLDER="${{ inputs.module_directory }}" || ""
if [[ -n "$MODULE_FOLDER" ]]; then
cd $MODULE_FOLDER
fi
touch "$ERROR_LOG"
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 : $LOC_FILE"
;;
"package-lock.json")
COUNT=$((COUNT+1))
message_type "NPM is no longer allowed. Kindly replace the lockfile using PNPM : $LOC_FILE"
;;
"pnpm-lock.yaml")
echo -e "\n\n"
echo "[DEBUG] - get pnpm version"
pnpm -v
echo "[DEBUG] - get node version"
node -v
echo "[DEBUG] - compare version start"
local skip=$(compare_version)
if [ "$SKIP" == "true" ] ; then continue; fi
echo "[DEBUG] - check manifests"
ls -la package.json
ls -la pnpm-lock.yaml
echo "[DEBUG] - LOC_FILE = $LOC_FILE"
echo "[DEBUG] - safe chain start"
#pnpm install --frozen-lockfile --loglevel warn --safe-chain-logging=verbose
pnpm install --frozen-lockfile --safe-chain-logging=verbose
COUNT=$((COUNT+1))
;;
"*")
message_type "no lockfile found in $LOC_DIR"
;;
esac
cd -
done
if [[ $COUNT -gt 1 ]]; then
message_type "$COUNT lockfiles were found. Kindly keep only the lockfile generated with PNPM : $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
shell: bash
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