@aegis-scan/skills 0.2.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ATTRIBUTION.md +171 -4
- package/CHANGELOG.md +112 -1
- package/README.md +27 -0
- package/dist/skills-loader.d.ts +43 -0
- package/dist/skills-loader.d.ts.map +1 -1
- package/dist/skills-loader.js +102 -0
- package/dist/skills-loader.js.map +1 -1
- package/package.json +1 -1
- package/skills/compliance/_INDEX.md +49 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/CHANGELOG.md +202 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/LICENSE +43 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/README.md +236 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/SKILL.md +437 -6
- package/skills/compliance/aegis-native/brutaler-anwalt/references/aegis-integration.md +3 -4
- package/skills/compliance/aegis-native/brutaler-anwalt/references/audit-patterns.md +842 -5
- package/skills/compliance/aegis-native/brutaler-anwalt/references/bgh-urteile.md +226 -10
- package/skills/compliance/aegis-native/brutaler-anwalt/references/branchenrecht.md +365 -1
- package/skills/compliance/aegis-native/brutaler-anwalt/references/checklisten.md +33 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/dsgvo.md +26 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/BDSG/paragraphs.md +62 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/BFSG/paragraphs.md +85 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/BGB/paragraphs.md +112 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/DDG/paragraphs.md +71 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/DSGVO/articles.md +182 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/EU-Verordnungen/AI-Act-2024-1689/articles.md +108 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/EU-Verordnungen/DSA-2022-2065/articles.md +131 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/HGB-AO/paragraphs.md +61 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/INDEX.md +93 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/TDDDG/paragraphs.md +67 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/UWG/paragraphs.md +117 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/gesetze/VSBG/paragraphs.md +57 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/it-recht.md +22 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/INDEX.md +122 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/ai/mistral-eu.md +123 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/ai/openai-dpa.md +120 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/auth/nextauth-tom.md +120 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/auth/supabase-auth-tom.md +104 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/nextjs/proxy-csp-pattern.md +93 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/payment/stripe-pci-tom.md +121 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/stack-patterns/tracking/plausible-pattern.md +107 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/AffiliateDisclaimer.tsx.example +54 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/COMPLIANCE-AUDIT-TRAIL-template.md +95 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/DSE-Section-UGC.md.example +77 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/DSFA-template.md +76 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/LostFoundReportForm-consent.tsx.example +126 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/README.md +33 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/UmamiScript.tsx.example +64 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/VVT-template.md +60 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/data-retention-cron.ts.example +52 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/data-retention-workflow.yml.example +47 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/proxy-strict-dynamic.ts.example +80 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/references/templates/security.txt.example +26 -0
- package/skills/compliance/aegis-native/brutaler-anwalt/scripts/health-check.sh +120 -0
- package/skills/defensive/aegis-native/rls-defense/SKILL.md +110 -0
- package/skills/defensive/aegis-native/tenant-isolation-defense/SKILL.md +26 -0
- package/skills/foundation/_INDEX.md +73 -0
- package/skills/foundation/aegis-native/aegis-audit/SKILL.md +194 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-1-headers.md +138 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-2-html.md +153 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-3-impressum.md +159 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-4-dse.md +178 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-5-cookie.md +180 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-6-branche.md +204 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-7-code-cross-check.md +212 -0
- package/skills/foundation/aegis-native/aegis-audit/references/layer-8-schadens-diagnose.md +232 -0
- package/skills/foundation/aegis-native/aegis-customer-build/SKILL.md +232 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-1-recon.md +147 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-2-architecture.md +164 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-3-component-build.md +231 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-4-content.md +196 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-5-integration.md +273 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-6-mid-audit.md +200 -0
- package/skills/foundation/aegis-native/aegis-customer-build/references/phase-7-final-verify.md +258 -0
- package/skills/foundation/aegis-native/aegis-handover-writer/SKILL.md +128 -0
- package/skills/foundation/aegis-native/aegis-module-builder/SKILL.md +255 -0
- package/skills/foundation/aegis-native/aegis-orchestrator/SKILL.md +229 -0
- package/skills/foundation/aegis-native/aegis-quality-gates/SKILL.md +182 -0
- package/skills/foundation/aegis-native/aegis-skill-creator/SKILL.md +223 -0
- package/skills/foundation/aegis-native/aegis-skill-creator/references/hard-constraint-template.md +213 -0
- package/skills/foundation/aegis-native/aegis-skill-creator/references/skillforge-methodology.md +220 -0
- package/skills/foundation/aegis-native/dsgvo-compliance/SKILL.md +185 -0
- package/skills/foundation/aegis-native/dsgvo-compliance/references/art-13-15-templates.md +309 -0
- package/skills/foundation/aegis-native/dsgvo-compliance/references/datenpanne-runbook.md +291 -0
- package/skills/offensive/matty-fork/cicd-redteam/SKILL.md +531 -0
- package/skills/offensive/matty-fork/cloud-security/SKILL.md +106 -0
- package/skills/offensive/matty-fork/container-escape/SKILL.md +174 -0
- package/skills/offensive/matty-fork/mobile-pentester/SKILL.md +357 -0
- package/skills/offensive/matty-fork/subdomain-takeover/SKILL.md +154 -0
- package/skills/osint/elementalsouls-fork/offensive-osint/README.md +92 -0
- package/skills/osint/elementalsouls-fork/offensive-osint/SKILL.md +4177 -0
- package/skills/osint/elementalsouls-fork/osint-methodology/README.md +66 -0
- package/skills/osint/elementalsouls-fork/osint-methodology/SKILL.md +1695 -0
- package/sbom.cdx.json +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# foundation/_INDEX.md — Foundation Skill Trigger-Table
|
|
2
|
+
|
|
3
|
+
Routes the Foundation's own skills (orchestrator, customer-build, audit, etc.) based on user intent + keyword triggers. Loaded on-demand by the master `AGENTS.md` router when a Foundation-related request arrives.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Skills in this category
|
|
8
|
+
|
|
9
|
+
| Trigger keywords | → Skill | Frontmatter `model` | Loaded path |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| start, session, bootstrap, phase, handover, weiter, weitermachen, übergabe, recap | `aegis-orchestrator` | opus | `foundation/aegis-native/aegis-orchestrator/SKILL.md` |
|
|
12
|
+
| handover, übergabe, session-ende, fertig, recap, abschluss | `aegis-handover-writer` | sonnet | `foundation/aegis-native/aegis-handover-writer/SKILL.md` |
|
|
13
|
+
| verify, check all gates, quality-gates, audit-gate, pre-commit-check | `aegis-quality-gates` | sonnet | `foundation/aegis-native/aegis-quality-gates/SKILL.md` |
|
|
14
|
+
| build customer, kundenseite, neue site, konfigurator-briefing, autonomous-build, 3h-build | `aegis-customer-build` | opus | `foundation/aegis-native/aegis-customer-build/SKILL.md` |
|
|
15
|
+
| module, feature, db-migration, api-route, refactor, neue funktion, neue api, neues modul | `aegis-module-builder` | sonnet | `foundation/aegis-native/aegis-module-builder/SKILL.md` |
|
|
16
|
+
| audit, paranoid-audit, AAA+++ check, 8-layer, security-audit, full-audit | `aegis-audit` | opus | `foundation/aegis-native/aegis-audit/SKILL.md` |
|
|
17
|
+
| neuer skill, skill erstellen, skill verbessern, skill audit, meta-skill, skillforge | `aegis-skill-creator` | opus | `foundation/aegis-native/aegis-skill-creator/SKILL.md` |
|
|
18
|
+
| consent, retention, art-13, art-15, art-33, datenpanne, drittland, dsgvo-baseline, schrems | `dsgvo-compliance` | opus | `foundation/aegis-native/dsgvo-compliance/SKILL.md` |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Slash-Commands
|
|
23
|
+
|
|
24
|
+
- `/start` / `/session` / `/bootstrap` — invoke aegis-orchestrator
|
|
25
|
+
- `/verify` / `/check all gates` — invoke aegis-quality-gates
|
|
26
|
+
- `/handover` / `/übergabe` / `/session-ende` — invoke aegis-handover-writer
|
|
27
|
+
- `/build` / `/customer-build` / `/agentur-build` — invoke aegis-customer-build
|
|
28
|
+
- `/module` / `/feature` / `/refactor` — invoke aegis-module-builder
|
|
29
|
+
- `/audit` / `/paranoid-audit` / `/8-layer` — invoke aegis-audit
|
|
30
|
+
- `/skill-creator` / `/new-skill` / `/skill-audit` — invoke aegis-skill-creator
|
|
31
|
+
- `/dsgvo` / `/art-13` / `/art-15` / `/datenpanne` / `/schrems` — invoke dsgvo-compliance
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Rules for foundation skills
|
|
36
|
+
|
|
37
|
+
- Each skill MUST have `metadata.required_tools`, `metadata.pre_done_audit`, `model`, `license` populated per the v0.3.0+ HARD-CONSTRAINT-frontmatter format.
|
|
38
|
+
- Each skill MUST validate `python3 /tmp/SkillForge/scripts/validate-skill.py <skill>` at 16/17 or higher (the 1-warning ceiling allows for "5 phases recommend 1-3" advisories on intentionally-multi-phase skills).
|
|
39
|
+
- Multi-file skills (SKILL.md + sibling `references/`) are auto-installed; references kept under `<skill>/references/`.
|
|
40
|
+
- The master `AGENTS.md` tool-mapping table is canonical — skills reference tool-categories (`shell-ops`, `file-ops`, etc.), the AGENTS.md tells the agent which actual harness-tool to use.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Bootstrap-checklist (called by master AGENTS.md)
|
|
45
|
+
|
|
46
|
+
When this category is loaded:
|
|
47
|
+
|
|
48
|
+
1. Verify the matched skill's SKILL.md is in context (read it, don't just assume).
|
|
49
|
+
2. Check the skill's `metadata.required_tools` — confirm those tool-categories are available in the harness (per AGENTS.md tool-mapping table).
|
|
50
|
+
3. If `metadata.pre_done_audit: "true"` — note it; the skill will not be allowed to declare DONE without explicit pre-done-audit completion.
|
|
51
|
+
4. Print: `Loaded foundation skill: <name>, model: <opus|sonnet|haiku>, audit-passes: <N>, gates: <N>`.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Cluster Composition Patterns
|
|
56
|
+
|
|
57
|
+
The 8 foundation skills compose into use-case clusters per master `AGENTS.md` Use-Case Routing:
|
|
58
|
+
|
|
59
|
+
| Use-case | Cluster |
|
|
60
|
+
|---|---|
|
|
61
|
+
| customer-build | aegis-orchestrator → aegis-customer-build (multi-agent) → aegis-quality-gates → aegis-handover-writer |
|
|
62
|
+
| compliance-audit | aegis-orchestrator → aegis-audit + brutaler-anwalt (cross-validate) → dsgvo-compliance (fix-templates) → aegis-handover-writer |
|
|
63
|
+
| dev-feature | aegis-orchestrator → aegis-module-builder (TDD) → aegis-quality-gates → aegis-handover-writer |
|
|
64
|
+
| aegis-self-test | aegis-orchestrator → aegis-quality-gates → aegis-audit → aegis-handover-writer |
|
|
65
|
+
| skill-authoring | aegis-orchestrator → aegis-skill-creator → aegis-quality-gates → aegis-handover-writer |
|
|
66
|
+
|
|
67
|
+
Each cluster ends with `aegis-handover-writer` to ensure the next session starts with full context.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Forward-compat note
|
|
72
|
+
|
|
73
|
+
`foundation/_INDEX.md` at v0.4.0+ routes the full 8-skill foundation cluster. Future foundation-additions (e.g., `aegis-deploy` for Hetzner-Dokploy automation, `aegis-monitoring` for post-deploy observability) get rows added here + corresponding SKILL.md folders under `foundation/aegis-native/`.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<!-- aegis-local: AEGIS-native skill, MIT-licensed; 8-Layer paranoid-audit skill. Headers / HTML / Impressum / DSE / Cookie / Branche / Code-Cross-Check / Schadens-Diagnose. Runs against built customer-site, gegen Live-URL, oder gegen lokales Repo. Output 4-section format (Schadens-Diagnose / Findings-Tabelle / Anwalts-Anhang / Abmahn-Simulation). Pattern ported from a private operational reference; this is the public OSS variant. -->
|
|
2
|
+
---
|
|
3
|
+
name: aegis-audit
|
|
4
|
+
description: 8-Layer paranoid-audit skill. Headers / HTML / Impressum / DSE / Cookie / Branche / Code-Cross-Check / Schadens-Diagnose. Runs against built site, live URL, or local repo. Output 4-section - Schadens-Diagnose / Findings-Tabelle / Anwalts-Anhang / Abmahn-Simulation. Trigger keywords - audit, paranoid-audit, AAA+++ check, 8-layer, security-audit, full-audit.
|
|
5
|
+
model: opus
|
|
6
|
+
license: MIT
|
|
7
|
+
metadata:
|
|
8
|
+
required_tools: "shell-ops,file-ops,curl,playwright,aegis-scan"
|
|
9
|
+
required_audit_passes: "1"
|
|
10
|
+
enforced_quality_gates: "0"
|
|
11
|
+
pre_done_audit: "true"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# aegis-audit — 8-Layer Paranoid Audit
|
|
15
|
+
|
|
16
|
+
The Foundation's audit skill. Runs an 8-layer audit against a target (customer-site / live URL / local repo), produces a 4-section structured report, classifies findings by severity (KRITISCH / HOCH / MITTEL / LOW), estimates €-risk per finding via the industry × visibility × competitor formula. Used by customer-build's Phase 6 (mid-audit, topic-scoped) and Phase 7 (final, full-pass).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## HARD-CONSTRAINT — Layer-Order, Reference-Loading, No Mocks
|
|
21
|
+
|
|
22
|
+
This skill MUST:
|
|
23
|
+
|
|
24
|
+
1. **Load all 8 layer-references** in `references/layer-1-headers.md` through `references/layer-8-schadens-diagnose.md` BEFORE producing any finding. Skipping a layer-reference = guaranteed false-negatives or false-positives.
|
|
25
|
+
2. **Execute layers in fixed order** (1 → 8). Earlier layers feed later ones (e.g., Layer 1 HTTP-headers feed Layer 5 cookie-detection). Out-of-order execution skips signal.
|
|
26
|
+
3. **No mocks.** Every layer hits the real target via real HTTP / curl / Playwright. If the target is unreachable — report NO-RESPONSE; never infer findings from chat-context.
|
|
27
|
+
4. **Cross-check with brutaler-anwalt** (`compliance/aegis-native/brutaler-anwalt/SKILL.md`). aegis-audit is the technical pass; brutaler-anwalt is the legal pass. They share Layer 3 (Impressum) + Layer 4 (DSE) + Layer 5 (Cookie). Findings get cross-validated.
|
|
28
|
+
5. **Output the canonical 4-section format.** Schadens-Diagnose / Findings-Tabelle / Anwalts-Anhang / Abmahn-Simulation. No deviation; downstream tooling parses this format.
|
|
29
|
+
6. **Include €-range estimates** per Layer 8 formula (industry × visibility × competitor-pressure). Estimates are advisory, not legal advice — disclaimer required.
|
|
30
|
+
|
|
31
|
+
If any layer cannot run (e.g., Playwright not installed) — STOP, report which layer + why. Don't silent-skip.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Mission
|
|
36
|
+
|
|
37
|
+
Eliminate the failure-mode where "the site looks fine" turns into a €15k abmahnung 3 weeks after launch. Catch the legal + technical regressions that scanners-alone miss because they don't cross-correlate (e.g., a tracker loaded before consent + impressum missing VAT-ID + cookie-banner with no equal-prominence reject = composite finding worth €5-15k).
|
|
38
|
+
|
|
39
|
+
Be the audit that:
|
|
40
|
+
|
|
41
|
+
- Hits every layer that abmahnanwalts inspect.
|
|
42
|
+
- Cross-correlates findings (a single scanner-hit might be 0 €; a 3-finding-cluster might be €15k).
|
|
43
|
+
- Estimates €-risk (operator can prioritize).
|
|
44
|
+
- Produces a 4-section report that operator + legal + dev can all consume.
|
|
45
|
+
- Distinguishes between "fix-now KRITISCH" and "fix-this-quarter MITTEL".
|
|
46
|
+
|
|
47
|
+
Production-bar reference: a previous full-audit on a 13-page site (private operational reference) returned 0 KRITISCH / 0 HOCH / 3 MITTEL / 8 LOW with €-range 200-800 €/quarter (very low) — the bar this skill targets.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Triggers
|
|
52
|
+
|
|
53
|
+
### Slash-commands
|
|
54
|
+
|
|
55
|
+
- `/audit` — run full 8-layer audit on the configured target
|
|
56
|
+
- `/paranoid-audit` — alias
|
|
57
|
+
- `/8-layer` — alias
|
|
58
|
+
|
|
59
|
+
### Auto-trigger keywords
|
|
60
|
+
|
|
61
|
+
- audit, paranoid-audit, AAA+++ check, 8-layer, security-audit, full-audit, abmahn-prevention
|
|
62
|
+
|
|
63
|
+
### Programmatic invocation
|
|
64
|
+
|
|
65
|
+
Customer-build Phase 6 invokes via:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
Skill: aegis-native/aegis-audit
|
|
69
|
+
Args: --mode=mid --topics=impressum,cookie,dse --target=http://localhost:3000
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Phase 7 invokes via:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
Skill: aegis-native/aegis-audit
|
|
76
|
+
Args: --mode=full --target=http://localhost:3000 --output=audits/final.md
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Process
|
|
82
|
+
|
|
83
|
+
The 8 layers run in fixed order. Each layer has a dedicated reference under `references/`.
|
|
84
|
+
|
|
85
|
+
### Layer Summary Table
|
|
86
|
+
|
|
87
|
+
| # | Layer | Mid-mode | Full-mode | Reference |
|
|
88
|
+
|---|---|---|---|---|
|
|
89
|
+
| 1 | HTTP-Headers | optional | always | layer-1-headers.md |
|
|
90
|
+
| 2 | HTML-Live-Probe | always | always | layer-2-html.md |
|
|
91
|
+
| 3 | Impressum | always | always | layer-3-impressum.md |
|
|
92
|
+
| 4 | DSE (Datenschutzerklärung) | always | always | layer-4-dse.md |
|
|
93
|
+
| 5 | Cookie + Consent | always | always | layer-5-cookie.md |
|
|
94
|
+
| 6 | Branche-Specific | optional | always | layer-6-branche.md |
|
|
95
|
+
| 7 | Code-Cross-Check (when local repo) | full only | always | layer-7-code-cross-check.md |
|
|
96
|
+
| 8 | Schadens-Diagnose (Synthesizer) | always | always | layer-8-schadens-diagnose.md |
|
|
97
|
+
|
|
98
|
+
### Phase 1: Pre-Audit Setup
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Verify target is reachable
|
|
102
|
+
curl -sf -o /dev/null -w "%{http_code}\n" "$TARGET"
|
|
103
|
+
# Expected: 200 / 301 / 302; otherwise abort with NO-RESPONSE finding
|
|
104
|
+
|
|
105
|
+
# Verify Playwright is available (for Layer 2 + Layer 5 deeper probes)
|
|
106
|
+
npx playwright --version
|
|
107
|
+
# If missing: STOP, ask operator to `npx playwright install chromium`
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Phase 2: Layer Execution (1 → 8)
|
|
111
|
+
|
|
112
|
+
For each enabled layer (per --mode):
|
|
113
|
+
|
|
114
|
+
1. Read the layer-reference for the patterns + thresholds.
|
|
115
|
+
2. Execute the probe(s).
|
|
116
|
+
3. Capture findings into the structured findings-list with:
|
|
117
|
+
- `id`: stable identifier (e.g., `L3-IMPRESSUM-VAT-MISSING`)
|
|
118
|
+
- `severity`: KRITISCH | HOCH | MITTEL | LOW
|
|
119
|
+
- `evidence`: the raw observation (URL + HTTP status + HTML snippet + curl output)
|
|
120
|
+
- `recommendation`: the fix
|
|
121
|
+
- `citation`: legal-source (Art. paragraph + court-decision when available)
|
|
122
|
+
|
|
123
|
+
### Phase 3: Cross-Correlation
|
|
124
|
+
|
|
125
|
+
After all layers run, run the cross-correlation pass:
|
|
126
|
+
|
|
127
|
+
- Layer 3 + Layer 5 cluster: Impressum-incomplete + cookie-pre-consent → composite KRITISCH (€5-15k abmahn)
|
|
128
|
+
- Layer 4 + Layer 5 cluster: DSE-incomplete + tracker-active → composite KRITISCH
|
|
129
|
+
- Layer 1 + Layer 7 cluster: missing CSP + unsafe-eval in code → composite HOCH
|
|
130
|
+
- Layer 6 + Layer 3 cluster: industry-specific pflichtangabe + impressum-missing → composite KRITISCH
|
|
131
|
+
|
|
132
|
+
Cross-correlation often elevates 3 individual MITTEL findings to a single composite KRITISCH — the actual abmahn-target.
|
|
133
|
+
|
|
134
|
+
### Phase 4: Report Generation (Layer 8 — Schadens-Diagnose)
|
|
135
|
+
|
|
136
|
+
Produce the 4-section report per the canonical template (see `references/layer-8-schadens-diagnose.md`):
|
|
137
|
+
|
|
138
|
+
1. **Schadens-Diagnose** — top-level summary + €-range estimate
|
|
139
|
+
2. **Findings-Tabelle** — detailed per-finding (severity / layer / evidence / fix / citation)
|
|
140
|
+
3. **Anwalts-Anhang** — legal citations (Art. paragraph + court-decisions)
|
|
141
|
+
4. **Abmahn-Simulation** — likelihood × industry × visibility = probable cost-range
|
|
142
|
+
|
|
143
|
+
### Phase 5: Output
|
|
144
|
+
|
|
145
|
+
Write the report to:
|
|
146
|
+
|
|
147
|
+
- `customers/<slug>/audits/<mode>-<date>.md` (when invoked from customer-build)
|
|
148
|
+
- `audits/<mode>-<date>.md` (when invoked standalone)
|
|
149
|
+
- stdout summary (1-line per finding) + path to full report
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Verification / Success Criteria
|
|
154
|
+
|
|
155
|
+
Before declaring the audit complete:
|
|
156
|
+
|
|
157
|
+
- [ ] All enabled layers executed (no silent-skip)
|
|
158
|
+
- [ ] Each layer's findings captured with full evidence (no hand-wavy "looks bad")
|
|
159
|
+
- [ ] Cross-correlation pass run after all layers
|
|
160
|
+
- [ ] Schadens-Diagnose €-range computed via Layer 8 formula
|
|
161
|
+
- [ ] 4-section report written + stdout summary printed
|
|
162
|
+
- [ ] No KRITISCH finding without a citation
|
|
163
|
+
- [ ] No HOCH finding without a fix-recommendation
|
|
164
|
+
- [ ] No "TODO" or placeholder text in the final report
|
|
165
|
+
|
|
166
|
+
If any unmet → audit is incomplete. Re-run failing layers + regenerate report.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Anti-Patterns
|
|
171
|
+
|
|
172
|
+
- ❌ Skipping a layer "because it doesn't apply to this target" — every layer applies; if none apply, report NOT-APPLICABLE in the layer-section, don't omit.
|
|
173
|
+
- ❌ Mocking HTTP-responses — every probe hits real target.
|
|
174
|
+
- ❌ Inferring findings from chat-context — read the raw output, cite line/byte.
|
|
175
|
+
- ❌ Hand-wavy severities — every severity has a defined criteria (per layer-reference); apply consistently.
|
|
176
|
+
- ❌ Composite findings without explicit cross-correlation logic — Phase 3 is mandatory.
|
|
177
|
+
- ❌ €-range without disclaimer — "Estimates are advisory; not legal advice. Verify with a Fachanwalt."
|
|
178
|
+
- ❌ Skipping Layer 8 (Schadens-Diagnose) "because no findings exist" — Layer 8 still produces a report stating "0 findings, low €-risk".
|
|
179
|
+
- ❌ Out-of-order layer execution — Layer 5 (cookie) needs Layer 1 (headers) data; running L5 before L1 misses signals.
|
|
180
|
+
- ❌ False-positive on a 3rd-party-CDN that's actually 1st-party-CNAME-aliased — verify via `dig CNAME` before reporting.
|
|
181
|
+
- ❌ Missing citation for KRITISCH — no Art./§/court-decision = downgrade to HOCH at most.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Extension Points
|
|
186
|
+
|
|
187
|
+
- **New layer**: add `references/layer-9-<name>.md` + add to the Layer Summary Table here. Phase 2 reads the layer-references list dynamically.
|
|
188
|
+
- **Industry-specific Layer 6**: per industry (legal, medical, financial, ...) extend `references/layer-6-branche.md` with industry-section. Phase 2 detects industry from the target's NAICS/WZ-code (or briefing.industry field).
|
|
189
|
+
- **Custom severity thresholds**: a project might want stricter KRITISCH thresholds. Override in `aegis.config.json` `audit.severities.kritisch.threshold` per layer.
|
|
190
|
+
- **Different target-types**: this skill audits a URL by default. Extend with `--mode=local-repo` (audits source-code without running build) or `--mode=tarball` (audits a published artifact) by adding probe-implementations per layer.
|
|
191
|
+
- **Multi-language support**: for non-DE/EU jurisdictions, add `references/layer-<N>-<jurisdiction>.md` (e.g., layer-3-impressum-uk.md for UK pflichtangaben). Layer 2 (HTML), Layer 1 (Headers), Layer 7 (Code) are jurisdiction-agnostic and reused.
|
|
192
|
+
- **Output format**: the 4-section format is canonical. Extension-formats (HTML / SARIF / JSON) live in `packages/reporters` and consume the audit's structured findings-list.
|
|
193
|
+
- **Continuous audit**: a project can run aegis-audit on every commit (CI integration) or on every URL-change (production-watch). Add `--mode=ci` (fast, layer 1+2+3+5 only) and `--mode=watch` (Layer 1+2+5).
|
|
194
|
+
- **Whitelisted-finding suppression**: some findings are project-accepted (e.g., a CSP `unsafe-inline` for a specific 3rd-party script). Add to `aegis.config.json` `audit.suppressions[]` with `id` + `rationale` + `expiry-date`. Suppressions expire by default (no permanent suppressions).
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Layer 1 Reference — HTTP-Headers
|
|
2
|
+
|
|
3
|
+
Layer 1 probes HTTP response-headers for security + privacy + caching headers. Findings here often feed Layer 5 (Cookie) + Layer 7 (Code-Cross-Check). **Time:** ~2-5 min per target.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Probe Pattern
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Capture headers (HEAD + GET; some servers strip security headers on HEAD)
|
|
11
|
+
curl -sI "$TARGET" > /tmp/audit-headers-head.txt
|
|
12
|
+
curl -s -I -X GET "$TARGET" > /tmp/audit-headers-get.txt
|
|
13
|
+
|
|
14
|
+
# Compare (some sites send different headers per method)
|
|
15
|
+
diff /tmp/audit-headers-head.txt /tmp/audit-headers-get.txt
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Then check each canonical header per the table below.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Canonical Header Checklist
|
|
23
|
+
|
|
24
|
+
| Header | Expected | Severity if missing/weak |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `Strict-Transport-Security` | `max-age=31536000; includeSubDomains; preload` | HOCH (missing) / MITTEL (max-age < 31536000) |
|
|
27
|
+
| `Content-Security-Policy` | strict (no `unsafe-inline` on `script-src`, no `*` on `frame-ancestors`) | KRITISCH (missing) / HOCH (`unsafe-inline`) |
|
|
28
|
+
| `X-Frame-Options` | `DENY` or `SAMEORIGIN` (or via CSP `frame-ancestors`) | HOCH (missing — clickjacking) |
|
|
29
|
+
| `X-Content-Type-Options` | `nosniff` | MITTEL (missing — MIME-sniffing) |
|
|
30
|
+
| `Referrer-Policy` | `strict-origin-when-cross-origin` or stricter | MITTEL (missing) / LOW (`unsafe-url`) |
|
|
31
|
+
| `Permissions-Policy` | scoped (no `*` defaults) | MITTEL (missing) |
|
|
32
|
+
| `Cross-Origin-Opener-Policy` | `same-origin` | LOW (missing) |
|
|
33
|
+
| `Cross-Origin-Embedder-Policy` | `require-corp` (when applicable) | LOW (missing — only for sensitive sites) |
|
|
34
|
+
| `Cross-Origin-Resource-Policy` | `same-origin` or `same-site` | LOW (missing) |
|
|
35
|
+
| `Cache-Control` (HTML) | `no-store, no-cache, must-revalidate` for auth-pages; `public, max-age=...` for static | MITTEL (auth-page cached) |
|
|
36
|
+
| `Set-Cookie` (auth) | `Secure; HttpOnly; SameSite=Lax` (or `Strict`) | KRITISCH (auth-cookie without HttpOnly) |
|
|
37
|
+
| `Server` | absent or generic (no version-disclosure) | LOW (verbose server-header) |
|
|
38
|
+
| `X-Powered-By` | absent | LOW (verbose framework-disclosure) |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## CSP Strictness Check
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
csp=$(grep -i "content-security-policy" /tmp/audit-headers-get.txt | cut -d: -f2-)
|
|
46
|
+
echo "$csp"
|
|
47
|
+
|
|
48
|
+
# Check for KRITISCH/HOCH patterns
|
|
49
|
+
grep -q "unsafe-inline" <<<"$csp" && echo "L1-CSP-UNSAFE-INLINE: HOCH"
|
|
50
|
+
grep -q "unsafe-eval" <<<"$csp" && echo "L1-CSP-UNSAFE-EVAL: HOCH"
|
|
51
|
+
grep -q "frame-ancestors[^;]*\*" <<<"$csp" && echo "L1-CSP-FRAME-ANCESTORS-WILDCARD: KRITISCH"
|
|
52
|
+
grep -q "default-src[^;]*\*" <<<"$csp" && echo "L1-CSP-DEFAULT-SRC-WILDCARD: KRITISCH"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Strictest CSP pattern (next.js with strict-dynamic + nonce):
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
default-src 'self';
|
|
59
|
+
script-src 'self' 'nonce-<hash>' 'strict-dynamic' https:;
|
|
60
|
+
style-src 'self' 'unsafe-inline';
|
|
61
|
+
img-src 'self' data: https:;
|
|
62
|
+
connect-src 'self';
|
|
63
|
+
frame-ancestors 'none';
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`style-src 'unsafe-inline'` is acceptable (CSS injection has lower exploitation impact than JS injection); `script-src 'unsafe-inline'` is not.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## HSTS Preload Check
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# If max-age < 31536000 OR missing includeSubDomains OR missing preload — not preload-eligible
|
|
74
|
+
hsts=$(grep -i "strict-transport-security" /tmp/audit-headers-get.txt | cut -d: -f2-)
|
|
75
|
+
max_age=$(grep -oE "max-age=[0-9]+" <<<"$hsts" | cut -d= -f2)
|
|
76
|
+
[ -z "$max_age" ] && echo "L1-HSTS-MISSING: HOCH"
|
|
77
|
+
[ -n "$max_age" ] && [ "$max_age" -lt 31536000 ] && echo "L1-HSTS-TOO-SHORT: MITTEL"
|
|
78
|
+
grep -qi "includesubdomains" <<<"$hsts" || echo "L1-HSTS-NO-SUBDOMAINS: MITTEL"
|
|
79
|
+
grep -qi "preload" <<<"$hsts" || echo "L1-HSTS-NO-PRELOAD: LOW"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
For preload-list eligibility, also verify:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# At https://hstspreload.org/ — site must:
|
|
86
|
+
# - Serve HSTS header on root domain + all subdomains
|
|
87
|
+
# - max-age >= 31536000 (1 year)
|
|
88
|
+
# - includeSubDomains
|
|
89
|
+
# - preload
|
|
90
|
+
# - Redirect HTTP to HTTPS on root + subdomains
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Cookie Header Cross-Check (feeds Layer 5)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Capture all Set-Cookie lines
|
|
99
|
+
grep -i "^set-cookie:" /tmp/audit-headers-get.txt
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
For each cookie, check:
|
|
103
|
+
|
|
104
|
+
- `Secure` flag set (only sent over HTTPS)
|
|
105
|
+
- `HttpOnly` flag set (no JS-access; KRITISCH if missing on auth-cookie)
|
|
106
|
+
- `SameSite` set (`Lax` or `Strict`; `None` requires `Secure`)
|
|
107
|
+
- `Path=/` reasonable scope
|
|
108
|
+
- `Max-Age` or `Expires` set (no session-cookies for tracking that should be persistent)
|
|
109
|
+
|
|
110
|
+
Layer 5 (Cookie + Consent) cross-references each cookie against the consent-status: any tracking-cookie set BEFORE consent is a TTDSG/TDDDG §25 violation.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Findings Format
|
|
115
|
+
|
|
116
|
+
Each Layer 1 finding writes to the structured findings-list:
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
- id: L1-CSP-UNSAFE-INLINE
|
|
120
|
+
layer: 1
|
|
121
|
+
severity: HOCH
|
|
122
|
+
evidence:
|
|
123
|
+
url: <target>
|
|
124
|
+
header_name: Content-Security-Policy
|
|
125
|
+
header_value: "default-src 'self'; script-src 'self' 'unsafe-inline' ..."
|
|
126
|
+
recommendation: "Replace 'unsafe-inline' with nonce-based CSP per OWASP CSP-3 cheatsheet"
|
|
127
|
+
citation: "OWASP CSP-3, BSI TR-03116-4 §4.2"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Anti-Patterns specific to Layer 1
|
|
133
|
+
|
|
134
|
+
- ❌ Reporting "HSTS missing" when site is HTTP-only — first fix HTTP-to-HTTPS redirect; HSTS is moot otherwise.
|
|
135
|
+
- ❌ Reporting "CSP unsafe-inline" without checking if the inline is `style-src` — script-src is the dangerous one; style-src is acceptable.
|
|
136
|
+
- ❌ Skipping cookie-headers — they feed Layer 5; Layer 5 then fails to detect pre-consent trackers.
|
|
137
|
+
- ❌ HEAD-only probe — some sites strip security-headers on HEAD; always run GET too.
|
|
138
|
+
- ❌ Reporting "X-XSS-Protection missing" — that header is deprecated (no longer recommended; modern CSP supersedes).
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Layer 2 Reference — HTML-Live-Probe
|
|
2
|
+
|
|
3
|
+
Layer 2 fetches the rendered HTML and analyzes structural + content patterns. Catches: missing alt-texts, broken meta-tags, SSR-skeleton-only pages, inline-script-leaks, missing footer/legal links. **Time:** ~3-5 min per target.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Probe Pattern
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Static fetch (curl)
|
|
11
|
+
curl -sL -A "Mozilla/5.0 (compatible; aegis-audit/1.0)" "$TARGET" > /tmp/audit-html-static.html
|
|
12
|
+
|
|
13
|
+
# Dynamic fetch (Playwright — captures JS-rendered content)
|
|
14
|
+
npx -y playwright-core@latest <<EOF
|
|
15
|
+
const { chromium } = require('playwright-core');
|
|
16
|
+
(async () => {
|
|
17
|
+
const b = await chromium.launch();
|
|
18
|
+
const ctx = await b.newContext({ userAgent: 'aegis-audit/1.0' });
|
|
19
|
+
const p = await ctx.newPage();
|
|
20
|
+
await p.goto('$TARGET', { waitUntil: 'networkidle', timeout: 30000 });
|
|
21
|
+
console.log(await p.content());
|
|
22
|
+
await b.close();
|
|
23
|
+
})();
|
|
24
|
+
EOF > /tmp/audit-html-dynamic.html
|
|
25
|
+
|
|
26
|
+
# Diff — large diff = heavy client-rendering (SSR/CSR balance check)
|
|
27
|
+
wc -l /tmp/audit-html-*.html
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Structural Checklist
|
|
33
|
+
|
|
34
|
+
| Check | How | Severity |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `<!doctype html>` present | `head -1 audit-html-static.html` | HOCH (missing) |
|
|
37
|
+
| `<html lang="...">` set | `grep -oE '<html[^>]*lang=' audit-html-static.html` | MITTEL (missing) |
|
|
38
|
+
| `<title>` present + non-empty + < 60 chars | `grep -oE '<title>[^<]*</title>'` | HOCH (missing or empty) |
|
|
39
|
+
| `<meta charset="utf-8">` | `grep -oE '<meta[^>]*charset=' audit-html-static.html \| head -1` | MITTEL (missing) |
|
|
40
|
+
| `<meta name="viewport">` | `grep -oE '<meta[^>]*viewport='` | HOCH (missing — mobile broken) |
|
|
41
|
+
| `<meta name="description">` | `grep -oE '<meta[^>]*description='` | HOCH (missing) |
|
|
42
|
+
| Heading-hierarchy (one h1, h2 → h3 ordering) | parse + check | MITTEL (multiple h1) / LOW (skip h2 → h3) |
|
|
43
|
+
| Open-Graph tags (og:title, og:description, og:image, og:url) | `grep -E 'og:(title\|description\|image\|url)'` | MITTEL (missing) |
|
|
44
|
+
| Twitter card tags | `grep -E 'twitter:card'` | LOW (missing) |
|
|
45
|
+
| Schema.org JSON-LD | `grep -oE 'application/ld\+json'` | LOW (missing) |
|
|
46
|
+
| Canonical link | `grep -oE 'rel="canonical"'` | MITTEL (missing) |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Image Checks (alt-text, lazy-load, dimensions)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Find all img tags
|
|
54
|
+
grep -oE '<img[^>]*>' /tmp/audit-html-static.html > /tmp/audit-imgs.txt
|
|
55
|
+
|
|
56
|
+
# Count
|
|
57
|
+
total=$(wc -l < /tmp/audit-imgs.txt)
|
|
58
|
+
|
|
59
|
+
# Missing alt-text
|
|
60
|
+
missing_alt=$(grep -cv 'alt=' /tmp/audit-imgs.txt)
|
|
61
|
+
empty_alt=$(grep -c 'alt=""' /tmp/audit-imgs.txt)
|
|
62
|
+
|
|
63
|
+
# Missing dimensions (CLS issue)
|
|
64
|
+
missing_dim=$(grep -cE 'width=' /tmp/audit-imgs.txt | head -1)
|
|
65
|
+
|
|
66
|
+
echo "Images: $total, missing alt: $missing_alt, empty alt: $empty_alt"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| Check | Severity |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Image without `alt=` | HOCH (A11y violation) |
|
|
72
|
+
| Image with `alt=""` (and not decorative-only) | MITTEL (A11y) |
|
|
73
|
+
| Image without `width` + `height` (causes CLS) | MITTEL |
|
|
74
|
+
| Image without `loading="lazy"` (below fold) | LOW (perf) |
|
|
75
|
+
| Image larger than render-size (e.g., 4000px-image rendered at 800px) | MITTEL (perf) |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## SSR-Skeleton Detection
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Static HTML body length vs dynamic
|
|
83
|
+
static_body_len=$(grep -oE '<body[^>]*>.*</body>' /tmp/audit-html-static.html | wc -c)
|
|
84
|
+
dynamic_body_len=$(grep -oE '<body[^>]*>.*</body>' /tmp/audit-html-dynamic.html | wc -c)
|
|
85
|
+
|
|
86
|
+
# If static body is < 20% of dynamic body — SSR-skeleton (SEO-bad)
|
|
87
|
+
ratio=$(echo "scale=2; $static_body_len / $dynamic_body_len" | bc)
|
|
88
|
+
[ $(echo "$ratio < 0.2" | bc) = 1 ] && echo "L2-SSR-SKELETON-ONLY: HOCH"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For Next.js App Router: SSR-skeleton + heavy client-side rendering = SEO penalty. Phase 2 architecture decisions should favor RSC.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Inline-Script Detection (CSP cross-check)
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Count inline scripts (no src attr)
|
|
99
|
+
inline_count=$(grep -oE '<script[^s]*>' /tmp/audit-html-static.html | wc -l)
|
|
100
|
+
|
|
101
|
+
# Big inline scripts may indicate injected analytics or unsafe-inline patterns
|
|
102
|
+
grep -oE '<script[^s][^>]*>[^<]{100,}' /tmp/audit-html-static.html | head -5
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If inline-scripts found AND Layer 1 CSP allows `'unsafe-inline'` on `script-src` → composite HOCH.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Footer-Link Resolution (feeds Layer 3)
|
|
110
|
+
|
|
111
|
+
Layer 3 (Impressum) needs the footer-link to /impressum. Resolve via:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Find footer
|
|
115
|
+
footer=$(grep -oE '<footer[^>]*>.*</footer>' /tmp/audit-html-static.html | head -1)
|
|
116
|
+
|
|
117
|
+
# Find links in footer
|
|
118
|
+
echo "$footer" | grep -oE '<a[^>]*href="[^"]*"[^>]*>[^<]*</a>'
|
|
119
|
+
|
|
120
|
+
# Extract the impressum-href
|
|
121
|
+
echo "$footer" | grep -oE 'href="[^"]*impressum[^"]*"' | head -1
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
If no `/impressum` link in footer or in main-nav — Layer 3 reports L3-IMPRESSUM-NO-FOOTER-LINK: HOCH.
|
|
125
|
+
|
|
126
|
+
If link exists but points to 404 — Layer 3 reports L3-IMPRESSUM-LINK-BROKEN: KRITISCH.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Findings Format
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
- id: L2-IMG-MISSING-ALT
|
|
134
|
+
layer: 2
|
|
135
|
+
severity: HOCH
|
|
136
|
+
evidence:
|
|
137
|
+
url: <target>
|
|
138
|
+
img_count: 14
|
|
139
|
+
missing_alt: 3
|
|
140
|
+
affected: ["img[1]", "img[7]", "img[12]"] # XPath-ish
|
|
141
|
+
recommendation: "Add meaningful alt-text to each img per WCAG 2.1 1.1.1"
|
|
142
|
+
citation: "WCAG 2.1 1.1.1, BFSG §3"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Anti-Patterns specific to Layer 2
|
|
148
|
+
|
|
149
|
+
- ❌ Skipping Playwright fetch "because curl is faster" — JS-rendered content invisible to curl-only.
|
|
150
|
+
- ❌ Reporting "no h1" without parsing — DOM-order matters; first h1 might be inside a `<header role="banner">`.
|
|
151
|
+
- ❌ Marking `alt=""` as KRITISCH — empty alt is correct for purely-decorative images per WCAG; downgrade.
|
|
152
|
+
- ❌ Reporting "missing OG-tags" for an internal admin-page — admin-pages don't need OG.
|
|
153
|
+
- ❌ Inferring SSR-skeleton from static-body length alone — also check if `<noscript>` content fills the gap.
|