Stop Node.js CPU attacks on Cockpit & Podman. Check Ubuntu, Rocky, SUSE with 1 command. Automation script + Docker lab + iptables fallback.
One quick historical note: In April 2026, SUSE released an important update for cockpit-podman (tracked as SUSE-SU-2026:1251-1) to fix two specific flaws: CVE-2026-25547 (unbounded brace expansion crash) and CVE-2026-26996 (minimatch ReDoS).
But here is the real lesson: these are not SUSE-only problems. They are classic “regular expression denial of service” (ReDoS) and “algorithmic complexity” bugs that can hit any Linux server running Cockpit, Podman, or any Node.js-based web UI.
Below you will learn how to check your own servers (Ubuntu, Rocky, SUSE), automate the fix, mitigate without updates, and build a lab to see the attack yourself.
1. How to check if you are vulnerable (actual commands)
- Cockpit (the web-based server manager, port 9090)
- Podman managed via Cockpit
- A Node.js backend doing brace expansion or glob pattern matching
# Check installed cockpit-podman version dpkg -l | grep cockpit-podman # Vulnerable: version < 33-1ubuntu1 (for 22.04) or < 33-1ubuntu2 (24.04) # Check Node.js packages that contain the flawed libraries find /usr/share/cockpit/ -name "*.js" -exec grep -l "brace-expansion\|minimatch" {} \;
# Check RPM version rpm -q cockpit-podman # Vulnerable: cockpit-podman < 33-2.el8 or < 33-2.el9 # Also check global Node modules if you have standalone Node apps npm list -g brace-expansion minimatch 2>/dev/null
# Already patched versions shown in April 2026 advisory zypper info cockpit-podman | grep Version # Safe version: 33-150300.6.9.1 or higher # Manual check for the vulnerable pattern in JS files grep -r "minimatch" /usr/share/cockpit-podman/
- If you expose Cockpit to the internet (port 9090) → critical risk
- If Cockpit is only on LAN/VPN → medium risk
- If you don’t use Cockpit at all → no risk
2. Automation script to apply the fix (bash, works on all major distros)
#!/bin/bash # Fix for CVE-2026-25547 & CVE-2026-26996 # Works on Ubuntu, Rocky, SUSE, and derivatives set -e detect_os() { if [ -f /etc/os-release ]; then . /etc/os-release OS=$ID VER=$VERSION_ID else echo "Cannot detect OS" exit 1 fi } update_system() { case $OS in ubuntu|debian) apt update apt upgrade -y cockpit cockpit-podman # Also update Node.js packages if installed globally if command -v npm &> /dev/null; then npm update -g brace-expansion minimatch fi ;; rocky|almalinux|rhel) dnf update -y cockpit cockpit-podman if command -v npm &> /dev/null; then npm update -g brace-expansion minimatch fi ;; suse|opensuse-leap|opensuse-tumbleweed) zypper --non-interactive update cockpit cockpit-podman if command -v npm &> /dev/null; then npm update -g brace-expansion minimatch fi ;; *) echo "Unsupported OS: $OS" exit 1 ;; esac } restart_cockpit() { systemctl restart cockpit systemctl status cockpit --no-pager } detect_os echo "Updating $OS $VER" update_system restart_cockpit echo "Fix applied. Check with: cockpit-bridge --version"
chmod +x fix-cockpit-nodejs.sh sudo ./fix-cockpit-nodejs.sh
3. Alternative mitigation if you can’t update now
# Only allow Cockpit from your management LAN (example: 192.168.1.0/24) iptables -A INPUT -p tcp --dport 9090 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 9090 -j DROP # Add connection limit to prevent resource exhaustion iptables -A INPUT -p tcp --dport 9090 -m connlimit --connlimit-above 10 -j REJECT
Mitigation 2: AppArmor profile to restrict Node.js CPU/memory
/usr/sbin/cockpit-bridge {
# ... (keep defaults) ...
set rlimit cpu <= 30,
set rlimit as <= 512M,
}
location /cockpit/ { proxy_pass https://127.0.0.1:9090; proxy_read_timeout 10s; # kill slow ReDoS attempts proxy_connect_timeout 5s; }
4. Hands-on Lab: Reproduce & test the fix in 15 minutes
# 1. Create a vulnerable Node.js environment cat > Dockerfile.vuln <<EOF FROM node:16-alpine RUN npm install -g brace-expansion@1.1.11 minimatch@3.0.4 COPY exploit.js /exploit.js CMD node /exploit.js EOF # 2. Write the exploit cat > exploit.js <<EOF const expand = require('brace-expansion'); // CVE-2026-25547 trigger: thousands of nested braces const malicious = '{' + '{'.repeat(100000) + '}'.repeat(100000) + '}'; console.log("Starting attack..."); expand(malicious); // Will consume 100% CPU and crash EOF # 3. Build and run docker build -f Dockerfile.vuln -t vulnerable-node . docker run --memory="256m" --cpus="0.5" vulnerable-node # You will see CPU spike and container killed
# Use patched versions npm install -g brace-expansion@1.1.12 minimatch@5.1.0 # Re-run the script – now it should reject the pattern or handle safely

Nenhum comentário:
Postar um comentário