Files
awoooi/scripts/security/public-frontend-env-guard.py

68 lines
2.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""檢查公開前端 env 範例不可洩漏內網拓樸。"""
from __future__ import annotations
import argparse
import re
from pathlib import Path
PRIVATE_IP_PATTERN = re.compile(
r"\b(?:10(?:\.\d{1,3}){3}|192\.168(?:\.\d{1,3}){2}|172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2})\b"
)
RETIRED_PUBLIC_TOPOLOGY_KEYS = {
"NEXT_PUBLIC_HOST_IPS",
"NEXT_PUBLIC_K8S_VIP_INFO",
}
ENV_EXAMPLE_PATHS = (
Path("apps/web/.env.example"),
)
def _active_assignment(line: str) -> tuple[str, str] | None:
stripped = line.strip()
if not stripped or stripped.startswith("#") or "=" not in stripped:
return None
key, value = stripped.split("=", 1)
return key.strip(), value.strip()
def validate(root: Path) -> None:
errors: list[str] = []
for relative_path in ENV_EXAMPLE_PATHS:
path = root / relative_path
if not path.exists():
continue
for line_number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), start=1):
assignment = _active_assignment(line)
if assignment is None:
continue
key, value = assignment
if key in RETIRED_PUBLIC_TOPOLOGY_KEYS:
errors.append(f"{relative_path}:{line_number}: 已停用公開前端拓樸 env key{key}")
if PRIVATE_IP_PATTERN.search(value):
errors.append(f"{relative_path}:{line_number}: env 範例不得包含內網 IP{key}")
if key.startswith("NEXT_PUBLIC_") and not value:
errors.append(f"{relative_path}:{line_number}: NEXT_PUBLIC_* 範例需明確使用公網入口或安全預設值:{key}")
if errors:
raise SystemExit("BLOCKED public frontend env guard:\n" + "\n".join(f"- {error}" for error in errors))
def main() -> None:
parser = argparse.ArgumentParser(description="檢查公開前端 env 範例不可洩漏內網拓樸")
parser.add_argument("--root", default=".", help="repository root")
args = parser.parse_args()
validate(Path(args.root).resolve())
print("OK public frontend env guard")
if __name__ == "__main__":
main()