forked from wangziqi/gongxue-base
feat: add external asset security scanner
This commit is contained in:
@@ -97,7 +97,7 @@ npm --workspace @tiku-saas/worker run exports:once
|
||||
3. 调用 `PUT /api/tenant-content/assets` 登记资源台账。托管对象默认进入 `status=draft`、`uploadStatus=pending`。
|
||||
4. 调用 `POST /api/tenant-content/assets/confirm-upload`,由后端读取对象元数据并比对大小、MIME、SHA-256。
|
||||
5. 校验通过后,后端只会置为 `uploadStatus=verified`、`securityScanStatus=pending`,并继续保持 `status=draft`。即使请求里传 `publish=true`,也不会绕过安全扫描直接发布。
|
||||
6. 运行 assets worker。worker 会先复检对象元数据,再执行内置 `metadata_rules` 安全扫描,检查 object key、MIME allowlist、文件大小、扩展名/MIME 是否匹配等规则。
|
||||
6. 运行 assets worker。worker 会先复检对象元数据,再执行内置 `metadata_rules` 安全扫描,检查 object key、MIME allowlist、文件大小、扩展名/MIME 是否匹配等规则;生产可配置 `WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http`,在内置规则通过后调用外部 HTTP 杀毒/内容安全服务。
|
||||
7. 扫描通过后,资源变为 `securityScanStatus=passed`,后台再调用 `PUT /api/tenant-content/assets` 将 `status=active` 发布。
|
||||
8. 学生端只能下载或预览 `active + uploadStatus=verified + securityScanStatus=passed` 的托管对象资源;后台管理员下载/预览也执行同一安全扫描门禁。
|
||||
9. 学生端和后台管理员下载/预览都会写入 `content_asset_access_events`,包含 `assetId/userId/accessType/result/expiresInSec/signatureMode/ip/userAgent` 等审计字段。
|
||||
@@ -168,7 +168,48 @@ npm --workspace @tiku-saas/worker run exports:once
|
||||
| `security_scan_provider` | 扫描来源,例如 `metadata_rules`、`trusted_export_worker` |
|
||||
| `security_scan_summary` | 风险等级、问题码、扫描证据和失败原因 |
|
||||
|
||||
当前内置 provider 是 `metadata_rules`。它不是完整杀毒引擎,但能阻断明显危险或不合规对象:跨租户 key、非法 object key、超限文件、MIME allowlist 外文件、扩展名/MIME 不匹配,以及测试/运营标记的强制失败。商用生产仍需继续接入真实 AV/内容安全 provider,并将结果写入同一张事件表。
|
||||
内置 provider 是 `metadata_rules`。它不是完整杀毒引擎,但能阻断明显危险或不合规对象:跨租户 key、非法 object key、超限文件、MIME allowlist 外文件、扩展名/MIME 不匹配,以及测试/运营标记的强制失败。
|
||||
|
||||
生产环境支持可插拔 HTTP provider:`WORKER_ASSET_SECURITY_SCANNER=metadata_rules,http`。worker 会在 metadata 规则通过后调用外部扫描服务,并把外部扫描结果和内置规则合并为一次最终结果写回 `content_assets`。如果外部服务返回失败、响应无效、超时或不可用,默认 `fail-open=false`,资源会被标记为 `securityScanStatus=failed` 并从 `active` 退回 `draft`。生产 readiness 会阻断没有外部 scanner、HTTP endpoint 非 HTTPS、token 弱或开启 fail-open 的配置。
|
||||
|
||||
HTTP scanner 请求由 worker 发起,前端不会接触扫描服务地址、token 或对象存储密钥。请求示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"assetId": "00000000-0000-0000-0000-000000000000",
|
||||
"tenantId": "00000000-0000-0000-0000-000000000001",
|
||||
"assetType": "pdf",
|
||||
"storageProvider": "aliyun_oss",
|
||||
"bucket": "tenant-assets",
|
||||
"objectKey": "tenant-id/assets/file.pdf",
|
||||
"fileName": "file.pdf",
|
||||
"mimeType": "application/pdf",
|
||||
"fileSizeBytes": 4096,
|
||||
"checksumSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"metadata": {
|
||||
"observed": {},
|
||||
"declared": {}
|
||||
},
|
||||
"requestedAt": "2026-06-29T00:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
HTTP scanner 响应契约:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "passed",
|
||||
"riskLevel": "none",
|
||||
"issueCodes": [],
|
||||
"provider": "clamav",
|
||||
"details": {
|
||||
"engine": "clamav",
|
||||
"signature": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`status` 只允许 `passed` 或 `failed`;`riskLevel` 只允许 `none/low/medium/high/critical`。`details` 会经过脱敏后写入扫描事件,`secret/token/password/privateKey/apiKey/authorization` 等字段会被替换为 `[redacted]`。
|
||||
|
||||
扫描事件表:
|
||||
|
||||
@@ -273,6 +314,11 @@ WORKER_ASSET_BATCH_SIZE=50
|
||||
WORKER_ASSET_MIN_AGE_SECONDS=300
|
||||
WORKER_ASSET_RECHECK_INTERVAL_SECONDS=86400
|
||||
WORKER_ASSET_REQUEST_TIMEOUT_MS=10000
|
||||
WORKER_ASSET_SECURITY_SCANNER=metadata_rules
|
||||
WORKER_ASSET_SECURITY_SCAN_HTTP_ENDPOINT=
|
||||
WORKER_ASSET_SECURITY_SCAN_HTTP_TOKEN=
|
||||
WORKER_ASSET_SECURITY_SCAN_HTTP_TIMEOUT_MS=10000
|
||||
WORKER_ASSET_SECURITY_SCAN_FAIL_OPEN=false
|
||||
```
|
||||
|
||||
## 生产建议
|
||||
@@ -282,7 +328,7 @@ WORKER_ASSET_REQUEST_TIMEOUT_MS=10000
|
||||
- 图片、PDF、视频分别设置合理的 CORS,只允许前端域名和小程序业务域名访问。
|
||||
- 开启对象版本控制、生命周期、跨区域复制或定时备份,满足后续容灾要求。
|
||||
- 视频资源已接入 SVIP/播放次数校验、短期签名和播放日志;生产阶段继续补转码、动态水印、CDN 防盗链和播放统计。
|
||||
- 大文件上传已经支持 API 即时确认和 worker 元数据复检;后续继续补杀毒、转码、水印和 CDN 刷新。
|
||||
- 大文件上传已经支持 API 即时确认、worker 元数据复检、内置规则扫描和外部 HTTP 扫描契约;生产阶段必须接入真实扫描服务 endpoint/token,并继续补转码、水印、CDN 刷新和生命周期策略。
|
||||
|
||||
## 官方依据
|
||||
|
||||
|
||||
Reference in New Issue
Block a user