文件
websafe-kb/scripts/validate-kb.py

90 行
2.4 KiB
Python
可执行文件

#!/usr/bin/env python3
"""
validate-kb.py
基础完整性检查脚本
检查内容:
- README 中的绝对路径链接是否真实存在
- 仓库中是否仍存在已知明文 token
- 关键样例文件是否带有 LAB / AUTHORIZED 边界标记
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path("/Users/x/websafe")
README = ROOT / "README.md"
KNOWN_SECRET_PATTERNS = [
re.compile(r'GITEA_TOKEN="(?!\$\{)[A-Fa-f0-9]{20,}"'),
]
BOUNDARY_FILES = [
ROOT / "README.md",
ROOT / "05-defense/hardening/nginx-hardening.conf",
ROOT / "08-threat-intel/config-examples/github/.github/dependabot.yml",
ROOT / "08-threat-intel/config-examples/github/.github/workflows/dependency-review.yml",
ROOT / "04-server-security/infrastructure/tools/site-scope-mapper.py",
]
def check_readme_links() -> list[str]:
errors = []
content = README.read_text(encoding="utf-8")
links = re.findall(r"\(/Users/x/websafe/[^)]+\)", content)
for raw in links:
path = Path(raw[1:-1].split("#", 1)[0])
if not path.exists():
errors.append(f"README link target missing: {path}")
return errors
def check_known_secrets() -> list[str]:
errors = []
for path in ROOT.rglob("*"):
if not path.is_file():
continue
if ".git" in path.parts:
continue
if path == ROOT / "scripts/validate-kb.py":
continue
try:
content = path.read_text(encoding="utf-8")
except UnicodeDecodeError:
continue
for pattern in KNOWN_SECRET_PATTERNS:
if pattern.search(content):
errors.append(f"Known secret pattern still present: {path}")
return errors
def check_boundary_markers() -> list[str]:
errors = []
for path in BOUNDARY_FILES:
content = path.read_text(encoding="utf-8")
if "LAB ONLY" not in content and "AUTHORIZED" not in content:
errors.append(f"Boundary marker missing: {path}")
return errors
def main() -> int:
errors = []
errors.extend(check_readme_links())
errors.extend(check_known_secrets())
errors.extend(check_boundary_markers())
if errors:
print("Validation failed:")
for item in errors:
print(f"- {item}")
return 1
print("Validation passed.")
return 0
if __name__ == "__main__":
raise SystemExit(main())