|
#!/bin/bash |
|
|
|
# Script de vérification des paquets vulnérables Shai-Hulud (Version optimisée) |
|
# Usage: ./check-shai-hulud-fast.sh <lock-file-or-directory> [--debug] |
|
# Version sans dépendance jq |
|
|
|
# Démarrer le timer global |
|
START_TIME=$(date +%s) |
|
|
|
# Variable globale pour tracker les vulnérabilités |
|
GLOBAL_VULNERABILITIES_FOUND=0 |
|
|
|
# Sources de données |
|
TENABLE_URL="https://raw.githubusercontent.com/tenable/shai-hulud-second-coming-affected-packages/main/list.json" |
|
DATADOG_URL="https://raw.githubusercontent.com/DataDog/indicators-of-compromise/main/shai-hulud-2.0/consolidated_iocs.csv" |
|
LOCK_FILE_OR_DIR="$1" |
|
DEBUG=false |
|
|
|
# Vérifier si --debug est passé |
|
if [ "$2" = "--debug" ] || [ "$1" = "--debug" ]; then |
|
DEBUG=true |
|
if [ "$1" = "--debug" ]; then |
|
LOCK_FILE_OR_DIR="$2" |
|
fi |
|
fi |
|
|
|
TEMP_DIR=$(mktemp -d) |
|
TENABLE_LIST="$TEMP_DIR/tenable.json" |
|
DATADOG_LIST="$TEMP_DIR/datadog.csv" |
|
|
|
# Couleurs pour l'affichage |
|
RED='\033[0;31m' |
|
GREEN='\033[0;32m' |
|
YELLOW='\033[1;33m' |
|
ORANGE='\033[0;33m' |
|
NC='\033[0m' # No Color |
|
|
|
# Fonction de nettoyage |
|
cleanup() { |
|
rm -rf "$TEMP_DIR" |
|
} |
|
trap cleanup EXIT |
|
|
|
# Fonction d'aide |
|
usage() { |
|
echo "Usage: $0 <lock-file-or-directory> [--debug]" |
|
echo "" |
|
echo "Vérifie si des paquets vulnérables (Shai-Hulud) sont présents dans votre fichier lock" |
|
echo "" |
|
echo "Fichiers supportés:" |
|
echo " - yarn.lock" |
|
echo " - package-lock.json" |
|
echo " - pnpm-lock.yaml" |
|
echo " - bun.lock" |
|
echo "" |
|
echo "Exemple:" |
|
echo " $0 yarn.lock" |
|
echo " $0 /path/to/project" |
|
echo " $0 package-lock.json --debug" |
|
exit 1 |
|
} |
|
|
|
# Vérification des arguments |
|
if [ -z "$LOCK_FILE_OR_DIR" ]; then |
|
echo -e "${RED}Erreur: Fichier lock ou répertoire manquant${NC}" |
|
usage |
|
fi |
|
|
|
if [ ! -f "$LOCK_FILE_OR_DIR" ] && [ ! -d "$LOCK_FILE_OR_DIR" ]; then |
|
echo -e "${RED}Erreur: Le fichier/répertoire '$LOCK_FILE_OR_DIR' n'existe pas${NC}" |
|
exit 1 |
|
fi |
|
|
|
# Vérification de la présence de curl |
|
if ! command -v curl &> /dev/null; then |
|
echo -e "${RED}Erreur: curl n'est pas installé${NC}" |
|
exit 1 |
|
fi |
|
|
|
echo -e "${YELLOW}📥 Téléchargement des listes de paquets vulnérables...${NC}" |
|
DOWNLOAD_START=$(date +%s) |
|
|
|
# Télécharger la liste Tenable |
|
if ! curl -s "$TENABLE_URL" -o "$TENABLE_LIST" 2>/dev/null; then |
|
echo -e "${RED}⚠️ Avertissement: Impossible de télécharger la liste Tenable${NC}" |
|
TENABLE_LIST="" |
|
fi |
|
|
|
# Télécharger la liste Datadog |
|
if ! curl -s "$DATADOG_URL" -o "$DATADOG_LIST" 2>/dev/null; then |
|
echo -e "${RED}⚠️ Avertissement: Impossible de télécharger la liste Datadog${NC}" |
|
DATADOG_LIST="" |
|
fi |
|
|
|
# Vérifier qu'au moins une source est disponible |
|
if [ -z "$TENABLE_LIST" ] && [ -z "$DATADOG_LIST" ]; then |
|
echo -e "${RED}Erreur: Aucune liste de paquets vulnérables disponible${NC}" |
|
exit 1 |
|
fi |
|
|
|
DOWNLOAD_END=$(date +%s) |
|
DOWNLOAD_TIME=$((DOWNLOAD_END - DOWNLOAD_START)) |
|
|
|
# Afficher les sources disponibles |
|
if [ -n "$TENABLE_LIST" ]; then |
|
echo -e "${GREEN} ✓ Liste Tenable téléchargée${NC}" |
|
fi |
|
if [ -n "$DATADOG_LIST" ]; then |
|
echo -e "${GREEN} ✓ Liste Datadog téléchargée${NC}" |
|
fi |
|
echo -e "${YELLOW} ⏱️ Téléchargement: ${DOWNLOAD_TIME}s${NC}" |
|
|
|
# Parser les listes des paquets vulnérables (une seule fois) |
|
echo "" |
|
echo -e "${YELLOW}🔍 Analyse des listes de vulnérabilités...${NC}" |
|
PARSE_START=$(date +%s) |
|
|
|
PARSED_VULNERABLE="$TEMP_DIR/vulnerable_parsed.txt" |
|
> "$PARSED_VULNERABLE" # Créer le fichier vide |
|
|
|
# Parser Tenable (JSON) |
|
if [ -n "$TENABLE_LIST" ] && [ -f "$TENABLE_LIST" ]; then |
|
tenable_temp="$TEMP_DIR/tenable_parsed.txt" |
|
|
|
# Extraire toutes les chaînes entre guillemets puis parser avec awk |
|
grep -o '"[^"]*"' "$TENABLE_LIST" | awk ' |
|
# Si ça ressemble à un nom de paquet npm (commence par @ ou contient /) |
|
/^"@/ || /\// { |
|
gsub(/"/, "") |
|
# Exclure les clés JSON comme "vuln_vers" |
|
if ($0 !~ /vuln_vers/ && $0 !~ /^[0-9]/) { |
|
package = $0 |
|
} |
|
} |
|
# Si ça ressemble à une version (commence par un chiffre) |
|
/^"[0-9]/ { |
|
gsub(/"/, "") |
|
if (package != "") { |
|
print package ":" $0 |
|
} |
|
} |
|
' > "$tenable_temp" |
|
|
|
# Ajouter au fichier principal |
|
cat "$tenable_temp" >> "$PARSED_VULNERABLE" |
|
|
|
echo -e "${GREEN} ✓ Liste Tenable analysée ($(wc -l < "$tenable_temp" | xargs) entrées)${NC}" |
|
fi |
|
|
|
# Parser Datadog (CSV) |
|
if [ -n "$DATADOG_LIST" ] && [ -f "$DATADOG_LIST" ]; then |
|
datadog_temp="$TEMP_DIR/datadog_parsed.txt" |
|
|
|
# Utiliser awk pour un parsing beaucoup plus rapide |
|
# Format CSV: package_name,package_versions,sources |
|
awk -F',' ' |
|
NR > 1 { |
|
# Ignorer la ligne de header |
|
package = $1 |
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", package) # trim |
|
|
|
# Extraire les versions (colonne 2, peut contenir des virgules internes) |
|
# On reconstruit tout sauf la dernière colonne (sources) |
|
versions = $2 |
|
for (i = 3; i < NF; i++) { |
|
versions = versions "," $i |
|
} |
|
|
|
# Nettoyer les guillemets |
|
gsub(/"/, "", versions) |
|
|
|
# Split par virgule et afficher chaque version |
|
n = split(versions, vers, ",") |
|
for (i = 1; i <= n; i++) { |
|
version = vers[i] |
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", version) # trim |
|
if (version != "" && package != "") { |
|
print package ":" version |
|
} |
|
} |
|
} |
|
' "$DATADOG_LIST" > "$datadog_temp" |
|
|
|
# Ajouter au fichier principal |
|
cat "$datadog_temp" >> "$PARSED_VULNERABLE" |
|
|
|
echo -e "${GREEN} ✓ Liste Datadog analysée ($(wc -l < "$datadog_temp" | xargs) entrées)${NC}" |
|
fi |
|
|
|
# Supprimer les doublons |
|
sort -u "$PARSED_VULNERABLE" -o "$PARSED_VULNERABLE" |
|
|
|
# Créer une liste des paquets affectés (sans version) pour détecter les warnings |
|
AFFECTED_PACKAGES="$TEMP_DIR/affected_packages.txt" |
|
cut -d: -f1 "$PARSED_VULNERABLE" | sort -u > "$AFFECTED_PACKAGES" |
|
|
|
PARSE_END=$(date +%s) |
|
PARSE_TIME=$((PARSE_END - PARSE_START)) |
|
VULNERABLE_TOTAL=$(wc -l < "$PARSED_VULNERABLE" | xargs) |
|
|
|
echo -e "${GREEN} ✓ $VULNERABLE_TOTAL entrées vulnérables uniques${NC}" |
|
echo -e "${YELLOW} ⏱️ Analyse: ${PARSE_TIME}s${NC}" |
|
|
|
|
|
analyse_file() { |
|
local LOCK_FILE="$1" |
|
local FILE_HAS_VULNERABILITIES=0 |
|
|
|
echo "" |
|
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
echo -e "${YELLOW}📁 Analyse: $LOCK_FILE${NC}" |
|
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
|
|
# Détection du type de fichier lock |
|
LOCK_TYPE="" |
|
if [[ "$LOCK_FILE" == *"yarn.lock"* ]]; then |
|
LOCK_TYPE="yarn" |
|
elif [[ "$LOCK_FILE" == *"package-lock.json"* ]]; then |
|
LOCK_TYPE="npm" |
|
elif [[ "$LOCK_FILE" == *"pnpm-lock.yaml"* ]]; then |
|
LOCK_TYPE="pnpm" |
|
elif [[ "$LOCK_FILE" == *"bun.lock"* ]] || [[ "$LOCK_FILE" == *"bun.lockb"* ]]; then |
|
LOCK_TYPE="bun" |
|
else |
|
echo -e "${RED}⚠️ Type de fichier lock non reconnu (ignoré)${NC}" |
|
return 0 |
|
fi |
|
|
|
# OPTIMISATION: Pré-extraire toutes les versions installées dans un fichier temporaire |
|
echo "" |
|
echo -e "${YELLOW}📦 Extraction des paquets installés...${NC}" |
|
EXTRACT_START=$(date +%s) |
|
|
|
# Encoder le path pour éviter les problèmes de noms de fichiers (remplacer / par _) |
|
LOCK_FILE_ENCODED=$(echo "$LOCK_FILE" | tr '/' '_') |
|
INSTALLED_VERSIONS="$TEMP_DIR/installed_${LOCK_FILE_ENCODED}.txt" |
|
|
|
case "$LOCK_TYPE" in |
|
"yarn") |
|
awk ' |
|
/^[" ]*[^# ].*@/ { |
|
gsub(/^[" ]*/, "") |
|
gsub(/[":].*$/, "") |
|
package = $0 |
|
getline |
|
if ($1 == "version") { |
|
gsub(/[" ]/, "", $2) |
|
split(package, parts, "@") |
|
pkg_name = parts[1] |
|
for (i = 2; i < length(parts); i++) { |
|
pkg_name = pkg_name "@" parts[i] |
|
} |
|
print pkg_name ":" $2 |
|
} |
|
} |
|
' "$LOCK_FILE" > "$INSTALLED_VERSIONS" |
|
;; |
|
|
|
"npm") |
|
grep -E '"(node_modules/|dependencies)' -A 3 "$LOCK_FILE" | \ |
|
awk ' |
|
/"node_modules\// || /"[^"]+": \{$/ { |
|
if (/"node_modules\//) { |
|
gsub(/.*node_modules\//, "") |
|
gsub(/".*/, "") |
|
package = $0 |
|
} else { |
|
gsub(/[" :].*/, "") |
|
package = $1 |
|
} |
|
} |
|
/"version":/ { |
|
gsub(/[", ]/, "", $2) |
|
if (package != "") print package ":" $2 |
|
} |
|
' > "$INSTALLED_VERSIONS" |
|
;; |
|
|
|
"pnpm") |
|
# Extraire de pnpm-lock.yaml (supporte v6 et v9) |
|
awk ' |
|
# Format v9: package@version: (avec possibles quotes) |
|
/^ .*@[0-9]/ { |
|
line = $0 |
|
gsub(/^ /, "", line) |
|
gsub(/['"'"']/, "", line) # Enlever les quotes |
|
gsub(/:.*/, "", line) |
|
|
|
# Trouver le dernier @ qui sépare la version |
|
last_at = 0 |
|
for (i = length(line); i > 0; i--) { |
|
if (substr(line, i, 1) == "@") { |
|
last_at = i |
|
break |
|
} |
|
} |
|
|
|
if (last_at > 0) { |
|
package = substr(line, 1, last_at - 1) |
|
version = substr(line, last_at + 1) |
|
|
|
# Si version commence par un chiffre, c'"'"'est bon |
|
if (version ~ /^[0-9]/ && package != "") { |
|
print package ":" version |
|
} |
|
} |
|
} |
|
|
|
# Format ancien v6: package: suivi de version: |
|
/^ [^ ].*:$/ && !/^ .*@[0-9]/ { |
|
gsub(/:.*/, "") |
|
gsub(/^ /, "") |
|
gsub(/['"'"']/, "", $0) |
|
package = $0 |
|
} |
|
/^ version:/ { |
|
gsub(/.*version: /, "") |
|
gsub(/['"'"']/, "", $0) |
|
if (package != "" && $0 != "") { |
|
print package ":" $0 |
|
package = "" |
|
} |
|
} |
|
' "$LOCK_FILE" > "$INSTALLED_VERSIONS" |
|
;; |
|
|
|
"bun") |
|
if [[ "$LOCK_FILE" == *".lockb"* ]]; then |
|
echo -e "${RED}❌ bun.lockb est un format binaire non supporté directement${NC}" |
|
echo " Solutions: bun install (génère bun.lock) ou bun install --yarn" |
|
return 0 |
|
fi |
|
|
|
# bun.lock v1 est au format JSON |
|
# Format: "key": ["package@version", "path", {...}, "sha"] |
|
sed -n '/^ "packages": {/,/^ }/p' "$LOCK_FILE" | \ |
|
grep -E '\["[^"]+@[0-9]' | \ |
|
sed 's/.*\["//' | \ |
|
sed 's/".*//' | \ |
|
awk -F'@' ' |
|
{ |
|
# Trouver le dernier @ qui sépare la version |
|
version = $NF |
|
if (version ~ /^[0-9]/) { |
|
# Reconstruire le nom du paquet (tout sauf le dernier champ) |
|
package = $1 |
|
for (i = 2; i < NF; i++) { |
|
package = package "@" $i |
|
} |
|
if (package != "") { |
|
print package ":" version |
|
} |
|
} |
|
} |
|
' | sort -u > "$INSTALLED_VERSIONS" |
|
;; |
|
esac |
|
|
|
EXTRACT_END=$(date +%s) |
|
EXTRACT_TIME=$((EXTRACT_END - EXTRACT_START)) |
|
INSTALLED_COUNT=$(wc -l < "$INSTALLED_VERSIONS" | xargs) |
|
|
|
echo -e "${GREEN} ✓ $INSTALLED_COUNT paquets détectés${NC}" |
|
echo -e "${YELLOW} ⏱️ Extraction: ${EXTRACT_TIME}s${NC}" |
|
|
|
# Comparer avec les vulnérabilités |
|
echo "" |
|
echo -e "${YELLOW}🔍 Recherche de correspondances...${NC}" |
|
COMPARE_START=$(date +%s) |
|
|
|
VULNERABLE_COUNT=0 |
|
WARNING_COUNT=0 |
|
declare -a FOUND_VULNERABILITIES |
|
declare -a FOUND_WARNINGS |
|
|
|
# Vérifier les vulnérabilités exactes |
|
while IFS=':' read -r package version; do |
|
if grep -Fx "$package:$version" "$INSTALLED_VERSIONS" > /dev/null; then |
|
echo -e " ${RED}⚠️ VULNÉRABILITÉ: $package@$version${NC}" |
|
FOUND_VULNERABILITIES+=("$package@$version") |
|
((VULNERABLE_COUNT++)) |
|
FILE_HAS_VULNERABILITIES=1 |
|
GLOBAL_VULNERABILITIES_FOUND=1 |
|
fi |
|
done < "$PARSED_VULNERABLE" |
|
|
|
COMPARE_END=$(date +%s) |
|
COMPARE_TIME=$((COMPARE_END - COMPARE_START)) |
|
echo -e "${YELLOW} ⏱️ Comparaison: ${COMPARE_TIME}s${NC}" |
|
|
|
# Vérifier les warnings (paquets affectés, versions différentes) |
|
echo "" |
|
echo -e "${YELLOW}⚠️ Vérification des paquets affectés (autres versions)...${NC}" |
|
WARNING_START=$(date +%s) |
|
|
|
while IFS=':' read -r package version; do |
|
if grep -Fx "$package" "$AFFECTED_PACKAGES" > /dev/null; then |
|
if ! grep -Fx "$package:$version" "$PARSED_VULNERABLE" > /dev/null; then |
|
echo -e " ${ORANGE}ℹ️ ATTENTION: $package@$version (version différente)${NC}" |
|
FOUND_WARNINGS+=("$package@$version") |
|
((WARNING_COUNT++)) |
|
fi |
|
fi |
|
done < "$INSTALLED_VERSIONS" |
|
|
|
WARNING_END=$(date +%s) |
|
WARNING_TIME=$((WARNING_END - WARNING_START)) |
|
echo -e "${YELLOW} ⏱️ Warnings: ${WARNING_TIME}s${NC}" |
|
|
|
echo "" |
|
|
|
# Afficher le résumé pour ce fichier |
|
if [ $VULNERABLE_COUNT -eq 0 ]; then |
|
echo -e "${GREEN}✅ Aucune vulnérabilité détectée dans ce fichier${NC}" |
|
|
|
if [ $WARNING_COUNT -gt 0 ]; then |
|
echo -e "${ORANGE}⚠️ $WARNING_COUNT paquet(s) avec versions affectées connues${NC}" |
|
fi |
|
else |
|
echo -e "${RED}❌ $VULNERABLE_COUNT vulnérabilité(s) détectée(s)${NC}" |
|
|
|
for vuln in "${FOUND_VULNERABILITIES[@]}"; do |
|
echo -e " ${RED}• $vuln${NC}" |
|
done |
|
|
|
if [ $WARNING_COUNT -gt 0 ]; then |
|
echo "" |
|
echo -e "${ORANGE}⚠️ $WARNING_COUNT autre(s) paquet(s) affecté(s)${NC}" |
|
fi |
|
fi |
|
|
|
return $FILE_HAS_VULNERABILITIES |
|
} |
|
|
|
# Si un répertoire est fourni, analyser tous les fichiers lock à l'intérieur |
|
if [ -d "$LOCK_FILE_OR_DIR" ]; then |
|
echo "" |
|
echo -e "${YELLOW}📂 Scan du répertoire: $LOCK_FILE_OR_DIR${NC}" |
|
|
|
FILES_FOUND=0 |
|
for file in $(find "$LOCK_FILE_OR_DIR" -type f \( -name "yarn.lock" -o -name "package-lock.json" -o -name "pnpm-lock.yaml" -o -name "bun.lock" -o -name "bun.lockb" \) -not -path "*/node_modules/*"); do |
|
((FILES_FOUND++)) |
|
analyse_file "$file" |
|
done |
|
|
|
if [ $FILES_FOUND -eq 0 ]; then |
|
echo -e "${YELLOW}⚠️ Aucun fichier lock trouvé dans le répertoire${NC}" |
|
exit 0 |
|
fi |
|
else |
|
analyse_file "$LOCK_FILE_OR_DIR" |
|
fi |
|
|
|
# Résumé final |
|
END_TIME=$(date +%s) |
|
TOTAL_TIME=$((END_TIME - START_TIME)) |
|
|
|
echo "" |
|
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
echo -e "${YELLOW}📊 RÉSUMÉ GLOBAL${NC}" |
|
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
echo "" |
|
|
|
if [ $GLOBAL_VULNERABILITIES_FOUND -eq 1 ]; then |
|
echo -e "${RED}🚨 DES VULNÉRABILITÉS ONT ÉTÉ DÉTECTÉES${NC}" |
|
echo "" |
|
|
|
# Collecter toutes les vulnérabilités trouvées (optimisé) |
|
ALL_VULNS="$TEMP_DIR/all_vulnerabilities.txt" |
|
> "$ALL_VULNS" |
|
|
|
# Pour chaque fichier d'installation, croiser avec les vulnérabilités |
|
for installed_file in "$TEMP_DIR"/installed_*.txt; do |
|
if [ -f "$installed_file" ]; then |
|
# Extraire et décoder le path original |
|
# Format: installed_<encoded_path>.txt |
|
original_path=$(basename "$installed_file" .txt | sed 's/^installed_//' | tr '_' '/') |
|
|
|
# Utiliser grep -Fxf pour comparer les deux fichiers en une seule fois (BEAUCOUP plus rapide) |
|
grep -Fxf "$PARSED_VULNERABLE" "$installed_file" 2>/dev/null | while IFS=':' read -r package version; do |
|
echo "$package@$version|$original_path" |
|
done >> "$ALL_VULNS" |
|
fi |
|
done |
|
|
|
if [ -f "$ALL_VULNS" ] && [ -s "$ALL_VULNS" ]; then |
|
# Grouper par paquet et afficher |
|
echo -e "${RED}📋 Récapitulatif des paquets compromis:${NC}" |
|
echo "" |
|
|
|
# Trier et grouper par paquet |
|
sort "$ALL_VULNS" | awk -F'|' ' |
|
{ |
|
vuln = $1 |
|
file = $2 |
|
if (vuln != last_vuln) { |
|
if (last_vuln != "") { |
|
# Afficher le paquet précédent |
|
printf " \033[0;31m• %s\033[0m\n", last_vuln |
|
printf " \033[1;33m→ %s\033[0m\n\n", files |
|
} |
|
last_vuln = vuln |
|
files = file |
|
} else { |
|
# Même paquet, ajouter le fichier |
|
files = files ", " file |
|
} |
|
} |
|
END { |
|
# Afficher le dernier |
|
if (last_vuln != "") { |
|
printf " \033[0;31m• %s\033[0m\n", last_vuln |
|
printf " \033[1;33m→ %s\033[0m\n", files |
|
} |
|
} |
|
' |
|
fi |
|
|
|
echo "" |
|
echo -e "${RED}Actions urgentes:${NC}" |
|
echo " 1. NE PAS mettre à jour vos dépendances" |
|
echo " 2. Isolez l'environnement concerné" |
|
echo " 3. Vérifiez vos logs pour toute activité suspecte" |
|
echo " 4. Tournez vos secrets (npm, GitHub, cloud, etc.)" |
|
echo " 5. Contactez votre équipe de sécurité" |
|
else |
|
echo -e "${GREEN}✅ Aucune vulnérabilité détectée${NC}" |
|
echo "" |
|
echo -e "${YELLOW}Recommandations:${NC}" |
|
echo " • NE PAS mettre à jour vos dépendances pour le moment" |
|
echo " • Surveillez les mises à jour des listes officielles" |
|
fi |
|
|
|
echo "" |
|
echo -e "${YELLOW}📚 Ressources:${NC}" |
|
echo " • Tenable: https://github.com/tenable/shai-hulud-second-coming-affected-packages" |
|
echo " • Datadog: https://github.com/DataDog/indicators-of-compromise" |
|
echo " • Blog: https://www.tenable.com/blog/faq-about-sha1-hulud-2-0" |
|
echo "" |
|
echo -e "⏱️ Temps total: ${TOTAL_TIME}s" |
|
echo "" |
|
|
|
# Code de sortie: 1 si des vulnérabilités ont été trouvées, 0 sinon |
|
exit $GLOBAL_VULNERABILITIES_FOUND |
Updated to fix warnings : some unaffected paquets were listed as affected