## Root Cause Analysis - Found CRITICAL RCE vulnerability in Next.js 15.0.3 (GHSA-9qr9-h5gf-34mp) - 10 vulnerabilities total including SSRF, DoS, Auth Bypass - Attack vector: exposed port 3000 + vulnerable Next.js → remote code execution ## Security Fixes - Upgraded Next.js: 15.0.3 → 15.5.9 (0 vulnerabilities) - Upgraded eslint-config-next: 15.0.3 → 15.5.9 ## Hardening (New Files) - apps/web/Dockerfile.secure: Multi-stage build, read-only FS, no shell - docker-compose.web.secure.yml: Resource limits, cap_drop ALL, localhost bind - scripts/rebuild-daarion-web-secure.sh: Local secure rebuild with Trivy scan - scripts/deploy-daarion-web-node1.sh: Production deployment to NODE1 - SECURITY-REBUILD-REPORT.md: Full incident analysis and remediation report ## Key Security Measures - restart: "no" (until verified) - ports: 127.0.0.1:3000 (localhost only, use Nginx reverse proxy) - read_only: true - cap_drop: ALL - resources.limits: 1 CPU, 512M RAM - no-new-privileges: true ## Related Incidents - Incident #1 (Jan 8): catcal, G4NQXBp miners - Incident #2 (Jan 9): softirq, vrarhpb miners - Hetzner AbuseID: 10F3971:2A Co-authored-by: Cursor Agent <agent@cursor.sh>
205 lines
6.7 KiB
Markdown
205 lines
6.7 KiB
Markdown
# 🔒 SECURITY REBUILD REPORT: daarion-web
|
||
|
||
**Дата:** 2026-01-09
|
||
**Версія:** 1.0.0
|
||
**Статус:** ✅ Готово до deployment
|
||
**Автор:** Cursor Agent (Security Analysis)
|
||
|
||
---
|
||
|
||
## 📋 Executive Summary
|
||
|
||
Проведено повний аналіз безпеки та hardening контейнера `daarion-web` після двох інцидентів криптомайнінгу.
|
||
|
||
### Ключові знахідки
|
||
|
||
| Аспект | Статус | Деталі |
|
||
|--------|--------|--------|
|
||
| Source Code | ✅ ЧИСТИЙ | Немає malicious коду |
|
||
| Dependencies | 🔴→✅ ВИПРАВЛЕНО | Next.js 15.0.3 → 15.5.9 |
|
||
| npm audit | ✅ ПРОЙДЕНО | 0 вразливостей |
|
||
| Dockerfile | ✅ HARDENED | Створено Dockerfile.secure |
|
||
| docker-compose | ✅ HARDENED | Створено docker-compose.web.secure.yml |
|
||
|
||
---
|
||
|
||
## 🔍 Розслідування (Root Cause Analysis)
|
||
|
||
### Виявлена критична вразливість
|
||
|
||
**Next.js 15.0.3 мала 10 вразливостей:**
|
||
|
||
| CVE/GHSA | Severity | Тип | Експлуатація |
|
||
|----------|----------|-----|--------------|
|
||
| GHSA-9qr9-h5gf-34mp | 🔴 CRITICAL | **RCE** | Remote Code Execution через React Flight Protocol |
|
||
| GHSA-4342-x723-ch2f | 🔴 HIGH | **SSRF** | Server-Side Request Forgery через Middleware |
|
||
| GHSA-7m27-7ghc-44w9 | 🔴 HIGH | **DoS** | Denial of Service через Server Actions |
|
||
| GHSA-f82v-jwr5-mffw | 🟡 HIGH | Auth Bypass | Authorization Bypass в Middleware |
|
||
| GHSA-qpjv-v59x-3qc4 | 🟡 HIGH | Cache Poison | Race Condition для Cache Poisoning |
|
||
| + 5 інших | 🟡 MEDIUM | Various | Information Exposure, Content Injection |
|
||
|
||
### Вектор атаки (найбільш вірогідний)
|
||
|
||
```
|
||
1. Атакуючий сканував exposed порт 3000
|
||
2. Виявив вразливу версію Next.js (15.0.3)
|
||
3. Експлуатував RCE (GHSA-9qr9-h5gf-34mp) через React Flight Protocol
|
||
4. Завантажив та запустив криптомайнер
|
||
5. Malware персистився в running container
|
||
6. При перезапуску → re-exploitation → нові майнери
|
||
```
|
||
|
||
### Чому різні майнери в різних інцидентах
|
||
|
||
| Інцидент | Майнери | Пояснення |
|
||
|----------|---------|-----------|
|
||
| #1 (8 січня) | `catcal`, `G4NQXBp` | Перша експлуатація |
|
||
| #2 (9 січня) | `softirq`, `vrarhpb` | Автоматичний re-exploit з новим payload |
|
||
|
||
**Висновок:** Атакуючий використовував автоматизований інструмент, який завантажував актуальну версію malware при кожній експлуатації.
|
||
|
||
---
|
||
|
||
## 🛡️ Hardening Заходи
|
||
|
||
### 1. Оновлення Dependencies
|
||
|
||
```bash
|
||
# До
|
||
"next": "15.0.3" # 10 CRITICAL/HIGH вразливостей
|
||
|
||
# Після
|
||
"next": "^15.5.9" # 0 вразливостей
|
||
```
|
||
|
||
### 2. Dockerfile.secure
|
||
|
||
Створено `/apps/web/Dockerfile.secure` з:
|
||
|
||
- ✅ Multi-stage build (ізоляція build-time від runtime)
|
||
- ✅ `npm ci --only=production --ignore-scripts` (блокування postinstall attacks)
|
||
- ✅ Non-root user (nextjs:1001)
|
||
- ✅ Видалення curl/wget/shell (обмеження інструментів атаки)
|
||
- ✅ Restrictive permissions (chmod 500/400)
|
||
- ✅ Health check
|
||
|
||
### 3. docker-compose.web.secure.yml
|
||
|
||
Створено з security hardening:
|
||
|
||
```yaml
|
||
# Ключові налаштування
|
||
restart: "no" # До перевірки!
|
||
ports:
|
||
- "127.0.0.1:3000:3000" # Тільки localhost
|
||
read_only: true # Read-only filesystem
|
||
cap_drop: [ALL] # Drop all capabilities
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
resources:
|
||
limits:
|
||
cpus: '1.0'
|
||
memory: 512M
|
||
user: "1001:1001"
|
||
```
|
||
|
||
### 4. Security Scan Script
|
||
|
||
Створено `/scripts/rebuild-daarion-web-secure.sh`:
|
||
|
||
1. Pre-flight checks
|
||
2. Cleanup old images
|
||
3. npm audit
|
||
4. Build with no-cache
|
||
5. Trivy scan
|
||
6. Test container
|
||
7. Monitoring instructions
|
||
|
||
---
|
||
|
||
## 🧪 Результати Тестування
|
||
|
||
### npm audit
|
||
|
||
```
|
||
✅ found 0 vulnerabilities
|
||
```
|
||
|
||
### Trivy scan (pending Docker start)
|
||
|
||
```bash
|
||
# Команда для запуску
|
||
trivy image --severity HIGH,CRITICAL daarion-web:secure-test
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 Deployment Checklist
|
||
|
||
### Локальне тестування (NODE2/MacBook)
|
||
|
||
- [ ] Запустити Docker Desktop
|
||
- [ ] Виконати `./scripts/rebuild-daarion-web-secure.sh`
|
||
- [ ] Дочекатися Trivy scan
|
||
- [ ] Моніторити контейнер 15+ хвилин
|
||
- [ ] Перевірити CPU usage (<10%)
|
||
- [ ] Перевірити процеси (тільки node)
|
||
|
||
### Production deployment (NODE1/Hetzner)
|
||
|
||
- [ ] Зробити backup поточного стану
|
||
- [ ] Скопіювати нові файли на NODE1:
|
||
- `apps/web/Dockerfile.secure`
|
||
- `apps/web/package.json` (оновлений)
|
||
- `apps/web/package-lock.json`
|
||
- `docker-compose.web.secure.yml`
|
||
- `scripts/rebuild-daarion-web-secure.sh`
|
||
- [ ] Побудувати образ на NODE1
|
||
- [ ] Запустити Trivy scan
|
||
- [ ] Запустити контейнер
|
||
- [ ] Моніторити 30+ хвилин
|
||
- [ ] Після успішної перевірки: `restart: "unless-stopped"`
|
||
|
||
---
|
||
|
||
## 📁 Створені файли
|
||
|
||
| Файл | Призначення |
|
||
|------|-------------|
|
||
| `apps/web/Dockerfile.secure` | Hardened Dockerfile |
|
||
| `docker-compose.web.secure.yml` | Secure docker-compose |
|
||
| `scripts/rebuild-daarion-web-secure.sh` | Deployment script |
|
||
| `SECURITY-REBUILD-REPORT.md` | Цей звіт |
|
||
|
||
---
|
||
|
||
## ⚠️ Важливі попередження
|
||
|
||
### НЕ РОБІТЬ:
|
||
|
||
1. ❌ Не запускайте старий образ `daarion-web:latest`
|
||
2. ❌ Не використовуйте `restart: unless-stopped` без перевірки
|
||
3. ❌ Не виставляйте порт 3000 на public IP
|
||
4. ❌ Не пропускайте security scanning
|
||
|
||
### ОБОВ'ЯЗКОВО:
|
||
|
||
1. ✅ Використовуйте тільки `Dockerfile.secure`
|
||
2. ✅ Запускайте Trivy scan перед кожним deployment
|
||
3. ✅ Bind порт до `127.0.0.1` (доступ через Nginx)
|
||
4. ✅ Моніторте CPU/memory після запуску
|
||
5. ✅ Тримайте Next.js оновленим
|
||
|
||
---
|
||
|
||
## 📞 Контакти
|
||
|
||
**При виникненні проблем:**
|
||
- Hetzner Abuse: https://statement-abuse.hetzner.com
|
||
- Security Team: admin@daarion.city
|
||
|
||
---
|
||
|
||
**Останнє оновлення:** 2026-01-09 10:30 UTC
|
||
**Наступна ревізія:** Після production deployment
|