PopElite/esc

GitHub: PopElite/esc

ESC 是一个生产就绪的 SaaS 安全运营平台,通过规则引擎与多 LLM 协同分析实现日志异常检测、沙盒攻击模拟和人工审批缓解的完整闭环。

Stars: 0 | Forks: 0

# ESC — 精英安全 Copilot ## 架构概述 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ INGESTION LAYER │ │ Nginx webhooks / CSV upload / Syslog / Cloud audit APIs │ └──────────────────────────────┬──────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ EVENT PIPELINE (Redis Bull) │ │ Dedup → Normalize → Fingerprint → Queue → Priority routing │ └──────────────────────────────┬──────────────────────────────────────┘ │ ┌──────────┴──────────┐ ▼ ▼ ┌─────────────────┐ ┌─────────────────────┐ │ DETECTION │ │ LLM ANALYSIS │ │ ENGINE │ │ ORCHESTRATOR │ │ │ │ │ │ ► Rule-based │ │ 1. Claude Sonnet │ │ ► Statistical │ │ 2. GPT-4o Mini │ │ ► Signature │ │ 3. Ollama (local) │ │ ► Heuristic │ │ │ │ │ │ Auto-failover │ │ 6 built-in │ │ Strict JSON output │ │ rule classes │ │ Confidence score │ └────────┬────────┘ └──────────┬──────────┘ │ │ └──────────┬─────────────┘ ▼ ┌─────────────────────────┐ │ ALERT ENGINE │ │ Risk scoring · SLA │ │ Webhook · Email notify │ │ RBAC-scoped visibility │ └────────────┬────────────┘ │ ┌────────────┴────────────┐ ▼ ▼ ┌───────────────────┐ ┌────────────────────────┐ │ MITIGATION │ │ SANDBOX ENGINE │ │ PLANNER (LLM) │ │ │ │ │ │ ⚠ SYNTHETIC ONLY │ │ Immediate steps │ │ No real network I/O │ │ Short-term plan │ │ Memory-isolated sim │ │ Long-term fixes │ │ 8 attack vectors │ │ │ │ Detection rate report │ │ requiresApproval │ │ │ │ = true ALWAYS │ │ │ └───────────────────┘ └────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────┐ │ POSTGRESQL (Prisma ORM) │ │ Organizations · Users · LogEvents │ │ Detections · Alerts · AuditLogs │ │ DetectionRules · SandboxSimulations │ └────────────────────────────────────────────────┘ ``` ## 模块映射 ``` esc/ ├── backend/ │ ├── src/ │ │ ├── index.ts # API entry: Express + middleware, connects DB │ │ ├── worker.ts # Bull worker process: full 7-step pipeline │ │ ├── routes.ts # All API routes (real Prisma reads/writes) │ │ ├── modules/ │ │ │ ├── auth/ │ │ │ │ └── auth.service.ts # JWT, RBAC, password hashing │ │ │ ├── detection/ │ │ │ │ ├── detection.engine.ts # 6 rule classes, in-memory context │ │ │ │ └── llm.orchestrator.ts # Claude→GPT→Ollama failover chain │ │ │ ├── sandbox/ │ │ │ │ └── sandbox.engine.ts # Synthetic attack simulation (safe) │ │ │ ├── queue/ │ │ │ │ └── log-ingest.queue.ts # Bull queue producer (Redis-backed) │ │ │ └── db/ │ │ │ └── prisma.client.ts # PrismaClient singleton, connect w/ retry │ │ ├── core/ │ │ │ └── middleware/ │ │ │ └── security.middleware.ts # Helmet, rate limit, CORS, audit │ │ └── shared/ │ │ ├── types/index.ts # Shared TypeScript interfaces │ │ └── utils/ │ │ ├── logger.ts # Winston structured logging │ │ └── crypto.ts # AES-256-GCM, HMAC, fingerprint │ ├── prisma/ │ │ ├── schema.prisma # Full DB schema (8 models, RBAC) │ │ └── seed.ts # Seeds demo org/user/log source │ ├── scripts/ │ │ └── test-ingestion.js # End-to-end pipeline smoke test │ ├── Dockerfile # Multi-stage, non-root user, runs prisma generate │ └── .env.example ├── frontend/ │ └── src/ # React dashboard (see below) ├── docker-compose.yml # Full stack: PG + Redis + API + FE + Nginx └── scripts/db/init.sql # DB init + extensions ``` ## 安全设计原则 ### 身份验证 - JWT (HS256) 有效期 15 分钟 + refresh token (7d) - 用于 token 吊销的 JWT ID (`jti`) 字段 - bcrypt cost factor 14(刻意放慢) - 常数时间密码比较(防止 timing attacks) - 登录失败时逐步增加延迟(防暴力破解) - 指数退避的账户锁定机制 ### RBAC(4 种角色) | 角色 | 可执行操作 | |------|--------| | `SUPER_ADMIN` | 所有操作 | | `SECURITY_ADMIN` | 所有安全操作,读取用户信息 | | `ANALYST` | 读取警报,提出缓解措施,审查检测 | | `READ_ONLY` | 对警报/检测/日志的只读访问权限 | | `SERVICE_ACCOUNT` | 仅用于日志接入(API keys) | ### 数据保护 - 对静态敏感数据(MFA 密钥、webhook URLs)使用 AES-256-GCM 加密 - 使用 SHA-256 指纹进行日志去重 - HMAC-SHA256 webhook 签名验证 - 日志中隐藏所有敏感字段 (`[REDACTED]`) - 生产环境下的 PostgreSQL `sslmode=require` ### 纵深防御(API) - `helmet` 和严格的 CSP - `cors` 白名单(非通配符) - 分级速率限制(全局 100/15分钟,身份验证 10/15分钟,接入 10k/分钟) - `express-validator` 通过 Zod 进行输入验证 - 拦截 Null byte injection - 请求大小限制 (10MB) - 非 root Docker 用户 + `cap_drop: ALL` + `no-new-privileges` - 内部 Docker 网络(DB/Redis 绝不公开暴露) ### 沙盒安全 沙盒引擎是纯模拟的: - 不执行 `child_process` - 没有连接到外部主机的 `net.Socket` 或 `http.request` - 没有文件系统写入操作 - 所有“攻击”事件均在内存中生成 - 需要作为显式开关的 `SANDBOX_MODE=true` 环境变量 - 每个结果都包含 `sandboxConfirmation` token ### 缓解措施安全 - 所有 `MitigationAction` 对象上硬编码了 `automated: false` - 在 LLM prompt 和响应 schema 中强制执行 `requiresApproval: true` - LLM 收到的指令是:“绝不建议自动化的破坏性操作” - 所有计划在执行任何步骤之前都需要人工审查 ## API Endpoints ``` GET /api/v1/health # Public health check GET /api/v1/health/detailed # Auth required: SECURITY_ADMIN POST /api/v1/auth/login # Login → JWT POST /api/v1/auth/logout # Revoke session POST /api/v1/logs/ingest # Bulk log ingestion (API key or JWT) GET /api/v1/alerts # List alerts (org-scoped) POST /api/v1/alerts/:id/acknowledge # Acknowledge alert POST /api/v1/analysis/event # LLM analyze a log event POST /api/v1/analysis/mitigation # Generate mitigation plan POST /api/v1/sandbox/simulate # Run sandbox simulation GET /api/v1/dashboard/stats # Dashboard KPIs GET /api/v1/audit # Audit log (SECURITY_ADMIN) ``` ## 检测规则 | ID | 名称 | 方法 | 风险 | |----|------|--------|------| | BF-001 | 暴力破解登录 | 阈值/时间窗口 | HIGH | | INJ-001 | SQL Injection | Regex 特征码 | CRITICAL | | PT-001 | Path Traversal | Regex 特征码 | HIGH | | RA-001 | 速率滥用 / DDoS | 统计 | HIGH | | PE-001 | Privilege Escalation | 基于规则 | CRITICAL | | GEO-001 | 不可能旅行 | 统计 | HIGH | ## 快速开始(完整工作流水线) ``` # 1. 配置 secrets cp backend/.env.example backend/.env # 编辑 backend/.env — 至少设置 JWT_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEY # (ANTHROPIC_API_KEY / OPENAI_API_KEY 可选 — pipeline 没有它们也能运行, # LLM 分析步骤将被跳过/使用 fallback) # 2. 一次性启动 + 冒烟测试 ./run.sh # ── 或手动 ── docker-compose up -d postgres redis docker-compose up migrate # runs prisma migrate deploy + db seed docker-compose up -d worker backend frontend nginx # 3. 运行 end-to-end pipeline 测试 docker-compose exec backend node scripts/test-ingestion.js ``` 测试脚本以初始化的 demo 管理员身份登录,将一批日志事件 (来自同一个 IP 的 15 次暴力破解登录失败,一个 SQL injection payload,一个 path traversal payload,以及一个正常事件)POST 到 `/api/v1/logs/ingest`,然后轮询 `/api/v1/alerts`,直到 worker 在 PostgreSQL 中生成真实的警报行, 并将它们打印出来。 观察流水线实时执行: ``` docker-compose logs -f worker ``` 你将看到如下输出: ``` [PIPELINE] ───────────────────────────────────────────── [PIPELINE] job=3 requestId=a1b2c3d4 [PIPELINE] STEP 1/7 -> normalizing event [PIPELINE] STEP 2/7 -> persisting LogEvent (fingerprint=9f8e7d6c5b4a...) [PIPELINE] STEP 3/7 -> running detection engine [PIPELINE] STEP 4/7 -> detection fired: category=BRUTE_FORCE risk=HIGH confidence=0.85 method=RULE_BASED [PIPELINE] STEP 5/7 -> calling LLM orchestrator (Claude -> GPT -> Ollama) [PIPELINE] STEP 5/7 -> LLM analysis complete: provider=claude riskLevel=HIGH confidence=0.91 [PIPELINE] STEP 6/7 -> persisting Detection + Alert rows [PIPELINE] STEP 7/7 -> alert persisted: id=7f3a... status=OPEN [PIPELINE] DONE (alert created) in 842ms [PIPELINE] ───────────────────────────────────────────── ``` ### 手动 API 演练 ``` # 登录(内置的 demo 管理员) TOKEN=$(curl -s -X POST http://localhost:3001/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@esc.local","password":"Demo@SecurePass123!"}' \ | jq -r .data.accessToken) # Ingest 一个恶意 event curl -s -X POST http://localhost:3001/api/v1/logs/ingest \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{ "sourceId": "00000000-0000-0000-0000-000000000002", "analyzeWithLLM": true, "events": [{ "timestamp": "'"$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"'", "rawPayload": {"msg": "test"}, "ipAddress": "203.0.113.99", "endpoint": "/api/users?id=1%27%20OR%20%271%27=%271", "method": "GET", "statusCode": 400, "userAgent": "sqlmap/1.7" }] }' # -> 202 Accepted,返回 jobIds。Worker 会异步处理它。 # 轮询 alerts(来自 PostgreSQL 的真实数据行) curl -s http://localhost:3001/api/v1/alerts -H "Authorization: Bearer $TOKEN" | jq ``` ### 实际连接的内容(无伪代码,无 mocks) | 组件 | 实际情况 | |---|---| | `POST /logs/ingest` | 验证输入,其自身不进行任何持久化——将每个事件作为一个 Bull job 推送到 `esc-log-ingest` 队列(基于 Redis) | | `worker.ts` | 独立的 Node 进程,`queue.process()` 消费者,在每个 job 上同步运行**完整的 7 步流水线** | | `detection.engine.ts` | 真正的内存中有状态规则引擎(IP/用户/端点历史映射),针对每个事件运行 | | `llm.orchestrator.ts` | 真实的 HTTP 调用,通过 try/catch 故障转移链连接到 Anthropic/OpenAI/Ollama;如果 3 个全部失败或未设置密钥,则优雅地降级为安全的 fallback 对象 | | `prisma.client.ts` | 真正的 `PrismaClient` 单例,在后端和 worker 启动时通过重试/退避机制进行连接 | | `LogEvent` / `Detection` / `Alert` / `AuditLog` 行 | 确实由 worker 按顺序写入 PostgreSQL,每个事件对应 | | `GET /alerts` | 真正的 `prisma.alert.findMany()`,范围限制为调用者的 `organizationId`,并带有 `include: { detection: ... }` | | `prisma/seed.ts` | 创建一个真实的 Organization,一个 SECURITY_ADMIN User(使用 bcrypt 哈希处理的密码),以及一个默认的 LogSource,以便 demo 可以立即使用 | ## 生产环境检查清单 - [ ] 更换 `.env` 中的所有密钥(JWT_SECRET、ENCRYPTION_KEY 等) - [ ] 启用 PostgreSQL SSL (`sslmode=require`) - [ ] 将 `CORS_ORIGINS` 设置为您的实际域名 - [ ] 配置用于警报通知的 SMTP - [ ] 在 Nginx (`./nginx/ssl/`) 中设置 TLS - [ ] 启用日志保留策略(默认:365 天) - [ ] 配置 Redis 持久化和密码 - [ ] 根据您的流量基准审查和调整检测阈值 - [ ] 设置外部监控(正常运行时间、错误率警报) - [ ] 为所有 `SECURITY_ADMIN` 和 `SUPER_ADMIN` 账户启用 MFA *ESC 是一个分析和警报平台。它从不自动执行缓解措施。所有建议的操作都需要明确的人工批准。*
标签:SaaS, 威胁分析, 搜索引擎查询, 攻击仿真, 日志异常检测, 测试用例, 自动化侦查工具, 自动化攻击, 请求拦截