main
md 65 lines 4.41 KB
Rendered Raw
1 # Hermes — History
2
3 ## Core Context
4 - Owns security review for application code, dependencies, and CI workflow changes.
5 - Evaluates risk with the full pipeline in mind, not just single-file diffs.
6
7 ## Learnings
8 - Branch protection must stay intact; automation should use the shared `branch-protection-pr-workflow` skill instead of bypasses.
9 - The current pipeline chains GitHub crawl data, press correlation, AI analysis, content generation, and GitHub Pages deployment, so security review must cover every handoff.
10 - The safest fallback posture is Copilot CLI first, GitHub Models second, and a bounded no-AI summary path after that.
11 - Retry logic and prompt sanitation both matter for defense-in-depth when external content can influence analysis prompts.
12 - Prompt-injection hardening should layer untrusted-content boundaries, pre-render sanitization, output evidence guards, and a closing trusted-mission reminder; sanitize repo descriptions by stripping leading whitespace, escaping boundary-close tags, truncating length, and warning on common injection phrases.
13 - URL validation must use `urllib.parse.urlparse()` instead of substring checks to avoid time-of-check-time-of-use (TOCTOU) vulnerabilities in test contexts and security checks (CodeQL hardening, PR #164).
14 - Config-driven external HTTP fetchers must enforce the intended allowlist in code (HTTPS + approved hosts), per-request timeouts, bounded retries, and bounded concurrency before running in CI.
15
16 ## Cookie Consent & Privacy Policy (Issue #183) — 2026-05-25
17
18 **Legal Text Patterns Used:**
19 - GDPR Article 6(1)(a) explicit consent (opt-in only, no pre-ticked boxes)
20 - GDPR Article 5(1)(a) transparency — all data processors disclosed
21 - GDPR Articles 13/14 privacy information requirements fully covered
22 - GDPR Article 21 right to object — revocation mechanism documented
23 - Zero dark patterns: "Accept all" and "Reject all" equally prominent
24 - Plain English tone, no legalese; links to external authorities (ICO, Google, GitHub)
25 - GA4 processor agreement noted; 14-month retention disclosed as default
26 - Subject access requests via GitHub Issues + direct profile link (proportionate to non-commercial research context)
27
28 **Files Created:**
29 - `content/privacy/_index.md` — Hugo privacy policy (~580 words, covers all GDPR minima)
30 - `data/cookieconsent.json` — Cookie Consent v3 config (plain English copy, no manipulation)
31
32 ## Cookie Banner BaseURL-Aware Links — 2026-05-25
33
34 - Cookie-banner in-site links must not hardcode root-relative paths like `/privacy/` because GitHub project Pages deploys SquadScope under `/SquadScope/`.
35 - Data-file legal copy should use placeholders such as `__PRIVACY_URL__`, with Hugo partials substituting them through URL helpers (`relURL` or `absURL`) at render time.
36
37 ## PR #236 Security Review (2026-06-05)
38
39 - Security review of PR #236 external RSS feeds integration complete
40 - **Verdict: Request changes** (blocking issues found)
41 - Formal approval blocked by GitHub own-PR rules (self-authored by Hermes as PR author)
42 - Posted blocking security comment to PR #236
43 - **Blocking Requirements:**
44 1. URL validation with `urllib.parse.urlparse()`: enforce HTTPS + allowlist hosts only
45 2. Reject credentials, local/private/link-local hosts, unexpected ports
46 3. Explicit per-request timeout in feed fetch code path
47 4. Bounded retry/backoff behavior
48 5. Optional `--max-workers` concurrency validation
49 - **Ownership:** Bender assigned as revision owner to avoid Leela reviewing own implementation changes
50 - **Impact:** PR #236 cannot merge until security fixes implemented and re-reviewed
51
52 ## PR #236 Security Re-Review (2026-06-05 final)
53
54 - Re-reviewed PR #236 at Bender fix commit `e91e2a5b33b816191148125d40192b3fff8fbc6a`
55 - **All security blockers resolved:**
56 - `urllib.parse.urlparse()` validation implemented with HTTPS + allowlist enforcement
57 - Credentials, localhost/private IPs, invalid ports rejected
58 - RSS fetches use `urlopen(..., timeout=DEFAULT_FETCH_TIMEOUT_SECONDS)` with bounded retries
59 - Parallel RSS crawling capped at `DEFAULT_MAX_WORKERS`; `--max-workers < 1` rejected
60 - Test coverage: unsafe URL rejection, explicit timeout propagation
61 - **Validation:** 563 tests passed in isolated PR worktree
62 - **Decision: Security approval/unblock** — CodeQL checks green
63 - **GitHub limitation:** Formal approval rejected due to own-PR token restrictions; unblock comment posted instead
64 - **Outcome:** Technical security gate cleared; awaits admin merge due to policy blocker
65