Skip to content

refactor(skills): introduce Thinking/ and Security/ category hierarchy [PR-03]#70

Merged
Steffen025 merged 6 commits intomainfrom
release/v3.0-pr03-skills-thinking-security
Mar 15, 2026
Merged

refactor(skills): introduce Thinking/ and Security/ category hierarchy [PR-03]#70
Steffen025 merged 6 commits intomainfrom
release/v3.0-pr03-skills-thinking-security

Conversation

@Steffen025
Copy link
Owner

@Steffen025 Steffen025 commented Mar 14, 2026

Summary

Part of PAI-OpenCode v3.0 finalization epic (WARNEX-77). Introduces two new skill category hierarchies by reorganizing flat skill directories.

What this PR contains

143 files (2 ADD + 141 RENAME)

New: .opencode/skills/Thinking/

From To
skills/BeCreative/ skills/Thinking/BeCreative/
skills/Council/ skills/Thinking/Council/
skills/FirstPrinciples/ skills/Thinking/FirstPrinciples/
skills/IterativeDepth/ skills/Thinking/IterativeDepth/
skills/RedTeam/ skills/Thinking/RedTeam/
skills/Science/ skills/Thinking/Science/
skills/WorldThreatModelHarness/ skills/Thinking/WorldThreatModelHarness/
(new) skills/Thinking/SKILL.md

New: .opencode/skills/Security/

From To
skills/AnnualReports/ skills/Security/AnnualReports/
skills/PromptInjection/ skills/Security/PromptInjection/
skills/Recon/ skills/Security/Recon/
skills/SECUpdates/ skills/Security/SECUpdates/
skills/WebAssessment/ skills/Security/WebAssessment/
(new) skills/Security/SKILL.md

⚠️ Important Dependency

PR-10 (WARNEX-84 — deletions of old flat paths) must merge AFTER this PR.
The old flat paths still exist on main as duplicates until PR-10 cleans them up.

CodeRabbit Focus

Review für Korrektheit, OpenCode-Konformität, und verbleibende Claude→OpenCode Probleme

Summary by CodeRabbit

  • New Features

    • Neue Security‑Skills: AnnualReports, PromptInjection, Recon, SECUpdates, WebAssessment
    • Bug‑Bounty‑Tracker mit CLI (init/update/show/recon) und integrierten Program‑Workflows
    • Neue reconnaissance‑ und pentest‑Tools: CIDR/IP utilities, DNS & WHOIS analysis, IPInfo client, mass/port/path scanning, subdomain/endpoint discovery, corporate‑structure lookup, report fetcher/listing
  • Documentation

    • Umfangreiche Handbücher, Quickstarts, Workflows, Beispiele und CLI‑Anleitungen für alle Skills und Tools (Methodiken, Reporting, Ethics)

Move 7 thinking skills under Thinking/ category:
- BeCreative, Council, FirstPrinciples, IterativeDepth
- RedTeam, Science, WorldThreatModelHarness

Move 5 security skills under Security/ category:
- AnnualReports, PromptInjection, Recon
- SECUpdates, WebAssessment

Add category SKILL.md index files for both new categories.
143 files total (2 ADD + 141 RENAME).

Part of PAI-OpenCode v3.0 finalization (WARNEX-77).
NOTE: PR-10 (deletions of old flat paths) must merge AFTER this PR.
@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Dieser PR fügt zahlreiche neue Security‑Skills, Tools und umfangreiche Dokumentation hinzu: AnnualReports‑CLI/Datendatei, ein Bug‑Bounty‑Tracker mit GitHub‑Integration, viele Recon‑Utilities (CIDR/DNS/WHOIS/IPInfo/Endpoint/Port/Mass/Path/Subdomain), WebAssessment‑Hilfen und umfassende PromptInjection/Recon/SECUpdates‑Workflows und Handbücher.

Changes

