实现分层实体漏洞知识库与实体级完整度监控

这个提交包含在:
hao
2026-03-19 17:57:45 -07:00
父节点 49fe46ab89
当前提交 1e81279e32
修改 2712 个文件,包含 434447 行新增2774 行删除

查看文件

@@ -5,7 +5,22 @@ from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Any, Dict, Iterable, List
from intel.config import FRAMEWORK_ROOT, GENERATED_DIR, REGISTRY_ROOT, ROOT, SECURE_CODE_ROOT, SYSTEMS_DIR, TRIAGE_DIR
from intel.config import (
ENTITY_BACKLOG_PATH,
ENTITY_BACKLOG_REPORT_MD_PATH,
ENTITY_CATALOG_REPORT_MD_PATH,
ENTITY_COMPLETENESS_PATH,
ENTITY_QUEUES_PATH,
ENTITIES_DIR,
FRAMEWORK_ROOT,
GENERATED_DIR,
REGISTRY_ROOT,
ROOT,
SECURE_CODE_ROOT,
SYSTEMS_DIR,
TRIAGE_DIR,
)
from intel.entities import build_entity_views
from intel.models import AdvisoryRecord
from intel.utils import ensure_dir, isoformat, now_utc, write_json, write_text
from lab.render import render_dashboard as render_lab_dashboard
@@ -218,6 +233,25 @@ def _sync_selected_json_dir(path: Path, payloads: Dict[str, Any], selected_syste
write_json(path / filename, payload)
def _sync_selected_entity_json_dir(path: Path, payloads: Dict[str, Any], selected_system_ids: set[str]) -> None:
ensure_dir(path)
desired = set(payloads.keys())
for file_path in path.glob("*.json"):
payload = None
try:
payload = file_path.read_text(encoding="utf-8")
except OSError:
continue
if not payload:
continue
if not any(file_path.stem == system_id or file_path.stem.startswith(f"{system_id}--") for system_id in selected_system_ids):
continue
if file_path.name not in desired:
file_path.unlink()
for filename, payload in payloads.items():
write_json(path / filename, payload)
def render_system_scaffolding(
source_map: Dict[str, Any],
advisories: List[AdvisoryRecord],
@@ -386,6 +420,9 @@ def render_case_pages(advisories: List[AdvisoryRecord], selected_system_ids: set
lines.append("fixed_versions:")
for version in (item.fixed_versions or [])[:20]:
lines.append(f' - "{version}"')
lines.append("entity_refs:")
for ref in item.entity_refs or []:
lines.append(f' - "{ref.get("entity_id", "")}:{ref.get("entity_type", "")}:{ref.get("relation", "")}"')
lines.append("secure_code_topics:")
for topic in item.secure_code_topics or []:
lines.append(f' - "{topic}"')
@@ -415,6 +452,26 @@ def render_case_pages(advisories: List[AdvisoryRecord], selected_system_ids: set
f"- 影响版本: `{', '.join((item.affected_versions or [])[:10]) or 'unknown'}`",
f"- 修复版本: `{', '.join((item.fixed_versions or [])[:10]) or 'unknown'}`",
"",
"## 对象与版本映射",
"",
f"- Advisory Scope: `{item.advisory_scope or 'core'}`",
f"- 影响对象: `{', '.join(component.get('name', '-') for component in (item.affected_components or [])) or 'unknown'}`",
f"- Entity Refs: `{', '.join(ref.get('entity_id', '-') for ref in (item.entity_refs or [])) or 'unknown'}`",
f"- 版本置信度: `{item.version_confidence or 'unknown'}`",
f"- 版本缺口: `{item.version_gap_reason or '-'}`",
f"- 版本证据源: `{', '.join((item.version_evidence_sources or [])[:5]) or 'unknown'}`",
"",
"## 受控验证流程",
"",
f"- Workflow ID: `{item.workflow.get('workflow_id') or '-'}`",
f"- 漏洞家族: `{item.workflow.get('vuln_family') or '-'}`",
f"- 入口面: `{item.workflow.get('entry_surface') or '-'}`",
f"- 需要角色: `{item.workflow.get('required_role') or '-'}`",
f"- 触发向量: {item.workflow.get('trigger_vector') or '-'}",
f"- 请求/页面入口: `{', '.join(item.workflow.get('request_or_ui_path', [])[:5]) or '-'}`",
f"- 输入形态: {item.workflow.get('input_shape') or '-'}",
f"- 预期不安全行为: {item.workflow.get('expected_unsafe_behavior') or '-'}",
"",
"## 其他来源",
"",
]
@@ -427,6 +484,28 @@ def render_case_pages(advisories: List[AdvisoryRecord], selected_system_ids: set
lines.extend(
[
"",
"## 证据点与补丁验证",
"",
]
)
for section, values in [
("服务端证据点", item.workflow.get("server_evidence_points", [])),
("浏览器证据点", item.workflow.get("browser_evidence_points", [])),
("数据库/文件系统证据点", item.workflow.get("db_or_fs_evidence_points", [])),
("检测信号", item.workflow.get("detection_signals", [])),
("补丁验证步骤", item.workflow.get("patch_validation_steps", [])),
("实验安全备注", item.workflow.get("lab_safety_notes", [])),
]:
lines.append(f"### {section}")
lines.append("")
if values:
for value in values:
lines.append(f"- {value}")
else:
lines.append("- 未定义")
lines.append("")
lines.extend(
[
"## 实验层",
"",
"- 仅用于自有资产、测试环境或已明确授权目标。",
@@ -454,6 +533,7 @@ def render_registry(
selected_system_ids: set[str] | None = None,
) -> None:
run_map = latest_runs_by_advisory()
entity_views = build_entity_views(source_map, advisories)
grouped: Dict[str, List[AdvisoryRecord]] = defaultdict(list)
advisory_payloads: Dict[str, Dict[str, Any]] = {}
for advisory in advisories:
@@ -497,10 +577,17 @@ def render_registry(
_sync_selected_json_dir(REGISTRY_ROOT / "advisories", advisory_payloads, selected_system_ids)
_sync_selected_json_dir(TRIAGE_DIR, triage_payloads, selected_system_ids)
_sync_selected_json_dir(REGISTRY_ROOT / "systems", system_payloads, selected_system_ids, systems_dir=True)
selected_entity_payloads = {
filename: payload
for filename, payload in entity_views["entity_payloads"].items()
if payload.get("root_system_id") in selected_system_ids
}
_sync_selected_entity_json_dir(ENTITIES_DIR, selected_entity_payloads, selected_system_ids)
return
_sync_json_dir(REGISTRY_ROOT / "advisories", advisory_payloads)
_sync_json_dir(TRIAGE_DIR, triage_payloads)
_sync_json_dir(REGISTRY_ROOT / "systems", system_payloads)
_sync_json_dir(ENTITIES_DIR, entity_views["entity_payloads"])
def render_generated(
@@ -513,6 +600,7 @@ def render_generated(
ensure_dir(GENERATED_DIR)
systems = {item["system_id"]: item for item in source_map["systems"]}
run_map = latest_runs_by_advisory()
entity_views = build_entity_views(source_map, advisories)
change_summary = change_summary or {}
triage_by_system: Dict[str, List[Dict[str, Any]]] = defaultdict(list)
for item in triage:
@@ -549,6 +637,8 @@ def render_generated(
f"- 渲染时间: `{isoformat(now_utc())}`",
f"- 系统数量: `{len(source_map['systems'])}`",
f"- Advisory 数量: `{len(advisories)}`",
f"- 已编目实体数量: `{entity_views['completeness']['cataloged_entity_total']}`",
f"- 待编目 backlog 数量: `{entity_views['completeness']['candidate_entity_total']}`",
f"- 重点 Markdown 数量: `{markdown_total}`",
f"- Run Bundle 数量: `{len(run_map)}`",
f"- 新增记录: `{change_summary.get('new_count', 0)}`",
@@ -568,6 +658,8 @@ def render_generated(
"generated_at": isoformat(now_utc()),
"system_count": len(source_map["systems"]),
"advisory_count": len(advisories),
"cataloged_entity_total": entity_views["completeness"]["cataloged_entity_total"],
"candidate_entity_total": entity_views["completeness"]["candidate_entity_total"],
"markdown_count": markdown_total,
"new_count": change_summary.get("new_count", 0),
"updated_count": change_summary.get("updated_count", 0),
@@ -577,6 +669,11 @@ def render_generated(
"failures": failures,
},
)
write_json(ENTITY_COMPLETENESS_PATH, entity_views["completeness"])
write_json(ENTITY_BACKLOG_PATH, entity_views["candidate_backlog"])
write_json(ENTITY_QUEUES_PATH, entity_views["queues"])
write_text(ENTITY_CATALOG_REPORT_MD_PATH, entity_views["catalog_report_markdown"])
write_text(ENTITY_BACKLOG_REPORT_MD_PATH, entity_views["backlog_report_markdown"])
render_lab_dashboard(
advisory_records=[item.to_dict() for item in advisories],
source_map_data=source_map,