Files
novalon-website/scripts/security-scan.sh
T
张翔 10404dbb36 chore: sync marketing pages, CMS extensions, tests and project docs
同步工作区剩余变更,主要包括:
- 营销页面组件与布局持续优化(about/news/services/solutions/team 等)
- 详情页四层叙事组件、布局组件、UI 组件调整
- CMS 数据模型、API 路由、权限、工作流、站内通知、媒体管理扩展
- 新增/补充单元测试与 E2E 测试(cms-workflow.spec.ts 等)
- ESLint 9 迁移、jest/tsconfig 配置更新、依赖调整
- 新增 ADR、CMS 评估文档、Release Review / Acceptance 报告
- 移除水墨装饰组件与大体积未使用字体文件
2026-07-25 08:04:01 +08:00

81 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# 封版验收安全扫描手动清单脚本
# 运行环境:本地生产预览服务 http://localhost:3000
# 前置条件:npm run start 已启动在 3000 端口
set -euo pipefail
BASE_URL="${BASE_URL:-http://localhost:3000}"
REPORT_DIR="${REPORT_DIR:-release-acceptance-reports/$(date +%Y%m%d-%H%M%S)}"
mkdir -p "$REPORT_DIR"
echo "======================================"
echo "安全扫描手动清单"
echo "目标: $BASE_URL"
echo "报告目录: $REPORT_DIR"
echo "======================================"
# SEC-01 / SEC-06: 依赖漏洞扫描
echo "[SEC-01] 运行 npm audit --production..."
npm audit --audit-level moderate --registry=https://registry.npmjs.org/ > "$REPORT_DIR/50-npm-audit-final.log" 2>&1 || true
# SEC-02: 安全响应头检查
echo "[SEC-02] 检查安全响应头..."
curl -sI "$BASE_URL/" | grep -iE 'X-Content-Type-Options|X-Frame-Options|X-XSS-Protection|Strict-Transport-Security|Content-Security-Policy' > "$REPORT_DIR/51-security-headers.log" 2>&1 || true
if [ ! -s "$REPORT_DIR/51-security-headers.log" ]; then
echo "未检测到安全响应头" > "$REPORT_DIR/51-security-headers.log"
fi
# SEC-03: 认证绕过测试
echo "[SEC-03] 测试未授权访问 /admin 与 /api/admin/models..."
{
echo "GET $BASE_URL/admin"
curl -s -o /dev/null -w "%{http_code}\n" "$BASE_URL/admin"
echo "GET $BASE_URL/api/admin/models"
curl -s -o /dev/null -w "%{http_code}\n" "$BASE_URL/api/admin/models"
} > "$REPORT_DIR/52-auth-bypass.log" 2>&1
# SEC-04: XSS 过滤测试
echo "[SEC-04] 测试联系表单 XSS 过滤..."
curl -s -X POST "$BASE_URL/api/contact" \
-H "Content-Type: application/json" \
-d '{"name":"XSS Test","email":"xss@test.com","phone":"13800138000","subject":"XSS","message":"<script>alert(1)</script>"}' \
> "$REPORT_DIR/53-xss-test.log" 2>&1
# SEC-05: SQLi 过滤测试
echo "[SEC-05] 测试联系表单 SQLi 过滤..."
curl -s -X POST "$BASE_URL/api/contact" \
-H "Content-Type: application/json" \
-d '{"name":"SQLi Test","email":"sqli@test.com","phone":"13800138000","subject":"SQLi","message":"1\x27 OR \x271\x27=\x271"}' \
> "$REPORT_DIR/54-sqli-test.log" 2>&1
# SEC-06: JWT 校验测试
echo "[SEC-06] 测试 JWT 校验..."
{
echo "空 token:"
curl -s -o /dev/null -w "%{http_code}\n" "$BASE_URL/api/admin/models"
echo "无效 token:"
curl -s -o /dev/null -w "%{http_code}\n" -H "Authorization: Bearer invalid-token" "$BASE_URL/api/admin/models"
echo "过期 token (expired signature):"
curl -s -o /dev/null -w "%{http_code}\n" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyMzkwMjJ9.4AdcjS3X_FSn0FxL5XfKX5qJ6tE4ZfG8h0e8_xW3V7o" "$BASE_URL/api/admin/models"
} > "$REPORT_DIR/55-jwt-test.log" 2>&1
# SEC-07: 敏感信息泄露扫描
echo "[SEC-07] 扫描源码中的硬编码敏感信息..."
grep -R -n -E "password|secret|token|api[_-]?key" \
--include="*.ts" --include="*.tsx" \
src/ \
| grep -v "\.env" \
| grep -v "process\.env" \
| grep -v "// " \
| head -100 \
> "$REPORT_DIR/56-secrets-scan.log" 2>&1 || true
if [ ! -s "$REPORT_DIR/56-secrets-scan.log" ]; then
echo "未发现明显硬编码敏感信息" > "$REPORT_DIR/56-secrets-scan.log"
fi
echo "======================================"
echo "安全扫描完成,产物保存在 $REPORT_DIR"
echo "======================================"