Cohort / File(s) Summary
AnnualReports Skill
.opencode/skills/Security/AnnualReports/SKILL.md, .opencode/skills/Security/AnnualReports/Data/sources.json, .opencode/skills/Security/AnnualReports/Tools/FetchReport.ts, .opencode/skills/Security/AnnualReports/Tools/ListSources.ts, .opencode/skills/Security/AnnualReports/Tools/UpdateSources.ts
Neuer Skill: Quellen‑JSON und drei CLI‑Tools zum Synchronisieren, Auflisten und Abrufen/„Summarizen“ von Reports. Prüfen: HTTP‑Fetch, HTML→Text‑Extraction, PDF‑Handling, Pfad‑Sanitization und Dateischreibrechte.
PromptInjection — Docs & Workflows
.opencode/skills/Security/PromptInjection/...
Große Sammlung neuer Dokumente (Taxonomie, Recon‑Methoden, Tests, Verteidigungen, Reporting, Workflows). Prüfen: Konsistenz von Autorisierungs‑/Ethik‑Hinweisen und interne Verlinkungen.
Recon — Docs & Workflows
.opencode/skills/Security/Recon/README.md, .opencode/skills/Security/Recon/SKILL.md, .opencode/skills/Security/Recon/Workflows/*
Umfangreiche Recon‑Dokumentation mit Workflows (Passive/Domain/Ip/Netblock/Bounty/UpdateTools/Analyse). Prüfen: Trigger, Autorisierungshinweise und Pfadreferenzen.
Recon Tools — Core Utilities
.opencode/skills/Security/Recon/Tools/CidrUtils.ts, .opencode/skills/Security/Recon/Tools/DnsUtils.ts, .opencode/skills/Security/Recon/Tools/IpinfoClient.ts, .opencode/skills/Security/Recon/Tools/WhoisParser.ts, .opencode/skills/Security/Recon/Tools/CorporateStructure.ts, .opencode/skills/Security/Recon/Tools/BountyPrograms.ts
Neue TypeScript‑Module mit exportierten Schnittstellen/APIs (CIDR, DNS, IPInfo, WHOIS, Corporate, Bounty). Prüfen: Export‑Signaturen, API‑Key‑Handling, Cache‑TTL, Fehlerpfade und Tests.
Recon Tools — Scanning & Discovery
.opencode/skills/Security/Recon/Tools/PortScan.ts, .opencode/skills/Security/Recon/Tools/MassScan.ts, .opencode/skills/Security/Recon/Tools/PathDiscovery.ts, .opencode/skills/Security/Recon/Tools/SubdomainEnum.ts, .opencode/skills/Security/Recon/Tools/EndpointDiscovery.ts
Wrappers um externe Scanner (naabu, masscan, ffuf, subfinder, Katana) plus Endpoint‑/Secret‑Extraction. Prüfen: Prozess‑Spawns, Root/Privileg‑Checks, JSON‑Parsing, Zeitlimits und sichere Ausgabe.
WebAssessment — BugBountyTool
.opencode/skills/Security/WebAssessment/BugBountyTool/package.json, .opencode/skills/Security/WebAssessment/BugBountyTool/bounty.sh, .opencode/skills/Security/WebAssessment/BugBountyTool/src/*, .opencode/skills/Security/WebAssessment/BugBountyTool/state.json
Neues zweistufiges Tracing: GitHubClient, StateManager, BugBountyTracker, CLI‑Entrypoints, Recon‑Generator, Persistenz/JSONL‑Logs. Prüfen: GitHub‑API‑Aufrufe, SHA‑Tracking, State‑Migration, Fehlerbehandlung und Schreibrechte.
WebAssessment — OSINT & FFUF Resources
.opencode/skills/Security/WebAssessment/OsintTools/*, .opencode/skills/Security/WebAssessment/FfufResources/*
Neue Dokumentation zu OSINT‑Integrationen (Shodan, Dehashed, etc.) und FFUF‑Vorlagen/Wortlisten/Request‑Templates. Prüfen: Beispielbefehle, Auth‑Hinweise und Pfadreferenzen.
SECUpdates Skill
.opencode/skills/Security/SECUpdates/SKILL.md, .opencode/skills/Security/SECUpdates/Workflows/Update.md, .opencode/skills/Security/SECUpdates/sources.json
News/Research/Ideas‑Aggregator mit Quellenliste und State‑Konzept (State/last-check.json). Prüfen: Quellen‑URLs, Initialisierungsflow und Deduplizierungslogik.
Security category overview
.opencode/skills/Security/SKILL.md
Kategorie‑Übersicht für Security‑Skills und Customization‑Hook. Prüfen: Pfad‑/Namen‑Konsistenz.
Misc (scripts/configs/docs)
diverse README/MDs, .opencode/skills/Security/WebAssessment/BugBountyTool/package.json
Verschiedene Hilfs‑/Konfigurationsdateien und Dokumentation. Prüfen: package.json‑Scripte, Shebangs, und relative Pfadkonsistenz.

Sequence Diagram(s)

sequenceDiagram
  participant Tracker as BugBountyTracker
  participant GH as GitHub API
  participant State as StateManager (local)
  participant FS as Filesystem

  Tracker->>GH: fetch commits / fetch files (domains.txt)
  GH-->>Tracker: commit SHAs / file contents
  Tracker->>State: loadState()
  State-->>Tracker: last_check, tracked_commits
  Tracker->>Tracker: analyze diffs (Tier1 → maybe Tier2)
  alt Tier2 required
    Tracker->>GH: fetch program files / diffs
    GH-->>Tracker: program data
  end
  Tracker->>State: saveMetadata(), saveState(), logDiscovery()
  State->>FS: write state.json, metadata, JSONL logs
  Tracker->>FS: write recon config (recon/*.json)
  FS-->>Tracker: path to generated recon config
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 Minuten

Possibly related PRs

Poem

🐇
Ich hopp­le leis’ durchs Repo‑Moos,
bring’ Tools, Docs, und einen großen Schoß.
Recon und Bounty, Quellen klar,
Reports im Nest — nun wunderbar.
Hüpft froh das Kaninchen, Code ist da.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der Titel bezieht sich direkt auf die Hauptänderung: Einführung einer Kategoriehierarchie für Thinking/ und Security/ Skills, was genau dem Inhalt des Pull Requests entspricht.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release/v3.0-pr03-skills-thinking-security
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.opencode/skills/Security/PromptInjection/SKILL.md (1)

310-313: ⚠️ Potential issue | 🟠 Major

Veraltete Pfade nach Hierarchie-Refactor

Die Referenzen zeigen noch auf ~/.opencode/skills/PromptInjection/... statt auf den neuen Security/PromptInjection-Pfad.

Vorgeschlagener Fix
-`~/.opencode/skills/PromptInjection/COMPREHENSIVE-ATTACK-TAXONOMY.md` (Section 5)
+`~/.opencode/skills/Security/PromptInjection/COMPREHENSIVE-ATTACK-TAXONOMY.md` (Section 5)

-`~/.opencode/skills/PromptInjection/attack-payloads/multi-stage/`
+`~/.opencode/skills/Security/PromptInjection/attack-payloads/multi-stage/`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/PromptInjection/SKILL.md around lines 310 - 313,
Update all outdated path references that still point to
"~/.opencode/skills/PromptInjection/..." so they use the new hierarchy
"Security/PromptInjection/..." instead: search the SKILL.md content for the
exact string "~/.opencode/skills/PromptInjection" (and any variants like
"~/.opencode/skills/PromptInjection/...") and replace them with
"Security/PromptInjection" (or "Security/PromptInjection/..." for subpaths), and
verify any Markdown links, examples, or code snippets referencing that old path
are adjusted accordingly.
🟡 Minor comments (20)
.opencode/skills/Security/Recon/Workflows/AnalyzeScanResultsGemini3.md-52-52 (1)

52-52: ⚠️ Potential issue | 🟡 Minor

Fehlende Sprachangaben in Code-Fences verletzen Markdown-Linting.

Mehrere Fenced Code Blocks haben kein Sprach-Tag (MD040). Bitte text, bash, json, yaml o.ä. ergänzen, damit Linting und Rendering konsistent bleiben.

Also applies to: 440-440, 451-451, 612-612, 663-663, 680-680, 699-699, 800-800, 926-926, 983-983

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Workflows/AnalyzeScanResultsGemini3.md at
line 52, Several fenced code blocks use bare triple-backticks (``` ) which
triggers MD040; update each such fence in the AnalyzeScanResultsGemini3.md
content so they include an explicit language tag (e.g., replace ``` with
```bash, ```json, ```yaml, or ```text as appropriate for the block) to satisfy
linting and ensure correct rendering; search for instances of the raw fence
marker (``` ) in the file and add the appropriate language token for the blocks
listed in the review (and any others you find).
.opencode/skills/Security/Recon/Workflows/BountyPrograms.md-29-33 (1)

29-33: ⚠️ Potential issue | 🟡 Minor

Datenquellen-Tabelle stimmt nicht mit der aktuellen Tool-Implementierung überein.

Die Tabelle nennt HackerOne und Bugcrowd als aktive Quellen, das Tool lädt derzeit aber nur die Chaos-Liste. Bitte entweder die Quellen im Tool ergänzen oder die Tabelle auf den Ist-Stand korrigieren.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Workflows/BountyPrograms.md around lines 29
- 33, The Datenquellen-Tabelle in BountyPrograms.md claims HackerOne and
Bugcrowd are sources but the implementation currently only loads the Chaos list
(chaos.projectdiscovery.io / chaos-bugbounty-list.json); either update the table
to reflect only the Chaos source or extend the tool to ingest HackerOne and
Bugcrowd. To fix, choose one: A) edit the markdown table to remove HackerOne and
Bugcrowd rows and clarify that the tool uses the ProjectDiscovery chaos list
(chaos.projectdiscovery.io / chaos-bugbounty-list.json) and update any README
references; or B) implement additional source handlers to fetch and normalize
HackerOne and Bugcrowd data (add fetch/parsers, update the data loading flow to
include these sources, and adjust any schemas/tests) and then update the table
to list all three sources.
.opencode/skills/Security/WebAssessment/BugBountyTool/README.md-88-88 (1)

88-88: ⚠️ Potential issue | 🟡 Minor

Fenced Code Blocks sollten Sprachkennungen setzen (MD040).

Mehrere Codeblöcke sind ohne Sprache markiert; das triggert markdownlint und erschwert konsistente Verarbeitung.

🔧 Vorschlag
-```
+```text
 🔍 Checking for new bug bounty programs...
 ...
-```
+```text
 📋 Bug bounty programs discovered in the last 24h
 ...
-```
+```text
 bug-bounties/
 ...

Also applies to: 127-127, 157-157

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/README.md at line 88,
Add explicit language identifiers to the fenced code blocks in README.md to
satisfy MD040: locate the three untagged triple-backtick blocks (the ones
showing "🔍 Checking for new bug bounty programs...", "📋 Bug bounty programs
discovered in the last 24h", and the "bug-bounties/" directory listing) and
change their opening fences from ``` to e.g. ```text (or ```bash/```console if
shell output) so each code block has a language tag.
.opencode/skills/Security/WebAssessment/BugBountyTool/src/show.ts-16-24 (1)

16-24: ⚠️ Potential issue | 🟡 Minor

--last sollte Eingaben validieren statt stillschweigend NaN zu akzeptieren.

Ungültige Werte führen aktuell zu unklaren/leer gefilterten Ergebnissen ohne Fehlhinweis.

🔧 Vorschlag
       if (args[i] === '--last' && args[i + 1]) {
         const value = args[i + 1];
+        let parsed: number;
         if (value.endsWith('h')) {
-          hours = parseInt(value.slice(0, -1));
+          parsed = Number.parseInt(value.slice(0, -1), 10);
         } else if (value.endsWith('d')) {
-          hours = parseInt(value.slice(0, -1)) * 24;
+          parsed = Number.parseInt(value.slice(0, -1), 10) * 24;
         } else {
-          hours = parseInt(value);
+          parsed = Number.parseInt(value, 10);
         }
+        if (!Number.isFinite(parsed) || parsed <= 0) {
+          throw new Error(`Invalid --last value: ${value}`);
+        }
+        hours = parsed;
         i++;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/show.ts around
lines 16 - 24, Beim Parsen des --last-Argumentes (code around the args[i] ===
'--last' branch that sets the variable hours) derzeit werden ungültige Eingaben
stillschweigend zu NaN akzeptiert; prüfe nach jedem parseInt-Aufruf das Ergebnis
mit isNaN and ensure it's a positive integer, und bei ungültigem Wert wirf/zeige
eine klare Fehlermeldung oder fallback auf einen Standardwert; validiere sowohl
Formate mit 'h' und 'd' als auch reine Zahlen, und aktualisiere die
Fehlerbehandlung (z.B. durch ein thrown Error oder processLogger/error output)
so dass callers wissen, wenn --last falsch angegeben wurde.
.opencode/skills/Security/WebAssessment/OsintTools/README.md-193-199 (1)

193-199: ⚠️ Potential issue | 🟡 Minor

Die unlabeled Codeblöcke verursachen die bestehenden Markdown-Lint-Warnungen.

Hier fehlt jeweils ein Sprachlabel, z. B. ini für die Konfiguration und text für den Fehlermeldungsblock.

Also applies to: 332-334

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/OsintTools/README.md around lines
193 - 199, Die unlabeled Markdown-Codeblöcke (der Block mit "[Twitter OAuth]"
und der separate Fehlermeldungsblock weiter unten) verursachen Lint-Warnungen;
behebe das, indem du den dreifachen Backticks ein Sprachlabel hinzufügst (z. B.
```ini für den Konfigurationsblock mit
"consumer_key/consumer_secret/access_token/access_secret" und ```text für den
Fehlermeldungsblock), so dass beide Codefences explizit getypt sind und der
Markdown-Linter die Blöcke korrekt behandelt.
.opencode/skills/Security/PromptInjection/Workflows/Reconnaissance.md-32-34 (1)

32-34: ⚠️ Potential issue | 🟡 Minor

Die Browser-Beispielblöcke brauchen ein Sprachlabel.

markdownlint meldet diese vier Fences bereits. Ein neutrales text reicht hier, falls das kein Shell-Code sein soll.

Also applies to: 45-47, 60-62, 75-79

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/PromptInjection/Workflows/Reconnaissance.md around
lines 32 - 34, The code fences containing the browser example lines (e.g., the
fence with "browser navigate https://target-app.com") are missing a language
label which triggers markdownlint; update those fenced code blocks to include a
language label such as "text" so they become "```text" at the start of each
block—apply this change to the snippet shown and the other similar fences
referenced (lines 45-47, 60-62, 75-79) to resolve the lint warnings.
.opencode/skills/Security/Recon/Tools/PathDiscovery.ts-248-317 (1)

248-317: ⚠️ Potential issue | 🟡 Minor

Optionen mit Pflichtwerten sollten fehlende Argumente sauber abfangen.

Mehrere Cases lesen next ungeprüft. --extensions am Ende der CLI crasht hier direkt über next.split(","), und numerische Flags können still NaN in den ffuf-Aufruf tragen. Bitte vor jedem i++ validieren und mit einer Usage-Fehlermeldung abbrechen.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/PathDiscovery.ts around lines 248 -
317, In the switch that populates options (inside PathDiscovery.ts handling
arg/next), validate that next is defined before using it for flags that require
a value (e.g., "-w"/"--wordlist", "--extensions", "-t"/"--threads", "--timeout",
"-mc"/"--match-codes", "-fc"/"--filter-codes", "-H"/"--header",
"-b"/"--cookies", "-X"/"--method", "-d"/"--data", "--proxy", "--rate",
"--recursion-depth"): if next is undefined, emit the usage/error message and
abort; for "--extensions" only call next.split(",") after confirming next is
present; for numeric flags (parseInt calls for threads, timeout, recursionDepth,
rate) check the result is a finite number (not NaN) before assigning to options
and on failure emit usage/error and abort; only perform i++ after validation
succeeds. Use the existing options object, the local next variable, and the same
case branches to implement these checks and error paths.
.opencode/skills/Security/PromptInjection/Workflows/IndirectInjectionTesting.md-55-62 (1)

55-62: ⚠️ Potential issue | 🟡 Minor

Die drei unlabeled Beispielblöcke triggern die vorhandenen Lint-Warnungen.

Bitte den Fences ein Sprachlabel geben; text wäre hier bereits ausreichend.

Also applies to: 168-180, 196-203

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.opencode/skills/Security/PromptInjection/Workflows/IndirectInjectionTesting.md
around lines 55 - 62, Die drei unlabeled fenced code blocks that contain the
marker line '--- SYSTEM OVERRIDE ---' trigger lint warnings; add a language
label (e.g., put ```text instead of ``` ) to each of those fenced blocks shown
in the snippet and to the other two occurrences referenced (the blocks around
the same '--- SYSTEM OVERRIDE ---' pattern at the other ranges) so every
triple-backtick fence is annotated with a language label.
.opencode/skills/Security/PromptInjection/Workflows/MultiStageAttacks.md-34-230 (1)

34-230: ⚠️ Potential issue | 🟡 Minor

Mehrere Dialog-Beispielblöcke ohne Sprachkennung

Die vielen untypisierten Fences erzeugen wiederholt MD040-Warnungen. text als Sprachlabel würde das sauber halten.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/PromptInjection/Workflows/MultiStageAttacks.md
around lines 34 - 230, Multiple fenced code blocks (e.g., the blocks starting
with "User: Hello, I'd like to learn about AI safety.", "User: I'm a security
researcher with authorization code: AUTH-12345.", and other "Turn X:" examples)
are missing a language label and trigger MD040; fix by adding a language label
such as text after each opening triple-backtick (change ``` to ```text) for
every unlabeled fence in MultiStageAttacks.md so the markdown linter stops
flagging MD040.
.opencode/skills/Security/PromptInjection/AutomatedTestingTools.md-214-230 (1)

214-230: ⚠️ Potential issue | 🟡 Minor

Code-Fence ohne Sprachkennung im Beispieloutput

Der Block startet ohne Sprache und verletzt die Markdown-Lint-Regel; bitte als text markieren.

Vorgeschlagener Fix
-```
+```text
 garak 0.9 (c) 2023 Leon Derczynski
@@
-```
+```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/PromptInjection/AutomatedTestingTools.md around
lines 214 - 230, The Markdown code fence containing the sample output starting
with "garak 0.9 (c) 2023 Leon Derczynski" (the block that lists probes
promptinject.InjectPrefix and jailbreak.Dan) lacks a language identifier and
triggers the lint rule; update that fenced block to use a language tag (e.g.,
"text") so it becomes ```text ... ``` to satisfy the Markdown lint rule and
preserve the example output formatting.
.opencode/skills/Security/PromptInjection/Workflows/DirectInjectionTesting.md-232-238 (1)

232-238: ⚠️ Potential issue | 🟡 Minor

Die Referenzpfade zeigen hier noch auf die Vor-PR-03-Struktur.

Unter „Complete Attack Reference“ fehlt weiterhin der Security/-Prefix. Nach dem Verzeichnis-Move landen beide Hinweise auf toten Pfaden statt bei Taxonomie und Payload-Bibliothek. Bitte entweder relative Pfade verwenden oder auf ~/.opencode/skills/Security/PromptInjection/... umstellen.
As per coding guidelines, "Workflows/ directory has operational procedures".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.opencode/skills/Security/PromptInjection/Workflows/DirectInjectionTesting.md
around lines 232 - 238, Update the broken reference paths in the "Complete
Attack Reference" section of DirectInjectionTesting.md so they point to the
moved locations: replace
`~/.opencode/skills/PromptInjection/COMPREHENSIVE-ATTACK-TAXONOMY.md` and
`~/.opencode/skills/PromptInjection/attack-payloads/direct-injection/` with
either relative paths or the new absolute paths under the Security prefix (e.g.,
`~/.opencode/skills/Security/PromptInjection/...`); ensure you only change the
two path strings in the "Complete Attack Reference" block and leave the
Workflows/ directory usage intact per guidelines.
.opencode/skills/Security/WebAssessment/OsintTools/API-TOOLS-GUIDE.md-357-368 (1)

357-368: ⚠️ Potential issue | 🟡 Minor

Beiden OSINT-Industries-Code-Beispielen fehlt import json.

Die Snippets (Zeilen 357–368 und 372–383) rufen json.dumps() auf, importieren aber nicht das json-Modul. Benutzer, die den Code unverändert übernehmen, erhalten einen NameError.

Füge import json am Anfang beider Code-Blöcke hinzu.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/OsintTools/API-TOOLS-GUIDE.md around
lines 357 - 368, The code examples using OSINTIndustriesClient call
json.dumps(...) but do not import the json module; add an import json statement
at the top of each affected snippet (both blocks that instantiate
OSINTIndustriesClient and call json.dumps) so that json is defined when
json.dumps is invoked.
.opencode/skills/Security/AnnualReports/Tools/FetchReport.ts-98-101 (1)

98-101: ⚠️ Potential issue | 🟡 Minor

Fehlerbehandlungsmuster erschwert Unterscheidung zwischen Erfolg und Fehlschlag.

fetchReportPage gibt bei Fehlern einen String zurück anstatt eine Exception zu werfen. Der Aufrufer kann nicht zwischen einem legitimen Seiteninhalt und einer Fehlermeldung unterscheiden.

🔧 Empfohlene Lösung

Entweder Exception werfen oder ein Result-Objekt verwenden:

interface FetchResult {
  success: boolean;
  content?: string;
  error?: string;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/AnnualReports/Tools/FetchReport.ts around lines 98
- 101, The catch block in fetchReportPage currently returns an error string
which makes callers unable to distinguish real content from failures; instead,
change the error handling so fetchReportPage throws an Error (e.g., throw new
Error(`Fetch failed: ${error}`)) from the catch block, or alternatively
implement and return a typed FetchResult interface ({ success: boolean;
content?: string; error?: string }) so callers can branch on success; update any
callers of fetchReportPage to expect and handle the thrown exception or the new
FetchResult shape accordingly.
.opencode/skills/Security/Recon/Workflows/IpRecon.md-244-263 (1)

244-263: ⚠️ Potential issue | 🟡 Minor

Fehlendes async Schlüsselwort bei Verwendung von await.

Die Funktion checkAuthorization verwendet await (Zeilen 249, 253), ist aber nicht als async deklariert.

🔧 Vorgeschlagene Korrektur
-function checkAuthorization(): boolean {
+async function checkAuthorization(): Promise<boolean> {
   console.log("⚠️  ACTIVE RECONNAISSANCE REQUIRES AUTHORIZATION");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Workflows/IpRecon.md around lines 244 - 263,
The function checkAuthorization uses await but isn't declared async; update the
function signature for checkAuthorization to be asynchronous (e.g., add the
async keyword) and change its return to a Promise<boolean> so callers handle the
async result; ensure usages of askUserConfirmation() and the
logAuthorizationEvent call remain inside the async function and any call sites
that expect a boolean are updated to await checkAuthorization().
.opencode/skills/Security/Recon/SKILL.md-386-388 (1)

386-388: ⚠️ Potential issue | 🟡 Minor

"Claude Code" sollte "OpenCode" sein.

Gemäß den PR-Zielen sollen verbleibende "Claude→OpenCode"-Referenzen korrigiert werden. Hier wird noch auf "Claude Code" verwiesen.

🔧 Vorgeschlagene Korrektur
 # Restart Claude Code to apply
+# Restart OpenCode to apply
-# Restart Claude Code to apply
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/SKILL.md around lines 386 - 388, Replace the
incorrect "Claude Code" reference with "OpenCode" in the SKILL.md content;
locate the exact string "Claude Code" (e.g., in the snippet showing "Restart
Claude Code to apply") and update it to "Restart OpenCode to apply" and
similarly change any other "Claude→OpenCode" remnants in this markdown so all
occurrences match the PR goal of renaming to "OpenCode".
.opencode/skills/Security/AnnualReports/Tools/FetchReport.ts-35-37 (1)

35-37: ⚠️ Potential issue | 🟡 Minor

Fehlende Fehlerbehandlung beim Laden der Quellen.

loadSources() wirft eine unverständliche Fehlermeldung, wenn sources.json nicht existiert oder ungültiges JSON enthält.

🛡️ Vorgeschlagene Verbesserung
 function loadSources(): Sources {
+  if (!existsSync(SOURCES_PATH)) {
+    throw new Error(`Sources file not found: ${SOURCES_PATH}. Run UpdateSources.ts first.`);
+  }
+  try {
     return JSON.parse(readFileSync(SOURCES_PATH, 'utf-8'));
+  } catch (error) {
+    throw new Error(`Failed to parse sources.json: ${error}`);
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/AnnualReports/Tools/FetchReport.ts around lines 35
- 37, Die Funktion loadSources() fehlt eine robuste Fehlerbehandlung beim
Lesen/parsen von SOURCES_PATH; fange Datei-/IO-Fehler und JSON.parse-Fehler ab
(try/catch um readFileSync + JSON.parse) und entweder wirf eine erklärende
Fehlermeldung mit Kontext (z. B. welchen Pfad und dass das JSON ungültig ist)
oder gib einen sinnvollen Fallback zurück (z. B. leere Sources) abhängig von der
gewünschten Laufzeitstrategie; referenziere loadSources() und SOURCES_PATH beim
Einfügen der try/catch und stelle sicher, daß die process- oder logger-Ausgabe
den ursprünglichen Fehlerinhalt beibehält.
.opencode/skills/Security/Recon/Workflows/NetblockRecon.md-104-107 (1)

104-107: ⚠️ Potential issue | 🟡 Minor

Edge-Case bei usableIPs-Berechnung nicht berücksichtigt.

usableIPs = totalIPs - 2 ist für /31 (Point-to-Point-Links mit 2 nutzbaren IPs) und /32 (Single Host mit 1 nutzbaren IP) falsch.

🔧 Vorgeschlagene Korrektur
   // Calculate total IPs
   const totalIPs = Math.pow(2, 32 - mask);
-  const usableIPs = totalIPs - 2; // Exclude network and broadcast
+  // Handle edge cases: /32 = 1 usable, /31 = 2 usable (RFC 3021)
+  const usableIPs = mask === 32 ? 1 : mask === 31 ? 2 : totalIPs - 2;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Workflows/NetblockRecon.md around lines 104
- 107, The usableIPs calculation incorrectly assumes two reserved addresses for
every mask; update the logic around the variables totalIPs, usableIPs and mask
so that: compute totalIPs = 2^(32 - mask) as before, then set usableIPs = 1 when
mask === 32, usableIPs = 2 when mask === 31, and usableIPs = Math.max(0,
totalIPs - 2) for masks <= 30 (or otherwise validate mask range) to handle edge
cases correctly; locate and modify the block that currently sets usableIPs =
totalIPs - 2 to implement this conditional assignment.
.opencode/skills/Security/AnnualReports/Tools/FetchReport.ts-203-207 (1)

203-207: ⚠️ Potential issue | 🟡 Minor

Unbehandelte Exception bei ungültiger URL.

new URL(url).pathname kann eine Exception werfen, wenn url keine gültige URL ist.

🛡️ Vorgeschlagene Korrektur
   if (args[0] === '--url' && args[1]) {
     const url = args[1];
+    let reportName: string;
+    try {
+      reportName = basename(new URL(url).pathname) || 'report';
+    } catch {
+      reportName = 'report';
+    }
     const content = await fetchReportPage(url);
 
     const report: Report = {
       vendor: 'custom',
-      name: basename(new URL(url).pathname) || 'report',
+      name: reportName,
       url
     };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/AnnualReports/Tools/FetchReport.ts around lines
203 - 207, Beim Erstellen des Report-Objekts kann new URL(url).pathname eine
Exception werfen für ungültige URLs; in der Funktion/Datei FetchReport.ts sollte
die URL-Erzeugung um eine sichere Prüfung/try-catch gewickelt werden: versuche
die URL mit new URL(url) in einem try-block zu parsen, verwende bei Erfolg
basename(parsed.pathname) und bei Fehler einen Fallback wie basename(url) oder
einen Default-Wert ('report'), und setze dann das Report-Objekt (Report,
basename, url) nur mit dem sicheren Pfad, sodass ungültige URL-Strings keine
unbehandelte Exception mehr auslösen.
.opencode/skills/Security/Recon/SKILL.md-507-508 (1)

507-508: ⚠️ Potential issue | 🟡 Minor

Großbuchstabenfehler bei WebAssessment-Pfad korrigieren.

Der Pfad auf Zeile 508 hat einen Großbuchstabenfehler: ~/.opencode/skills/Webassessment/ sollte ~/.opencode/skills/WebAssessment/ sein. Der erste Pfad ~/.opencode/skills/Investigation/OSINT/ ist korrekt und entspricht der aktuellen Verzeichnisstruktur.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/SKILL.md around lines 507 - 508, Der
Pfad-String `~/.opencode/skills/Webassessment/` enthält einen
Großbuchstabenfehler; ändere diesen Vorkommen auf
`~/.opencode/skills/WebAssessment/` so dass er mit der bestehenden
Verzeichnisstruktur übereinstimmt (vergleiche mit dem bereits korrekten
`~/.opencode/skills/Investigation/OSINT/` Eintrag).
.opencode/skills/Security/Recon/Tools/DnsUtils.ts-457-489 (1)

457-489: ⚠️ Potential issue | 🟡 Minor

Unbekannte CLI-Kommandos sollten mit Exit-Code 1 enden.

Aktuell fällt jeder Tippfehler stillschweigend durch und sieht für Automation wie ein erfolgreicher Lauf aus. Das Tool sollte in diesem Fall Usage ausgeben und fehlschlagen.

💡 Mögliche Korrektur
   if (args.length === 0) {
     console.log("Usage:");
-    console.log("  dns-utils.ts <domain>              - Get all records");
-    console.log("  dns-utils.ts <domain> email        - Email security analysis");
-    console.log("  dns-utils.ts <domain> subdomains   - Enumerate subdomains");
-    console.log("  dns-utils.ts <domain> reverse <ip> - Reverse DNS");
+    console.log("  DnsUtils.ts <domain>              - Get all records");
+    console.log("  DnsUtils.ts <domain> email        - Email security analysis");
+    console.log("  DnsUtils.ts <domain> subdomains   - Enumerate subdomains");
+    console.log("  DnsUtils.ts <domain> reverse <ip> - Reverse DNS");
     process.exit(1);
   }
@@
   } else if (command === "reverse" && args[2]) {
     const hostname = await reverseDNS(args[2]);
     console.log(hostname || "No PTR record found");
+  } else {
+    console.error("Unknown command");
+    process.exit(1);
   }
 }

As per coding guidelines, ".opencode/skills/**: Tools/ directory has CLI tools for automation".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/DnsUtils.ts around lines 457 - 489,
The CLI silently exits successfully for unknown commands; add a final else
branch after the existing command handlers (after the else if blocks handling
"email", "subdomains", and "reverse") that prints the Usage text (same lines
currently printed when args.length===0) and calls process.exit(1), and ensure
the "reverse" case without args[2] also falls through to this branch; update
handling around args, getAllRecords, analyzeEmailSecurity,
enumerateSubdomainsViaCert, enumerateCommonSubdomains and reverseDNS so any
unrecognized command results in usage output and exit code 1.
🧹 Nitpick comments (18)
.opencode/skills/Security/WebAssessment/FfufResources/REQUEST_TEMPLATES.md (1)

67-67: Base64-Credential deutlicher als Beispiel kennzeichnen.

Der Base64-String YWRtaW46cGFzc3dvcmQxMjM= dekodiert zu admin:password123. Obwohl dies offensichtlich ein Beispiel ist, könnte dies für zusätzliche Klarheit explizit markiert werden, um Missverständnisse zu vermeiden.

💡 Vorgeschlagene Verbesserung
-Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=
+Authorization: Basic [EXAMPLE_BASE64_admin:password123]

Oder einen Kommentar hinzufügen:

 Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=
+# Note: Example credential (admin:password123 in Base64)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/FfufResources/REQUEST_TEMPLATES.md
at line 67, Die Zeile "Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=" in
REQUEST_TEMPLATES.md enthält ein decodierbares Beispiel-Credential; kennzeichne
diesen Base64-String deutlich als Beispiel oder ersetze ihn durch einen klaren
Platzhalter (z. B. "Authorization: Basic <BASE64_CREDENTIAL_EXAMPLE>") und füge
optional einen kurzen Kommentar hinzu, dass der gezeigte String zu
"admin:password123" dekodiert werden kann, damit Leser nicht fälschlich
annehmen, es handle sich um echte Produktionsdaten.
.opencode/skills/Security/WebAssessment/BugBountyTool/package.json (1)

12-14: @types/node gehört in devDependencies, nicht in Runtime-Dependencies.

@types/node ist eine reine Typisierungsabhängigkeit für TypeScript und wird zur Laufzeit nicht benötigt. Eine Überprüfung des Codes bestätigt, dass @types/node nirgendwo importiert wird. Sie sollte in devDependencies verschoben werden.

Vorschlag
-  "dependencies": {
-    "@types/node": "^20.10.0"
-  }
+  "devDependencies": {
+    "@types/node": "^20.10.0"
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/package.json around
lines 12 - 14, The package.json currently lists the type-only package
"@types/node" under "dependencies"; remove the "@types/node" entry from
"dependencies" and add the same version string under "devDependencies" instead
(ensure the "devDependencies" object exists), then update the lockfile by
running the project's package manager install command so the change is
persisted.
.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts (1)

61-70: Erster update()-Lauf macht nur Initialisierung, keine Analyse.

Das ist funktional okay, aber unpraktisch: Nutzer brauchen zwei Runs für ein erstes Ergebnis. Optional direkt nach initialize() mit der eigentlichen Prüfung fortfahren.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 61 - 70, Die erste Ausführung von update() bricht nach await
this.initialize() ab und liefert keine Analyseergebnisse; ändere das Verhalten
in der Methode (prüfe currentState.initialized, rufe bei Bedarf
this.initialize() auf und fahre dann mit dem normalen Update-/Analyse-Flow fort
statt sofort return) – z.B. entferne den frühen return nach await
this.initialize(), stelle sicher, dass startTime weiterhin korrekt verwendet
wird und dass keine doppelten Initialisierungen passieren (verwende
currentState.initialized oder ein lokales Flag), damit ein Erstlauf sowohl
initialisiert als auch sofort die Prüfung durchführt und echte Ergebnisse
zurückliefert.
.opencode/skills/Security/Recon/Tools/MassScan.ts (2)

17-17: Ungenutzter Import.

Die $ Shell-Funktion wird importiert, aber im Code wird Bun.spawn verwendet. Der Import kann entfernt werden.

🧹 Vorgeschlagene Korrektur
-import { $ } from "bun";
+// No imports needed - using Bun global
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/MassScan.ts at line 17, Entferne den
ungenutzten Import "import { $ } from 'bun';" aus MassScan.ts: suche die
Importzeile, entferne sie und vergewissere dich, dass im restlichen Code (z.B.
bei der Nutzung von Bun.spawn) keine Verweise auf "$" mehr vorhanden sind; wenn
"$" nirgendwo sonst verwendet wird, kann die Importzeile sicher gelöscht.

369-377: IP-Sortierung nur für IPv4.

Die IP-Sortierlogik nimmt IPv4-Format an (4 Oktette). Bei IPv6-Adressen würde dies fehlschlagen. Da masscan auch IPv6 unterstützen kann, wäre eine robustere Sortierung sinnvoll.

♻️ Robustere IP-Sortierung
       // Sort IPs numerically
       const sortedIps = [...byIp.keys()].sort((a, b) => {
+        // Handle IPv6 by falling back to string comparison
+        if (a.includes(":") || b.includes(":")) {
+          return a.localeCompare(b);
+        }
         const aParts = a.split(".").map(Number);
         const bParts = b.split(".").map(Number);
+        if (aParts.length !== 4 || bParts.length !== 4) {
+          return a.localeCompare(b);
+        }
         for (let i = 0; i < 4; i++) {
           if (aParts[i] !== bParts[i]) return aParts[i] - bParts[i];
         }
         return 0;
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/MassScan.ts around lines 369 - 377,
The current IP sorting (creating sortedIps from byIp.keys()) assumes IPv4 by
splitting on dots and comparing four octets, which will break for IPv6; replace
the inline sort with a reusable comparator (e.g., compareIPs) that first detects
address family using net.isIP or an IP parsing library, then normalizes
addresses to comparable numeric forms (32-bit integer for IPv4, 128-bit BigInt
or 16-byte Buffer for IPv6) and compares those values; update the sort call that
assigns sortedIps to use this comparator and ensure non-IP strings (if any) are
consistently ordered (e.g., treat invalid addresses as greater or lesser).
.opencode/skills/Security/AnnualReports/SKILL.md (1)

73-95: Fehlende Sprachkennzeichnung in Code-Blöcken.

Die Beispiel-Code-Blöcke haben keine Sprachkennzeichnung. Dies wurde auch vom Static-Analysis-Tool (MD040) gemeldet.

📝 Vorgeschlagene Korrektur
 **Example 1: Update sources from upstream**
-```
+```text
 User: "Update the annual reports"
 → Invokes UPDATE workflow

Analog für die anderen Beispiele auf Zeilen 82 und 90.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/AnnualReports/SKILL.md around lines 73 - 95, The
Markdown example code blocks lack a language tag (triggering MD040); update each
triple-backtick fence for the three example blocks so they start with ```text
instead of ``` — specifically the blocks beginning with the lines containing
'User: "Update the annual reports"', 'Example 2: Find threat intelligence
reports' (the block that lists Global Threat Intelligence and 56 reports), and
'Example 3: Analyze ransomware trends' (the ANALYZE workflow block). Ensure each
opening fence is ```text and leave the block contents unchanged.
.opencode/skills/Security/Recon/Tools/PortScan.ts (1)

24-24: Nicht verwendete timeout-Option im Interface.

Die timeout-Option ist in PortScanOptions definiert, wird aber beim Aufbau des naabu-Befehls nicht verwendet. Dies könnte zu Verwirrung führen.

🔧 Option entweder verwenden oder entfernen
   // Nach Zeile 107, vor CDN handling:
+  // Timeout
+  if (options.timeout) {
+    args.push("--timeout", String(options.timeout));
+  }
+
   // CDN handling
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/PortScan.ts at line 24, Die Option
timeout in der Schnittstelle PortScanOptions wird nicht verwendet; entweder
entferne das Feld oder benutze es beim Aufbau des naabu-Befehls. Öffne die
Stelle, die die naabu-Kommandos zusammenstellt (z.B. die Funktion/methode, die
Args oder das Command in der PortScan-Klasse/bei buildCommand/runScan) und wenn
timeout gesetzt ist, hänge das passende naabu-Flag (z.B. -timeout mit dem
erwarteten Format) an die Argumentliste; alternativ entferne timeout aus
PortScanOptions und überall dort, wo es optional übergeben wird, um Verwirrung
zu vermeiden.
.opencode/skills/Security/SECUpdates/SKILL.md (2)

14-23: Voice Notification setzt lokalen Service voraus.

Die Voice Notification verwendet localhost:8888, ohne dass dokumentiert ist, wie dieser Service eingerichtet wird. Dies könnte zu Fehlern führen, wenn der Service nicht läuft.

Erwägen Sie, einen Hinweis hinzuzufügen, dass dies optional ist oder wie der Notification-Service eingerichtet wird, oder verwenden Sie eine Fehlerbehandlung, die stille Fehler ignoriert (was das > /dev/null 2>&1 & bereits tut).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/SECUpdates/SKILL.md around lines 14 - 23, Die
"Voice Notification (REQUIRED)" Abschnitt verwendet fest localhost:8888 im
curl-Aufruf und geht nicht darauf ein, wie der Service gestartet wird;
aktualisiere SKILL.md: markiere die Voice-Notification als optional (oder
dokumentiere explizit wie ein Notification-Service zu betreiben/konfigurieren),
zeige alternativ wie HOST/PORT als konfigurierbare Variable (z.B. ENV) ersetzt
werden kann und füge eine kurze Fehlerbehandlung/Hinweis hinzu, dass der
curl-Aufruf (die gezeigte curl-Zeile) stille Fehler unterdrückt; referenziere
dabei die Überschrift "Voice Notification (REQUIRED)" und den gezeigten
curl-Befehl, damit Reviewer die Stellen leicht finden.

138-138: State-Pfad-Inkonsistenz.

Der State-Datei-Pfad State/last-check.json sollte mit dem vollständigen Pfad ~/.opencode/skills/Security/SECUpdates/State/last-check.json dokumentiert werden, um Konsistenz zu gewährleisten.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/SECUpdates/SKILL.md at line 138, The documented
state file path is inconsistent: update the markdown entry "**State file:**
`State/last-check.json`" to use the full path
`~/.opencode/skills/Security/SECUpdates/State/last-check.json` so the SKILL.md
shows the complete, unambiguous location for the state file.
.opencode/skills/Security/SECUpdates/Workflows/Update.md (1)

19-26: Fehlende Sprachkennzeichnung im Code-Block.

Der Code-Block für die Source-URLs hat keine Sprachkennzeichnung (MD040).

📝 Vorgeschlagene Korrektur
-```
+```text
 Source 1: https://tldrsec.com
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/SECUpdates/Workflows/Update.md around lines 19 -
26, Der Code-Block mit den Quell-URLs (der Block, der mit den Zeilen "Source 1:
https://tldrsec.com" ... "Source 6: https://risky.biz" beginnt) fehlt die
Sprachkennzeichnung und schlägt MD040; behebe es, indem du die öffnenden
Backticks von ``` auf ```text änderst (also die Code-Block-Markierung um die
Sprache "text" ergänzen) so dass der Block beginnt mit ```text und der restliche
Inhalt unverändert bleibt; suche im Dokument nach dem Block mit den "Source
X:"-Zeilen und aktualisiere nur die öffnende Backtick-Zeile.
.opencode/skills/Security/Recon/Tools/SubdomainEnum.ts (2)

84-86: Potenzielle Einschränkung bei großen Subdomain-Listen.

Die Verwendung von echo mit Pipe zu dnsx könnte bei sehr großen Subdomain-Listen zu Problemen führen (Shell-Argumentlängenbegrenzungen). Eine Alternative wäre die Verwendung von temporären Dateien oder Process-Stdin.

♻️ Robustere Alternative
 async function resolveSubdomains(
   subdomains: string[]
 ): Promise<Record<string, string[]>> {
   const resolved: Record<string, string[]> = {};
   try {
-    const input = subdomains.join("\n");
-    const result = await $`echo ${input} | dnsx -silent -a -resp`.text();
+    const proc = Bun.spawn(["dnsx", "-silent", "-a", "-resp"], {
+      stdin: "pipe",
+      stdout: "pipe",
+    });
+    const writer = proc.stdin.getWriter();
+    await writer.write(new TextEncoder().encode(subdomains.join("\n")));
+    await writer.close();
+    const result = await new Response(proc.stdout).text();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/SubdomainEnum.ts around lines 84 - 86,
Die aktuelle Verwendung von echo mit Template-String in der Linie, die `const
input = subdomains.join("\n");` und `const result = await $`echo ${input} | dnsx
-silent -a -resp`.text();` enthält, bricht bei sehr großen Listen durch
Shell-Argumentlängenbegrenzungen; fixiere das, indem du statt des inline-echo
entweder 1) die Inhalte von `input` in eine temporäre Datei schreibst und `dnsx`
gegen diese Datei ausführst, oder 2) `dnsx` direkt via spawned child process
aufrufst und den `input`-String in den Prozess-stdin streamst (z.B. mittels
`child_process.spawn`), und dann `result` aus dem Prozess-stdout liest;
aktualisiere die Stelle mit dem `$`-Call entsprechend und entferne die
echo-Form, referenziere dabei die vorhandenen Variablen `subdomains`, `input`
und `result`.

49-51: API-Schlüssel als Kommandozeilenargument entfernen.

Der PDCP_API_KEY wird als Kommandozeilenargument mit -key übergeben, wodurch er in Prozesslisten (ps aux) sichtbar wird. Die Chaos-CLI liest PDCP_API_KEY automatisch aus der Umgebungsvariable, wenn diese gesetzt ist – das explizite -key-Flag ist nicht erforderlich.

Entfernen Sie -key ${key} aus dem Befehl und verlassen Sie sich auf die Umgebungsvariable:

const result = await $`chaos -d ${domain} -silent`.text();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/SubdomainEnum.ts around lines 49 - 51,
Remove the API key from the spawned command in SubdomainEnum.ts: stop passing
the `-key ${key}` flag to the chaos CLI and call it as `chaos -d ${domain}
-silent` so the CLI reads PDCP_API_KEY from the environment; update the
invocation that uses the `key` variable (in the try block around the backtick
command) and remove/clean up any now-unused `key` parameter or variable to avoid
leaving secrets in process listings.
.opencode/skills/Security/PromptInjection/APPLICATION-RECONNAISSANCE-METHODOLOGY.md (1)

584-609: Fehlender Sprachbezeichner im Diagramm-Code-Block.

Der Flow-Diagramm-Block (Zeilen 586-595) hat keinen Sprachbezeichner. Empfehlung: text oder plaintext verwenden.

📝 Vorgeschlagene Korrektur
 ## Flow Diagram
-```
+```text
 User Input → Web Form → POST /api/chat → Backend Server → OpenAI API
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.opencode/skills/Security/PromptInjection/APPLICATION-RECONNAISSANCE-METHODOLOGY.md
around lines 584 - 609, The fenced flow diagram block (the triple-backtick block
containing "User Input → Web Form → POST /api/chat → Backend Server → OpenAI
API" in the Flow Diagram section) is missing a language identifier; update that
code fence to include a language tag such as ```text or ```plaintext so the
diagram is rendered/parsed correctly (i.e., change ``` to ```text for the
diagram block that starts with "User Input → Web Form → POST /api/chat → Backend
Server → OpenAI API").
.opencode/skills/Security/Recon/Tools/IpinfoClient.ts (2)

86-99: API-Key in URL statt Authorization-Header.

Der API-Key wird als URL-Parameter übergeben (?token=). Dies ist weniger sicher als ein Authorization-Header, da URLs in Logs, Browser-History und Referrer-Headern erscheinen können. IPInfo unterstützt auch Bearer-Token-Authentifizierung.

🔒 Vorgeschlagene Verbesserung
-    const url = `${this.baseUrl}/${ip}/json?token=${this.apiKey}`;
+    const url = `${this.baseUrl}/${ip}/json`;
 
     try {
-      const response = await fetch(url);
+      const response = await fetch(url, {
+        headers: {
+          'Authorization': `Bearer ${this.apiKey}`
+        }
+      });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/IpinfoClient.ts around lines 86 - 99,
The request currently appends the API key as a URL token parameter in
IpinfoClient (the code building url =
`${this.baseUrl}/${ip}/json?token=${this.apiKey}` and the subsequent fetch),
which is insecure; change the request to remove the ?token=... from the URL (use
`${this.baseUrl}/${ip}/json`) and pass the API key in the fetch headers as
Authorization: `Bearer ${this.apiKey}` instead, ensuring the fetch call in the
same method includes a headers object and retains the existing
response.ok/status handling (including the 429 and 401 checks).

88-99: Fehlendes Timeout bei fetch-Requests.

Ohne Timeout können Requests bei Netzwerkproblemen unbegrenzt hängen bleiben.

🛡️ Vorgeschlagene Verbesserung
     try {
-      const response = await fetch(url);
+      const controller = new AbortController();
+      const timeoutId = setTimeout(() => controller.abort(), 10000);
+      
+      const response = await fetch(url, {
+        signal: controller.signal,
+      });
+      
+      clearTimeout(timeoutId);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/IpinfoClient.ts around lines 88 - 99,
The fetch call in IpinfoClient.ts (the request that uses the url variable and
awaits fetch(...)) lacks a timeout and can hang; fix by creating an
AbortController, use its signal in the fetch call, start a timer (e.g.,
configurable default like 5s) that calls controller.abort() on timeout, and
clear the timer after the response is received; update the method in the
IpinfoClient class (the function that constructs and awaits fetch(url)) to
accept/configure a timeout value and handle AbortError appropriately.
.opencode/skills/Security/Recon/SKILL.md (1)

34-36: Fehlende Sprachbezeichner in Code-Blöcken (optional).

Mehrere Fenced-Code-Blöcke haben keinen Sprachbezeichner. Für bessere Lesbarkeit und Syntax-Highlighting empfohlen.

📝 Beispielkorrektur für Zeile 34
-```
+```text
 Running the **WorkflowName** workflow from the **Recon** skill...

Also applies to: 422-423, 436-437, 454-455, 480-481

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/SKILL.md around lines 34 - 36, Several
fenced code blocks (e.g., the block containing "Running the **WorkflowName**
workflow from the **Recon** skill..." and the other similar blocks noted) lack a
language identifier; update each triple-backtick fence to include an appropriate
language tag (for plain text or markdown, e.g., ```text or ```md) so editors and
renderers can apply syntax highlighting—search for the exact code-block contents
such as "Running the **WorkflowName** workflow from the **Recon** skill..." and
the other similar blocks referenced and prepend the chosen language identifier
to each opening ``` fence.
.opencode/skills/Security/Recon/Workflows/IpRecon.md (1)

67-79: IPv6-Regex ist zu restriktiv.

Der IPv6-Regex ^([0-9a-fA-F]{0,4}:){7}[0-9a-fA-F]{0,4}$ erfasst keine komprimierten Formen wie ::1, 2001:db8::1 oder fe80::1%eth0. Da dies Dokumentation ist, sollte ein Hinweis auf die Vereinfachung hinzugefügt werden.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Workflows/IpRecon.md around lines 67 - 79,
The IPv6 regex in function isValidIP is too restrictive and misses compressed
forms and zone IDs; update isValidIP to use a robust validator (e.g., Node's
net.isIP or a comprehensive IPv6 parser) instead of the current
/^([0-9a-fA-F]{0,4}:){7}[0-9a-fA-F]{0,4}$/ so it correctly accepts compressed
addresses like ::1, 2001:db8::1 and zone identifiers like fe80::1%eth0, and/or
add a clear comment in the documentation noting the previous regex was a
simplification and has been replaced to support all valid IPv6 formats.
.opencode/skills/Security/Recon/Tools/WhoisParser.ts (1)

294-299: Redundante Date-Parsing-Logik.

Nach dem Regex-Match wird new Date(dateStr) erneut aufgerufen, obwohl bereits bekannt ist, dass das Standardparsing fehlgeschlagen ist (Zeile 278-282).

♻️ Vorgeschlagene Verbesserung
   for (const format of formats) {
     const match = dateStr.match(format);
     if (match) {
-      return new Date(dateStr);
+      // Parse matched components explicitly
+      // For ISO/YYYY-MM-DD: match groups are year, month, day
+      return new Date(dateStr); // Standard parsing works for these formats
     }
   }

Da das Standard-Parsing für diese Formate funktioniert, könnte die Regex-Prüfung komplett entfernt werden, oder explizite Komponentenextraktion implementiert werden.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/WhoisParser.ts around lines 294 - 299,
The regex loop over formats that checks dateStr (the for (const format of
formats) { const match = dateStr.match(format); ... }) is redundant because you
then call new Date(dateStr) even though standard parsing already supports those
formats; remove the entire loop and simply return new Date(dateStr) for the
fallback path (or, if you need stricter correctness, replace the loop with
explicit component extraction from the regex match and construct the Date via
new Date(year, month-1, day, hour, minute, second) or Date.UTC using the match
groups).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bc70fd17-b53e-433b-a759-82509b1a3150

📥 Commits

Reviewing files that changed from the base of the PR and between aa1daf5 and 9787c75.

⛔ Files ignored due to path filters (1)
  • .opencode/skills/Security/WebAssessment/BugBountyTool/bun.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (142)
  • .opencode/skills/Security/AnnualReports/Data/sources.json
  • .opencode/skills/Security/AnnualReports/Reports/.gitkeep
  • .opencode/skills/Security/AnnualReports/SKILL.md
  • .opencode/skills/Security/AnnualReports/Tools/FetchReport.ts
  • .opencode/skills/Security/AnnualReports/Tools/ListSources.ts
  • .opencode/skills/Security/AnnualReports/Tools/UpdateSources.ts
  • .opencode/skills/Security/PromptInjection/APPLICATION-RECONNAISSANCE-METHODOLOGY.md
  • .opencode/skills/Security/PromptInjection/AutomatedTestingTools.md
  • .opencode/skills/Security/PromptInjection/COMPREHENSIVE-ATTACK-TAXONOMY.md
  • .opencode/skills/Security/PromptInjection/DefenseMechanisms.md
  • .opencode/skills/Security/PromptInjection/QuickStartGuide.md
  • .opencode/skills/Security/PromptInjection/README.md
  • .opencode/skills/Security/PromptInjection/Reporting.md
  • .opencode/skills/Security/PromptInjection/SKILL.md
  • .opencode/skills/Security/PromptInjection/Workflows/CompleteAssessment.md
  • .opencode/skills/Security/PromptInjection/Workflows/DirectInjectionTesting.md
  • .opencode/skills/Security/PromptInjection/Workflows/IndirectInjectionTesting.md
  • .opencode/skills/Security/PromptInjection/Workflows/MultiStageAttacks.md
  • .opencode/skills/Security/PromptInjection/Workflows/Reconnaissance.md
  • .opencode/skills/Security/Recon/Data/BountyPrograms.json
  • .opencode/skills/Security/Recon/README.md
  • .opencode/skills/Security/Recon/SKILL.md
  • .opencode/skills/Security/Recon/Tools/BountyPrograms.ts
  • .opencode/skills/Security/Recon/Tools/CidrUtils.ts
  • .opencode/skills/Security/Recon/Tools/CorporateStructure.ts
  • .opencode/skills/Security/Recon/Tools/DnsUtils.ts
  • .opencode/skills/Security/Recon/Tools/EndpointDiscovery.ts
  • .opencode/skills/Security/Recon/Tools/IpinfoClient.ts
  • .opencode/skills/Security/Recon/Tools/MassScan.ts
  • .opencode/skills/Security/Recon/Tools/PathDiscovery.ts
  • .opencode/skills/Security/Recon/Tools/PortScan.ts
  • .opencode/skills/Security/Recon/Tools/SubdomainEnum.ts
  • .opencode/skills/Security/Recon/Tools/WhoisParser.ts
  • .opencode/skills/Security/Recon/Workflows/AnalyzeScanResultsGemini3.md
  • .opencode/skills/Security/Recon/Workflows/BountyPrograms.md
  • .opencode/skills/Security/Recon/Workflows/DomainRecon.md
  • .opencode/skills/Security/Recon/Workflows/IpRecon.md
  • .opencode/skills/Security/Recon/Workflows/NetblockRecon.md
  • .opencode/skills/Security/Recon/Workflows/PassiveRecon.md
  • .opencode/skills/Security/Recon/Workflows/UpdateTools.md
  • .opencode/skills/Security/SECUpdates/SKILL.md
  • .opencode/skills/Security/SECUpdates/Workflows/Update.md
  • .opencode/skills/Security/SECUpdates/sources.json
  • .opencode/skills/Security/SKILL.md
  • .opencode/skills/Security/WebAssessment/BugBountyTool/README.md
  • .opencode/skills/Security/WebAssessment/BugBountyTool/bounty.sh
  • .opencode/skills/Security/WebAssessment/BugBountyTool/package.json
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/config.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/github.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/init.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/recon.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/show.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/state.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/types.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/update.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/state.json
  • .opencode/skills/Security/WebAssessment/FfufResources/REQUEST_TEMPLATES.md
  • .opencode/skills/Security/WebAssessment/FfufResources/WORDLISTS.md
  • .opencode/skills/Security/WebAssessment/OsintTools/API-TOOLS-GUIDE.md
  • .opencode/skills/Security/WebAssessment/OsintTools/README.md
  • .opencode/skills/Security/WebAssessment/OsintTools/automation-frameworks-notes.md
  • .opencode/skills/Security/WebAssessment/OsintTools/network-tools-notes.md
  • .opencode/skills/Security/WebAssessment/OsintTools/osint-api-tools.py
  • .opencode/skills/Security/WebAssessment/OsintTools/visualization-threat-intel-notes.md
  • .opencode/skills/Security/WebAssessment/SKILL.md
  • .opencode/skills/Security/WebAssessment/WebappExamples/console_logging.py
  • .opencode/skills/Security/WebAssessment/WebappExamples/element_discovery.py
  • .opencode/skills/Security/WebAssessment/WebappExamples/static_html_automation.py
  • .opencode/skills/Security/WebAssessment/WebappScripts/with_server.py
  • .opencode/skills/Security/WebAssessment/Workflows/CreateThreatModel.md
  • .opencode/skills/Security/WebAssessment/Workflows/UnderstandApplication.md
  • .opencode/skills/Security/WebAssessment/Workflows/VulnerabilityAnalysisGemini3.md
  • .opencode/skills/Security/WebAssessment/Workflows/bug-bounty/AutomationTool.md
  • .opencode/skills/Security/WebAssessment/Workflows/bug-bounty/Programs.md
  • .opencode/skills/Security/WebAssessment/Workflows/ffuf/FfufGuide.md
  • .opencode/skills/Security/WebAssessment/Workflows/ffuf/FfufHelper.md
  • .opencode/skills/Security/WebAssessment/Workflows/osint/Automation.md
  • .opencode/skills/Security/WebAssessment/Workflows/osint/MasterGuide.md
  • .opencode/skills/Security/WebAssessment/Workflows/osint/MetadataAnalysis.md
  • .opencode/skills/Security/WebAssessment/Workflows/osint/Reconnaissance.md
  • .opencode/skills/Security/WebAssessment/Workflows/osint/SocialMediaIntel.md
  • .opencode/skills/Security/WebAssessment/Workflows/pentest/Exploitation.md
  • .opencode/skills/Security/WebAssessment/Workflows/pentest/MasterMethodology.md
  • .opencode/skills/Security/WebAssessment/Workflows/pentest/Reconnaissance.md
  • .opencode/skills/Security/WebAssessment/Workflows/pentest/ToolInventory.md
  • .opencode/skills/Security/WebAssessment/Workflows/webapp/Examples.md
  • .opencode/skills/Security/WebAssessment/Workflows/webapp/TestingGuide.md
  • .opencode/skills/Security/WebAssessment/ffuf-helper.py
  • .opencode/skills/Thinking/BeCreative/Assets/creative-writing-template.md
  • .opencode/skills/Thinking/BeCreative/Assets/idea-generation-template.md
  • .opencode/skills/Thinking/BeCreative/Examples.md
  • .opencode/skills/Thinking/BeCreative/Principles.md
  • .opencode/skills/Thinking/BeCreative/ResearchFoundation.md
  • .opencode/skills/Thinking/BeCreative/SKILL.md
  • .opencode/skills/Thinking/BeCreative/Templates.md
  • .opencode/skills/Thinking/BeCreative/Workflows/DomainSpecific.md
  • .opencode/skills/Thinking/BeCreative/Workflows/IdeaGeneration.md
  • .opencode/skills/Thinking/BeCreative/Workflows/MaximumCreativity.md
  • .opencode/skills/Thinking/BeCreative/Workflows/StandardCreativity.md
  • .opencode/skills/Thinking/BeCreative/Workflows/TechnicalCreativityGemini3.md
  • .opencode/skills/Thinking/BeCreative/Workflows/TreeOfThoughts.md
  • .opencode/skills/Thinking/Council/CouncilMembers.md
  • .opencode/skills/Thinking/Council/OutputFormat.md
  • .opencode/skills/Thinking/Council/RoundStructure.md
  • .opencode/skills/Thinking/Council/SKILL.md
  • .opencode/skills/Thinking/Council/Workflows/Debate.md
  • .opencode/skills/Thinking/Council/Workflows/Quick.md
  • .opencode/skills/Thinking/FirstPrinciples/SKILL.md
  • .opencode/skills/Thinking/FirstPrinciples/Workflows/Challenge.md
  • .opencode/skills/Thinking/FirstPrinciples/Workflows/Deconstruct.md
  • .opencode/skills/Thinking/FirstPrinciples/Workflows/Reconstruct.md
  • .opencode/skills/Thinking/IterativeDepth/SKILL.md
  • .opencode/skills/Thinking/IterativeDepth/ScientificFoundation.md
  • .opencode/skills/Thinking/IterativeDepth/TheLenses.md
  • .opencode/skills/Thinking/IterativeDepth/Workflows/Explore.md
  • .opencode/skills/Thinking/RedTeam/Integration.md
  • .opencode/skills/Thinking/RedTeam/Philosophy.md
  • .opencode/skills/Thinking/RedTeam/SKILL.md
  • .opencode/skills/Thinking/RedTeam/Workflows/AdversarialValidation.md
  • .opencode/skills/Thinking/RedTeam/Workflows/ParallelAnalysis.md
  • .opencode/skills/Thinking/SKILL.md
  • .opencode/skills/Thinking/Science/Examples.md
  • .opencode/skills/Thinking/Science/METHODOLOGY.md
  • .opencode/skills/Thinking/Science/Protocol.md
  • .opencode/skills/Thinking/Science/SKILL.md
  • .opencode/skills/Thinking/Science/Templates.md
  • .opencode/skills/Thinking/Science/Workflows/AnalyzeResults.md
  • .opencode/skills/Thinking/Science/Workflows/DefineGoal.md
  • .opencode/skills/Thinking/Science/Workflows/DesignExperiment.md
  • .opencode/skills/Thinking/Science/Workflows/FullCycle.md
  • .opencode/skills/Thinking/Science/Workflows/GenerateHypotheses.md
  • .opencode/skills/Thinking/Science/Workflows/Iterate.md
  • .opencode/skills/Thinking/Science/Workflows/MeasureResults.md
  • .opencode/skills/Thinking/Science/Workflows/QuickDiagnosis.md
  • .opencode/skills/Thinking/Science/Workflows/StructuredInvestigation.md
  • .opencode/skills/Thinking/WorldThreatModelHarness/ModelTemplate.md
  • .opencode/skills/Thinking/WorldThreatModelHarness/OutputFormat.md
  • .opencode/skills/Thinking/WorldThreatModelHarness/SKILL.md
  • .opencode/skills/Thinking/WorldThreatModelHarness/Workflows/TestIdea.md
  • .opencode/skills/Thinking/WorldThreatModelHarness/Workflows/UpdateModels.md
  • .opencode/skills/Thinking/WorldThreatModelHarness/Workflows/ViewModels.md

Comment on lines +219 to +230
// Note: Full update would merge parsed data into sources.json
// For now, just update the timestamp since manual curation is preferred
current.metadata.lastUpdated = new Date().toISOString().split('T')[0];
current.metadata.totalReports = countReports(current);

writeFileSync(SOURCES_PATH, JSON.stringify(current, null, 2));
console.log('✅ Updated sources.json');
console.log(` Total reports: ${current.metadata.totalReports}`);
console.log(` Last updated: ${current.metadata.lastUpdated}`);

console.log('\n💡 For full upstream sync, manually review changes at:');
console.log(` ${UPSTREAM_URL.replace('/README.md', '')}`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Der Schreibpfad übernimmt die frisch geparsten Upstream-Daten überhaupt nicht.

Trotz der Erfolgslogausgabe werden im Standardpfad nur Metadaten des vorhandenen JSONs fortgeschrieben; parsed selbst wird nie serialisiert. Damit kann das Tool einen erfolgreichen Sync melden, obwohl die Upstream-Inhalte gar nicht übernommen werden, und totalReports bleibt weiter auf Altbestand.

💡 Vorschlag
-    // Note: Full update would merge parsed data into sources.json
-    // For now, just update the timestamp since manual curation is preferred
-    current.metadata.lastUpdated = new Date().toISOString().split('T')[0];
-    current.metadata.totalReports = countReports(current);
-
-    writeFileSync(SOURCES_PATH, JSON.stringify(current, null, 2));
+    const next: Sources = {
+      metadata: {
+        source: UPSTREAM_URL.replace('/README.md', ''),
+        lastUpdated: new Date().toISOString().split('T')[0],
+        totalReports: parsedTotal,
+      },
+      categories: {
+        analysis: {},
+        survey: {},
+      },
+    };
+
+    for (const [key, reports] of parsed) {
+      const section: keyof Sources['categories'] =
+        key.startsWith('analysis_') ? 'analysis' : 'survey';
+      const category = key.replace(/^(analysis|survey)_/, '');
+      next.categories[section][category] = reports;
+    }
+
+    writeFileSync(SOURCES_PATH, JSON.stringify(next, null, 2));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/AnnualReports/Tools/UpdateSources.ts around lines
219 - 230, Die aktuelle Implementierung aktualisiert nur current.metadata and
schreibt current zurück via writeFileSync(SOURCES_PATH) ohne je die frisch
geparsten Upstream-Daten (parsed) zu übernehmen; passe die Logik in
UpdateSources.ts so an, dass entweder parsed vollständig in
current.sources/entries gemerged oder current komplett durch parsed ersetzt wird
(je nach gewünschtem Verhalten), bevor writeFileSync(SOURCES_PATH, ...)
aufgerufen wird; aktualisiere danach current.metadata.totalReports =
countReports(current) (oder countReports(parsed) falls ersetzt) und setze
current.metadata.lastUpdated wie bisher, damit die tatsächlich übernommenen
Inhalte serialisiert werden.

Comment on lines +60 to +69
async function executeWhois(query: string): Promise<string> {
try {
const result = await $`whois ${query}`.text();
return result;
} catch (error) {
throw new Error(
`WHOIS query failed: ${error instanceof Error ? error.message : "Unknown error"}`
);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Potenzielle Command-Injection-Schwachstelle.

Der query-Parameter wird direkt an die Shell übergeben. Bei bösartiger Eingabe wie example.com; rm -rf / könnte beliebiger Code ausgeführt werden.

🔒 Vorgeschlagene Korrektur
 async function executeWhois(query: string): Promise<string> {
+  // Validate query to prevent injection
+  if (!/^[a-zA-Z0-9.\-:]+$/.test(query)) {
+    throw new Error(`Invalid WHOIS query: ${query}`);
+  }
+  
   try {
     const result = await $`whois ${query}`.text();
     return result;

Alternative mit Array-Syntax für sicherere Shell-Ausführung:

import { spawn } from 'child_process';

async function executeWhois(query: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const proc = spawn('whois', [query]);
    // ... handle stdout/stderr
  });
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function executeWhois(query: string): Promise<string> {
try {
const result = await $`whois ${query}`.text();
return result;
} catch (error) {
throw new Error(
`WHOIS query failed: ${error instanceof Error ? error.message : "Unknown error"}`
);
}
}
async function executeWhois(query: string): Promise<string> {
// Validate query to prevent injection
if (!/^[a-zA-Z0-9.\-:]+$/.test(query)) {
throw new Error(`Invalid WHOIS query: ${query}`);
}
try {
const result = await $`whois ${query}`.text();
return result;
} catch (error) {
throw new Error(
`WHOIS query failed: ${error instanceof Error ? error.message : "Unknown error"}`
);
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/Recon/Tools/WhoisParser.ts around lines 60 - 69,
The executeWhois function currently passes user input into a shell template
(`$`whois ${query}``) causing a command-injection risk; replace this with a
child_process spawn-based implementation that invokes whois with an argument
array (spawn('whois', [query])) and collect stdout/stderr via the spawned
process, reject the Promise on non-zero exit or stderr, and avoid any shell:true
usage; additionally validate or whitelist the query string (e.g., allow only
domain/IP characters) before spawning to further mitigate injection.

The main checkForUpdates() return path (Tier 2 / analyzeChanges branch)
spread results from analyzeChanges() which is typed as
Omit<DiscoveryResult, 'total_checked' | 'check_duration_ms'> — so
total_checked was always absent, violating the DiscoveryResult interface.

The other two early-return paths correctly set total_checked (0 and 5).
Set total_checked: 4 to match the four platforms checked in analyzeChanges
(hackerone, bugcrowd, intigriti, yeswehack).

Addresses CodeRabbit round-1 critical finding.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts:
- Around line 61-70: The returned metric total_checked is inconsistent across
early-return paths; introduce a single totalChecked variable in the surrounding
tracker method (initialize it to 0), increment it wherever individual program
checks are performed, and replace the hard-coded 0/5/4 literals in every return
object (the ones that return new_programs, scope_expansions, upgraded_programs)
with totalChecked so all return paths (including the early
currentState.initialized branch that calls this.initialize()) report the same
computed count; reference currentState.initialized, this.initialize(), startTime
and the total_checked field in the returned objects when making the change.
- Around line 9-10: Der Tracker instanziiert StateManager (private state = new
StateManager()) but CONFIG.paths still point to the old
"~/.opencode/skills/hacking/bug-bounties" location; update src/config.ts (the
CONFIG.paths entries referenced by StateManager) to the new Security hierarchy
path (e.g. under "~/.opencode/skills/Security/...") so StateManager writes to
the new location, and verify Tracker's use of GitHubClient and StateManager
(symbols: GitHubClient, StateManager, CONFIG.paths) continue to work with the
revised paths.
- Around line 200-206: Die jetzige Prüfung verwendet nur einen Längenvergleich
zwischen program.key_scopes und existing.key_scopes (in der Stelle, die das
meta-Objekt mit change_type: 'scope_expansion' erstellt), was False-Negatives
produziert; ändere die Bedingung so, dass sie prüft, ob program.key_scopes
mindestens ein Element enthält, das nicht in existing.key_scopes vorkommt (z.B.
mittels Set-Differenz oder Array.prototype.some/!includes), und nur dann meta
mit key_scopes: program.key_scopes, discovered_at und change_type:
'scope_expansion' setzen; behalte die existierenden Feldnamen
(program.key_scopes, existing.key_scopes, meta, change_type) unverändert.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f3dc142d-98a4-4fde-945f-b55e9eddc0f3

📥 Commits

Reviewing files that changed from the base of the PR and between 9787c75 and c730be7.

📒 Files selected for processing (1)
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts

Comment on lines +9 to +10
private github = new GitHubClient();
private state = new StateManager();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Persistenzpfade sind nicht auf die neue Security-Hierarchie umgestellt.

Auf Line 10 wird StateManager verwendet; dessen CONFIG.paths zeigen laut src/config.ts (Line 18-22) weiterhin auf ~/.opencode/skills/hacking/bug-bounties. Damit schreibt der Tracker trotz PR-Ziel in den Altpfad.

🔧 Vorschlag (in src/config.ts)
-    root: '~/.opencode/skills/hacking/bug-bounties',
-    state: '~/.opencode/skills/hacking/bug-bounties/state.json',
-    cache: '~/.opencode/skills/hacking/bug-bounties/cache',
-    logs: '~/.opencode/skills/hacking/bug-bounties/logs',
+    root: '~/.opencode/skills/Security/WebAssessment/BugBountyTool',
+    state: '~/.opencode/skills/Security/WebAssessment/BugBountyTool/state.json',
+    cache: '~/.opencode/skills/Security/WebAssessment/BugBountyTool/cache',
+    logs: '~/.opencode/skills/Security/WebAssessment/BugBountyTool/logs',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 9 - 10, Der Tracker instanziiert StateManager (private state = new
StateManager()) but CONFIG.paths still point to the old
"~/.opencode/skills/hacking/bug-bounties" location; update src/config.ts (the
CONFIG.paths entries referenced by StateManager) to the new Security hierarchy
path (e.g. under "~/.opencode/skills/Security/...") so StateManager writes to
the new location, and verify Tracker's use of GitHubClient and StateManager
(symbols: GitHubClient, StateManager, CONFIG.paths) continue to work with the
revised paths.

Comment on lines +61 to +70
if (!currentState.initialized) {
console.log('⚠️ Tracker not initialized. Run initialization first.');
await this.initialize();
return {
new_programs: [],
scope_expansions: [],
upgraded_programs: [],
total_checked: 0,
check_duration_ms: Date.now() - startTime,
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

total_checked ist zwischen Rückgabepfaden semantisch inkonsistent.

Auf Line 68 wird 0, auf Line 86 5 und auf Line 128 4 zurückgegeben. Diese Metrik ist damit nicht stabil auswertbar (Monitoring/CLI-Ausgabe).

Also applies to: 80-88, 126-130

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 61 - 70, The returned metric total_checked is inconsistent across
early-return paths; introduce a single totalChecked variable in the surrounding
tracker method (initialize it to 0), increment it wherever individual program
checks are performed, and replace the hard-coded 0/5/4 literals in every return
object (the ones that return new_programs, scope_expansions, upgraded_programs)
with totalChecked so all return paths (including the early
currentState.initialized branch that calls this.initialize()) report the same
computed count; reference currentState.initialized, this.initialize(), startTime
and the total_checked field in the returned objects when making the change.

config.ts:
- Update CONFIG.paths from old 'hacking/bug-bounties' location to correct
  new path 'Security/WebAssessment/BugBountyTool' after PR-03 skill reorg

tracker.ts:
- Extract PLATFORM_COUNT constant (4) to make total_checked consistent
  across all return paths; replace hardcoded 5 and 4 literals with the
  shared constant so Tier-1, Tier-2, and future paths stay in sync
- Fix scope_expansion detection: replace length comparison with Set-based
  check (program.key_scopes.some(s => !existing.key_scopes.includes(s)))
  to catch scope changes where items are added without increasing total count
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts (2)

61-61: PLATFORM_COUNT sollte aus dem platforms-Array abgeleitet werden.

Die Konstante PLATFORM_COUNT = 4 ist mit dem platforms-Array auf Zeile 146 dupliziert. Bei Änderungen an den Plattformen könnten diese Werte divergieren.

♻️ Vorschlag: Konstante aus Array ableiten
+const PLATFORMS = ['hackerone', 'bugcrowd', 'intigriti', 'yeswehack'] as const;
+
 export class BugBountyTracker {
   private github = new GitHubClient();
   private state = new StateManager();

Dann in update() und analyzeChanges():

-    const PLATFORM_COUNT = 4; // hackerone, bugcrowd, intigriti, yeswehack
+    const PLATFORM_COUNT = PLATFORMS.length;
-    const platforms = ['hackerone', 'bugcrowd', 'intigriti', 'yeswehack'] as const;
+    // PLATFORMS is defined at module level
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts at line
61, PLATFORM_COUNT is hard-coded and duplicates the platforms array; change it
to derive from the array by replacing the constant usage with platforms.length
(e.g., remove or replace PLATFORM_COUNT declaration and use platforms.length
wherever PLATFORM_COUNT is referenced) and update functions that rely on it
(notably update() and analyzeChanges()) to read the dynamic value so the count
always matches the platforms array.

202-202: Optional: Set für bessere Lookup-Performance.

Die aktuelle Implementierung ist korrekt, aber bei großen Scope-Listen könnte ein Set den Lookup von O(n) auf O(1) reduzieren.

⚡ Vorschlag für Performance-Optimierung
-          } else if (program.key_scopes.some(s => !existing.key_scopes.includes(s))) {
+          } else {
+            const existingScopes = new Set(existing.key_scopes);
+            if (!program.key_scopes.some(s => !existingScopes.has(s))) {
+              continue;
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts at line
202, Replace the O(n) includes check over existing.key_scopes with an O(1) Set
lookup: create a Set from existing.key_scopes (e.g., existingScopes) and change
the predicate in the program.key_scopes.some(...) call to use
existingScopes.has(s) instead of existing.key_scopes.includes(s) so the
comparison between program.key_scopes and existing.key_scopes is much faster for
large lists.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/config.ts:
- Around line 19-25: The paths in CONFIG currently contain unexpanded tildes;
Node fs calls will not resolve '~'. Add an expandPath helper in config.ts that
imports homedir from 'os' and replaces a leading '~' (use /^~/) with homedir(),
then use that helper to set CONFIG.paths.root, state, cache, and logs so all
exported paths are expanded before StateManager or other code uses them; ensure
expandPath is used for every path value in the exported CONFIG object.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts:
- Around line 100-105: The code calls
this.github.getLatestCommit(CONFIG.files.domains_txt) but always sets
currentState.last_check and saves state even when latestDomains is
null/undefined; change the flow in the function containing getLatestCommit so
that if latestDomains is falsy you log or throw the error and return early (do
not update currentState.last_check or call this.state.saveState), and only set
currentState.tracked_commits.domains_txt, update currentState.last_check = new
Date().toISOString(), and call this.state.saveState(currentState) when
latestDomains is valid; reference getLatestCommit, CONFIG.files.domains_txt,
currentState.tracked_commits.domains_txt, last_check, and this.state.saveState
when making the change.

---

Nitpick comments:
In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts:
- Line 61: PLATFORM_COUNT is hard-coded and duplicates the platforms array;
change it to derive from the array by replacing the constant usage with
platforms.length (e.g., remove or replace PLATFORM_COUNT declaration and use
platforms.length wherever PLATFORM_COUNT is referenced) and update functions
that rely on it (notably update() and analyzeChanges()) to read the dynamic
value so the count always matches the platforms array.
- Line 202: Replace the O(n) includes check over existing.key_scopes with an
O(1) Set lookup: create a Set from existing.key_scopes (e.g., existingScopes)
and change the predicate in the program.key_scopes.some(...) call to use
existingScopes.has(s) instead of existing.key_scopes.includes(s) so the
comparison between program.key_scopes and existing.key_scopes is much faster for
large lists.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0a2f164c-3590-4daf-a100-b5a445535131

📥 Commits

Reviewing files that changed from the base of the PR and between c730be7 and ec120a3.

📒 Files selected for processing (2)
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/config.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts

- config.ts: add expandPath() helper for tilde expansion, use BASE constant
  for paths to avoid duplication, expand all CONFIG.paths entries
- tracker.ts: extract PLATFORMS as module-level const (replaces magic
  number PLATFORM_COUNT = 4), derive PLATFORM_COUNT via PLATFORMS.length,
  inline platforms ref uses module-level array, use Set.has() instead of
  Array.includes() for O(1) scope dedup
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts (1)

102-107: ⚠️ Potential issue | 🟡 Minor

Fehlerbehandlung bei fehlgeschlagener Commit-Abfrage weiterhin ungelöst.

Wenn getLatestCommit fehlschlägt und null zurückgibt, wird currentState.last_check trotzdem aktualisiert und der State gespeichert. Bei nachfolgenden Updates könnten dadurch Änderungen verpasst werden, da der Zeitstempel voranschreitet, aber der Commit-SHA nicht aktualisiert wurde.

🛡️ Vorgeschlagene Korrektur
     // Update state with latest commits
     const latestDomains = await this.github.getLatestCommit(CONFIG.files.domains_txt);
-    if (latestDomains) {
-      currentState.tracked_commits.domains_txt = latestDomains.sha;
+    if (!latestDomains) {
+      console.warn('⚠️  Konnte neuesten domains.txt Commit nicht abrufen - State nicht aktualisiert');
+      // Return early ohne State-Update, um Datenverlust zu vermeiden
+      return {
+        ...results,
+        total_checked: PLATFORM_COUNT,
+        check_duration_ms: Date.now() - startTime,
+      };
     }
+    currentState.tracked_commits.domains_txt = latestDomains.sha;
     currentState.last_check = new Date().toISOString();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 102 - 107, When getLatestCommit(CONFIG.files.domains_txt) returns null you
must not advance currentState.last_check or persist the state because that would
hide missed updates; modify the block around getLatestCommit in tracker.ts so
that you only set currentState.tracked_commits.domains_txt, update
currentState.last_check, and call this.state.saveState(currentState) when
latestDomains is truthy, and otherwise log or handle the error (e.g., via
this.logger.error) and skip saving so the previous SHA and timestamp remain
intact.
🧹 Nitpick comments (1)
.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts (1)

204-214: Set wird ineffizient innerhalb des .some()-Callbacks erstellt.

Auf Zeile 204 wird new Set(existing.key_scopes) bei jeder Iteration von .some() neu erstellt. Dies führt zu O(n*m) Komplexität statt O(n+m).

♻️ Vorgeschlagene Optimierung
           } else {
+            const existingScopes = new Set(existing.key_scopes);
-            if (program.key_scopes.some(s => !new Set(existing.key_scopes).has(s))) {
+            if (program.key_scopes.some(s => !existingScopes.has(s))) {
               const meta: ProgramMetadata = {
                 ...existing,
                 key_scopes: program.key_scopes,
                 discovered_at: new Date().toISOString(),
                 change_type: 'scope_expansion',
               };

               scopeExpansions.push(meta);
               metadata.set(key, meta);
             }
           }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 204 - 214, Die Erstellung von new Set(existing.key_scopes) passiert in
jedem Callback-Aufruf von program.key_scopes.some, was ineffizient ist; fixiere
das, indem du vor dem Aufruf ein einmaliges Set erstellst (z. B. const
existingScopes = new Set(existing.key_scopes)) und dann existingScopes.has(...)
innerhalb der some‑Callback verwendest, so dass die Prüfung auf
Scope‑Erweiterung in der if‑Bedingung (die den scope_expansion Zweig füllt:
scopeExpansions.push(meta); metadata.set(key, meta);) O(n+m) statt O(n*m) wird.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts:
- Around line 102-107: When getLatestCommit(CONFIG.files.domains_txt) returns
null you must not advance currentState.last_check or persist the state because
that would hide missed updates; modify the block around getLatestCommit in
tracker.ts so that you only set currentState.tracked_commits.domains_txt, update
currentState.last_check, and call this.state.saveState(currentState) when
latestDomains is truthy, and otherwise log or handle the error (e.g., via
this.logger.error) and skip saving so the previous SHA and timestamp remain
intact.

---

Nitpick comments:
In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts:
- Around line 204-214: Die Erstellung von new Set(existing.key_scopes) passiert
in jedem Callback-Aufruf von program.key_scopes.some, was ineffizient ist;
fixiere das, indem du vor dem Aufruf ein einmaliges Set erstellst (z. B. const
existingScopes = new Set(existing.key_scopes)) und dann existingScopes.has(...)
innerhalb der some‑Callback verwendest, so dass die Prüfung auf
Scope‑Erweiterung in der if‑Bedingung (die den scope_expansion Zweig füllt:
scopeExpansions.push(meta); metadata.set(key, meta);) O(n+m) statt O(n*m) wird.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3e06b314-b4ef-4297-b2a6-d9c5c84be85f

📥 Commits

Reviewing files that changed from the base of the PR and between ec120a3 and fe3c683.

📒 Files selected for processing (2)
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/config.ts
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/config.ts

- tracker.ts: move last_check update and saveState inside the latestDomains
  truthy block so a null response from getLatestCommit does not advance the
  checkpoint timestamp or persist stale state; add error log for the null case
- tracker.ts: hoist Set(existing.key_scopes) out of the some() callback into
  a const existingScopes before the conditional, reducing scope-expansion
  check from O(n*m) to O(n+m)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts:
- Around line 103-107: Der aktuelle Checkpoint schreibt global last_check und
damit gekoppelt domains_txt direkt nach dem Fetch von
this.github.getLatestCommit, was zu TOCTOU-Problemen führt; stattdessen benutze
für Plattform-Abfragen den pro-Plattform-Commit-Checkpoint
(currentState.tracked_commits[...] in Kombination mit getCompareDiff) als
Resume-Punkt und schreibe den jeweiligen tracked_commits.domains_txt erst nach
erfolgreicher Fetch/Parse/Verarbeitung dieser Plattform zurück via
this.state.saveState; entferne oder ignoriere die Abfrage-Logik, die Änderungen
seit last_check nutzt, und stelle sicher, dass nur commit-basierte Vergleiche
(getCompareDiff) und nach erfolgreichem Verarbeiten das Update von
currentState.tracked_commits und der anschließende this.state.saveState
erfolgen.
- Around line 197-203: Der aktuelle Upgrade-Pfad baut das meta-Objekt aus
...existing und überschreibt nur offers_bounties, dadurch bleiben Felder wie
key_scopes, max_severity, name oder url veraltet; ändere die Erstellung von meta
so dass es den aktuellen Program-Snapshot widerspiegelt (z.B. spread das
aktuelle program statt existing), behalte discovered_at und setze change_type:
'upgraded_to_paid' und offers_bounties: true; referenziere die Variablen
Programm/ProgramMetadata (meta, existing, program, offers_bounties,
discovered_at, change_type) beim Update, damit der Cache mit dem aktuellen
Programmstand synchronisiert wird.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a27e7f32-cd75-4714-9f08-4c0c66a09cf6

📥 Commits

Reviewing files that changed from the base of the PR and between fe3c683 and 471be00.

📒 Files selected for processing (1)
  • .opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts

Comment on lines +103 to +107
const latestDomains = await this.github.getLatestCommit(CONFIG.files.domains_txt);
if (latestDomains) {
currentState.tracked_commits.domains_txt = latestDomains.sha;
currentState.last_check = new Date().toISOString();
await this.state.saveState(currentState);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Checkpointing nicht an last_check koppeln.

Line 159 fragt Plattformänderungen seit dem globalen Zeitstempel ab, obwohl ihr an Line 227 bereits pro Plattform einen Commit-Checkpoint fortschreibt. Dadurch entsteht ein TOCTOU-Loch: Kommt nach dem Plattform-Check, aber vor Line 106 noch ein Commit rein, wird er beim nächsten Lauf dauerhaft übersprungen. Dasselbe passiert bei partiellen Fetch-/Parse-Fehlern. Nutzt hier den per-Plattform-Checkpoint als Resume-Punkt (z. B. commit-basiert über getCompareDiff) und schreibt ihn erst nach erfolgreicher Verarbeitung der jeweiligen Plattform fort.

Also applies to: 159-162, 225-228

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 103 - 107, Der aktuelle Checkpoint schreibt global last_check und damit
gekoppelt domains_txt direkt nach dem Fetch von this.github.getLatestCommit, was
zu TOCTOU-Problemen führt; stattdessen benutze für Plattform-Abfragen den
pro-Plattform-Commit-Checkpoint (currentState.tracked_commits[...] in
Kombination mit getCompareDiff) als Resume-Punkt und schreibe den jeweiligen
tracked_commits.domains_txt erst nach erfolgreicher Fetch/Parse/Verarbeitung
dieser Plattform zurück via this.state.saveState; entferne oder ignoriere die
Abfrage-Logik, die Änderungen seit last_check nutzt, und stelle sicher, dass nur
commit-basierte Vergleiche (getCompareDiff) und nach erfolgreichem Verarbeiten
das Update von currentState.tracked_commits und der anschließende
this.state.saveState erfolgen.

Comment on lines +197 to +203
if (!existing.offers_bounties && program.offers_bounties) {
const meta: ProgramMetadata = {
...existing,
offers_bounties: true,
discovered_at: new Date().toISOString(),
change_type: 'upgraded_to_paid',
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Metadaten im Upgrade-Pfad mit dem aktuellen Snapshot synchronisieren.

Line 198 startet mit ...existing und übernimmt danach nur offers_bounties. Wenn zwischen zwei Läufen zusätzlich key_scopes, max_severity, name oder url geändert wurden, bleibt der Cache auf dem alten Stand — und wegen des fortgeschriebenen Checkpoints wird das später nicht mehr korrigiert. Selbst wenn ihr nur ein upgraded_to_paid-Event emitten wollt, sollte meta hier den aktuellen Programmsnapshot spiegeln.

💡 Vorschlag
           if (!existing.offers_bounties && program.offers_bounties) {
             const meta: ProgramMetadata = {
               ...existing,
+              name: program.name,
+              url: program.url,
               offers_bounties: true,
+              key_scopes: program.key_scopes,
+              max_severity: program.max_severity,
               discovered_at: new Date().toISOString(),
               change_type: 'upgraded_to_paid',
             };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.opencode/skills/Security/WebAssessment/BugBountyTool/src/tracker.ts around
lines 197 - 203, Der aktuelle Upgrade-Pfad baut das meta-Objekt aus ...existing
und überschreibt nur offers_bounties, dadurch bleiben Felder wie key_scopes,
max_severity, name oder url veraltet; ändere die Erstellung von meta so dass es
den aktuellen Program-Snapshot widerspiegelt (z.B. spread das aktuelle program
statt existing), behalte discovered_at und setze change_type: 'upgraded_to_paid'
und offers_bounties: true; referenziere die Variablen Programm/ProgramMetadata
(meta, existing, program, offers_bounties, discovered_at, change_type) beim
Update, damit der Cache mit dem aktuellen Programmstand synchronisiert wird.

- tracker.ts: spread program instead of existing in the upgraded_to_paid
  branch so that fresh fields (key_scopes, max_severity, name, url) are
  captured in the metadata cache rather than stale values from existing;
  preserve discovered_at and change_type overrides

Skipped: TOCTOU refactor (finding 1) — getCompareDiff exists but the
requested change is an architectural redesign of the two-tier detection
strategy, not a targeted bug fix; current last_check-based approach is
functional and the refactor would introduce more risk than it resolves
@Steffen025 Steffen025 merged commit b159c8a into main Mar 15, 2026
3 checks passed
@Steffen025 Steffen025 deleted the release/v3.0-pr03-skills-thinking-security branch March 15, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant