Engagement Manager 是一个用于跟踪攻击性安全项目的 Web 应用程序。它采用现代 UI,基于 Next.js、Prisma 和 PostgreSQL 构建。该应用包含日历、项目、客户、联系人、发现和操作员。

| 扫描器/导出系列 | 接受的导出 |
|---|---|
| Burp Suite | Issues XML,包括惰性内部模式 DTD |
| Nessus / Tenable | Nessus v2 XML(.nessus) |
| Nmap | XML;开放端口及其脚本输出成为信息性观察结果,而非推断的漏洞 |
| OpenVAS / Greenbone | 原生 XML 报告或 GMP get_reports_response |
| OWASP ZAP | 包含站点和警报的传统 JSON 报告 |
| Nuclei | JSON Lines(-jsonl) |
| Qualys | 扫描结果 XML(SCAN/IP 结构),而非单独的主机检测 API 格式 |
| Semgrep / CodeQL 及其他 SARIF 生成器 | SARIF JSON 运行、规则和结果 |
每次导入的导出内容限制为 2 MB 和 500 个发现,并设有每用户预览和确认速率限制。应用程序在手动创建、模板和扫描器导入中总共最多接受 10,000 个发现,单个项目最多 500 个。全局 Findings 列表每页加载 100 行,项目/报告发现查询受相同的每项目限制约束。未知布局会明显失败,而不会被静默视为成功导入。扫描器严重性仅为建议:批准前请审查其上下文。引用的 URL、HTML 和嵌入的远程图像不会被获取或执行。
报告允许 1–100 个发现、最多 100 张证据图像(每张 5 MB,总输入 20 MB)、500 页和 25 MB 输出。签发限制为每个项目 50 个版本,整个应用程序已签发 PDF 总计 1 GB。预览和签发设有每用户速率限制,并且每个应用程序进程一次只允许一个 PDF 渲染。发现最多保留 1000 个修订版本和 500 条评论;达到限制时会失败,而不会覆盖历史记录。DejaVu 字体及其再分发许可证包含在 assets/fonts 中;部署必须保留这些资产(Next 输出追踪会包含它们)。
Next.js Server Actions 共享单个 25mb 请求体大小限制(在 next.config.ts 中设置),用于证据上传。登录使用专用的同源 URL 编码路由,在身份验证或数据库操作之前设有 4 KB 流式限制。
这保留了现有的共享已认证工作区,而非新的按客户租户模型。所有新页面、操作和 PDF 下载都会检查当前由数据库支持的会话。草稿限定于其所有者;审查、模板批准和签发权限在服务器端强制执行。机密 PDF 响应为 private/no-store。最终 PDF 仅包含明确的报告字段允许列表,绝不包含私有草稿、审查评论或无关项目。
该实现使用 OWASP Top 10:2025 检查清单:访问检查(A01)、私有响应和现有 CSP/CSRF 控制(A02)、固定依赖项和 CI(A03)、现有会话/密钥保护以及报告完整性检查(A04/A08)、惰性 Markdown/XML 和参数化数据库访问(A05)、有界处理和独立审查(A06)、实时会话检查(A07)、无内容审计事件(A09),以及失败时清理的事务性更改(A10)。摘要可检测意外损坏;它不是数字签名,也不能防御数据库管理员。这不是合规认证。生产环境仍然需要 HTTPS、受保护的数据库/备份存储以及对审计输出的运营监控。
在部署此升级之前,请进行常规应用程序备份,并使用 npm run db:migrate 应用附加的 20260904221808_reporting_workflow 和 20260906194500_add_revocable_sessions 迁移,然后重新生成 Prisma Client 并重新构建。现有发现从版本 1 的 Draft 开始,现有浏览器 cookie 必须重新登录,以便获得由服务器支持的会话 ID。不要重置现有数据库。备份通过现有的全数据库导出包含新表和已签发 PDF。
npm test npm run lint npx tsc --noEmit --noUnusedLocals --noUnusedParameters npm run build npm audit
`npm test` 使用 Node 的非隔离测试模式配合 `tsx`,以便各个 TypeScript 测试用例真正执行,而不仅仅是报告文件子进程成功。在 CI 中保持显式的断言总数可见。
数据库和浏览器回归测试需要一个**名为 `reporting_tests` 的专用本地数据库**,并已应用迁移。它们会创建并删除自己的夹具行;切勿将这些测试指向应用程序数据库。将 `REPORTING_TEST_DATABASE_URL` 设置为该测试数据库,然后运行:```bash
DATABASE_URL="$REPORTING_TEST_DATABASE_URL" npx prisma migrate deploy
npm run test:reporting
npx playwright install chromium
npm run test:browser
浏览器测试套件会在端口 3317 上启动自己的回环开发服务器,并使用仅用于测试的会话密钥;它拒绝复用已有的服务器。如有需要,可将 REPORTING_TEST_BROWSER 设置为已安装的 Chromium 可执行文件。它测试草稿隐私、冲突编辑、证据上传、独立审查、PDF 权限/不可变性、无需 JavaScript 的模板创建,以及选择性去重导入。集成测试会演练实际的事务冲突和回滚。这些测试套件不能替代远程局域网、Safari 或生产部署验证。
此应用程序设计为在 Ubuntu 上运行,并需要以下内容:```bash sudo apt update && sudo apt install -y nodejs npm postgresql postgresql-client postgresql-contrib zip
`postgresql-client` 提供 `pg_dump`、`pg_restore` 和 `psql`;`zip` 用于创建备份归档。恢复提取由应用程序处理,并带有严格的条目和大小验证。
安装软件包并不总是会让 PostgreSQL 保持运行。在创建角色或启动应用之前,请启动并启用该服务:```bash
sudo systemctl enable --now postgresql
sudo systemctl status postgresql --no-pager
如果应用之后报错 Can't reach database server at 127.0.0.1:5432,请运行 sudo systemctl start postgresql,并用 pg_isready -h 127.0.0.1 -p 5432 确认。
该应用需要 Node.js ^22.12.0 或 >=24.0.0(参见 package.json 中的 engines)。如果操作系统软件包版本较旧,请从可信的软件包源安装受支持的版本,并在运行 setup.sh 之前验证其签名。
在运行 Prisma 或应用之前,请在项目根目录中创建 .env 文件:```bash
cat > .env << 'EOF'
DATABASE_URL="postgresql://em_admin:em_pass@localhost:5432/engagement_manager?schema=public"
JWT_SECRET="replace-with-a-long-random-secret-at-least-32-characters"
EOF
chmod 600 .env
| 变量 | 必需 | 说明 |
|----------|----------|-------|
| `DATABASE_URL` | 是 | PostgreSQL 连接字符串。Prisma 使用 `schema=public` 查询参数。备份和恢复使用仅所有者可访问的临时 pgpass 文件,因此密码不会出现在子进程参数中。 |
| `JWT_SECRET` | 生产环境必需 | 必须至少为 **32 个字符**。生产环境中若缺少此变量,应用将拒绝启动。轮换此密钥会使所有现有会话失效。 |
| `TRUST_PROXY` | 否 | 仅当应用位于反向代理之后,且该代理会**覆盖** `X-Forwarded-For` / `X-Real-IP` 和 `X-Forwarded-Host` 时,才设置为 `1`(或 `true`)。在此模式下,登录来源检查会在存在 `X-Forwarded-Host` 时使用它;该值必须包含一个公共主机名,使用时若端口非默认端口也需包含。否则,代理必须保留公共 `Host` 头。这是实现准确的按来源登录限制所必需的生产拓扑。未设置时,请求头将被忽略以防止欺骗,登录使用更高的每分钟共享回退预算,这样单个客户端就无法造成 15 分钟的全局锁定。 |
| `ALLOWED_DEV_ORIGINS` | 否 | **仅限开发环境。** 允许加载 `/_next` 资源的额外主机名(逗号分隔)。服务器当前的局域网 IPv4 地址会自动允许。用于稳定的 DNS 名称。生产构建会忽略此项。 |
生成强密钥:```bash
openssl rand -base64 32
请确保 PostgreSQL 已首先运行(参见先决条件)。自动化脚本 ./setup.sh 会为你启动该服务;以下手动步骤假定服务已启动。
运行以下命令以创建 PostgreSQL 数据库和用户:```bash sudo -u postgres createuser --pwprompt em_admin sudo -u postgres psql -c "ALTER USER em_admin CREATEDB;" sudo -u postgres createdb --owner=em_admin engagement_manager sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE engagement_manager TO em_admin;"
### 生产环境
使用具有**最小权限**的专用数据库用户——不要授予 `CREATEDB` 或超级用户权限:```bash
sudo -u postgres createuser --pwprompt em_app
sudo -u postgres createdb --owner=em_app engagement_manager
将 DATABASE_URL 设置为使用 em_app(或你选择的用户名)。迁移通过 npm run db:migrate 以该用户身份运行。
注意: 数据库文件存储在 PostgreSQL 数据目录中(通常为
/var/lib/postgresql/<version>/main/)。
在仓库根目录下,运行:```bash chmod +x setup.sh ./setup.sh
该脚本会安装先决条件,启动并启用 PostgreSQL 服务,提示输入数据库用户名和密码,写入一个 `chmod 600` 的 `.env` 文件,创建 PostgreSQL 角色和数据库,应用迁移,并初始化默认管理员账户。生产模式还会完成 `npm run build`,并仅打印生产启动命令。它不会从远程 shell 脚本安装 Node.js;请先安装受支持的 Node.js 版本。
对于无头或 CI 使用:```bash
sudo install -d -m 700 -o "$USER" /secure
openssl rand -base64 24 > /secure/db-password
chmod 600 /secure/db-password
./setup.sh -y --db-user=em_admin --db-pass-file=/secure/db-password
运行 ./setup.sh --help 查看所有选项。