Compare commits

...

7 Commits

Author SHA1 Message Date
davida-ps f0f0f1db97 fix(clawsec-scanner): release 0.0.2 with real OpenClaw DAST harness (#128)
* fix(clawsec-scanner): ship real openclaw dast harness in 0.0.2

* fix(clawsec-scanner): classify ts harness limits as info coverage

* docs(wiki): add clawsec-scanner module documentation

* docs(release): add clawsec-suite install guidance to quick install text

* docs(readme): clarify standalone installs and suite optionality

* docs(readme): remove standalone quick-install block

* docs(readme): rename skill section and clarify suite start point
2026-03-10 19:27:22 +02:00
dependabot[bot] 687822b6cb chore(deps-dev): bump typescript from 5.8.3 to 5.9.3 (#109)
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.8.3 to 5.9.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.8.3...v5.9.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-10 17:10:33 +02:00
dependabot[bot] e715c8a625 chore(deps): bump actions/setup-node from 6.2.0 to 6.3.0 (#120)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/6044e13b5dc448c55e2357c09f80417699197238...53b83947a5a98c8d113130e565377fae1a50d02f)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-10 16:51:09 +02:00
dependabot[bot] bd54393ed4 chore(deps-dev): bump @types/node from 25.2.3 to 25.4.0 (#125)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.2.3 to 25.4.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 25.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-10 13:59:08 +02:00
dependabot[bot] 0fcc6e6b6d chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 (#107)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-10 13:55:23 +02:00
dependabot[bot] 8d292457fb chore(deps): bump bandit from 1.9.3 to 1.9.4 in /.github (#103)
Bumps [bandit](https://github.com/PyCQA/bandit) from 1.9.3 to 1.9.4.
- [Release notes](https://github.com/PyCQA/bandit/releases)
- [Commits](https://github.com/PyCQA/bandit/compare/1.9.3...1.9.4)

---
updated-dependencies:
- dependency-name: bandit
  dependency-version: 1.9.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-10 13:52:00 +02:00
github-actions[bot] 1cced651a0 chore: CVE advisories - 0 new, 20 updated (#127)
Automated update from NVD CVE feed.
Keywords: OpenClaw clawdbot Moltbot NanoClaw WhatsApp-bot baileys
Poll window: 2026-03-09T06:19:31Z to 2026-03-10T06:12:16.000Z

Co-authored-by: davida-ps <232346510+davida-ps@users.noreply.github.com>
2026-03-10 09:07:06 +02:00
25 changed files with 1495 additions and 495 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
ruff==0.15.2
bandit==1.9.3
bandit==1.9.4
+4 -4
View File
@@ -20,7 +20,7 @@ jobs:
- windows-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
@@ -83,7 +83,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
@@ -98,7 +98,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
@@ -123,7 +123,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
+1 -1
View File
@@ -318,7 +318,7 @@ jobs:
ls -la public/checksums.json public/checksums.sig public/signing-public.pem
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
+1 -1
View File
@@ -89,7 +89,7 @@ jobs:
signature_file: public/checksums.sig
- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '20'
cache: 'npm'
+1 -1
View File
@@ -62,7 +62,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: SARIF file
path: results.sarif
+6 -3
View File
@@ -639,7 +639,7 @@ jobs:
echo "publishable=${PUBLISHABLE}" >> $GITHUB_OUTPUT
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 20
@@ -898,6 +898,9 @@ jobs:
npx clawhub@latest install ${{ steps.parse.outputs.skill_name }}
```
**If you already have `clawsec-suite` installed:**
Ask your agent to pull `${{ steps.parse.outputs.skill_name }}` from the ClawSec catalog and it will handle setup and verification automatically.
**Manual download with verification:**
```bash
# 1. Download the release archive, checksums, and signing material
@@ -1003,7 +1006,7 @@ jobs:
- name: Setup Node
if: needs.release-tag.outputs.publishable == 'true'
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 20
@@ -1159,7 +1162,7 @@ jobs:
echo "Skill is publishable to ClawHub"
- name: Setup Node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 20
+5 -2
View File
@@ -159,7 +159,9 @@ See [`skills/clawsec-nanoclaw/INSTALL.md`](skills/clawsec-nanoclaw/INSTALL.md) f
The **clawsec-suite** is a skill-of-skills manager that installs, verifies, and maintains security skills from the ClawSec catalog.
### Skills in the Suite
`clawsec-suite` is optional orchestration; skills can still be installed directly as standalone packages.
### ClawSec Skills
| Skill | Description | Installation | Compatibility |
|-------|-------------|--------------|---------------|
@@ -433,8 +435,9 @@ npm run build
│ ├── populate-local-wiki.sh # Local wiki llms export populator
│ └── release-skill.sh # Manual skill release helper
├── skills/
│ ├── clawsec-suite/ # 📦 Suite installer (skill-of-skills)
│ ├── clawsec-suite/ # 📦 Suite installer (skill-of-skills - start here and have your agent do the rest)
│ ├── clawsec-feed/ # 📡 Advisory feed skill
│ ├── clawsec-scanner/ # 🔍 Vulnerability scanner (deps + SAST + OpenClaw DAST)
│ ├── clawsec-nanoclaw/ # 📱 NanoClaw platform security suite
│ ├── clawsec-clawhub-checker/ # 🧪 ClawHub reputation checks
│ ├── clawtributor/ # 🤝 Community reporting skill
+27 -9
View File
@@ -1,6 +1,6 @@
{
"version": "0.0.3",
"updated": "2026-03-09T06:19:31Z",
"updated": "2026-03-10T06:12:56Z",
"description": "Community-driven security advisory feed for ClawSec. Automatically updated with OpenClaw-related CVEs from NVD and community-reported security incidents.",
"advisories": [
{
@@ -641,6 +641,7 @@
"title": "OpenClaw versions prior to 2026.2.2 contain a vulnerability in the gateway WebSocket connect handsha...",
"description": "OpenClaw versions prior to 2026.2.2 contain a vulnerability in the gateway WebSocket connect handshake in which it allows skipping device identity checks when auth.token is present but not validated. Attackers can connect to the gateway without providing device identity or pairing by exploiting the presence check instead of validation, potentially gaining operator access in vulnerable deployments.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -746,6 +747,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a webhook routing vulnerability in the Google Chat moni...",
"description": "OpenClaw versions prior to 2026.2.14 contain a webhook routing vulnerability in the Google Chat monitor component that allows cross-account policy context misrouting when multiple webhook targets share the same HTTP path. Attackers can exploit first-match request verification semantics to process inbound webhook events under incorrect account contexts, bypassing intended allowlists and session policies.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -816,6 +818,7 @@
"title": "OpenClaw versions prior to 2026.2.2 contain a server-side request forgery vulnerability in attachmen...",
"description": "OpenClaw versions prior to 2026.2.2 contain a server-side request forgery vulnerability in attachment and media URL hydration that allows remote attackers to fetch arbitrary HTTP(S) URLs. Attackers who can influence media URLs through model-controlled sendAttachment or auto-reply mechanisms can trigger SSRF to internal resources and exfiltrate fetched response bytes as outbound attachments.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -851,6 +854,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a vulnerability in the gateway in which it fails to san...",
"description": "OpenClaw versions prior to 2026.2.14 contain a vulnerability in the gateway in which it fails to sanitize internal approval fields in node.invoke parameters, allowing authenticated clients to bypass exec approval gating for system.run commands. Attackers with valid gateway credentials can inject approval control fields to execute arbitrary commands on connected node hosts, potentially compromising developer workstations and CI runners.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -881,11 +885,12 @@
{
"id": "CVE-2026-28465",
"severity": "medium",
"type": "unknown_cwe_345",
"nvd_category_id": "CWE-345",
"type": "unknown_cwe_290",
"nvd_category_id": "CWE-290",
"title": "OpenClaw's voice-call plugin versions before 2026.2.3 contain an improper authentication vulnerabili...",
"description": "OpenClaw's voice-call plugin versions before 2026.2.3 contain an improper authentication vulnerability in webhook verification that allows remote attackers to bypass verification by supplying untrusted forwarded headers. Attackers can spoof webhook events by manipulating Forwarded or X-Forwarded-* headers in reverse-proxy configurations that implicitly trust these headers.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -921,6 +926,7 @@
"title": "OpenClaw versions prior to 2026.2.12 use non-constant-time string comparison for hook token validati...",
"description": "OpenClaw versions prior to 2026.2.12 use non-constant-time string comparison for hook token validation, allowing attackers to infer tokens through timing measurements. Remote attackers with network access to the hooks endpoint can exploit timing side-channels across multiple requests to gradually determine the authentication token.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -956,6 +962,7 @@
"title": "OpenClaw exec-approvals allowlist validation checks pre-expansion argv tokens but execution uses rea...",
"description": "OpenClaw exec-approvals allowlist validation checks pre-expansion argv tokens but execution uses real shell expansion, allowing safe bins like head, tail, or grep to read arbitrary local files via glob patterns or environment variables. Authorized callers or prompt-injection attacks can exploit this to disclose files readable by the gateway or node process when host execution is enabled in allowlist mode.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -991,6 +998,7 @@
"title": "OpenClaw versions prior to 2026.2.13 contain a vulnerability in the browser control API in which it ...",
"description": "OpenClaw versions prior to 2026.2.13 contain a vulnerability in the browser control API in which it accepts user-supplied output paths for trace and download files without consistently constraining writes to temporary directories. Attackers with API access can exploit path traversal in POST /trace/stop, POST /wait/download, and POST /download endpoints to write files outside intended temp roots.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1026,6 +1034,7 @@
"title": "OpenClaw versions prior to 2026.2.12 fail to validate the sessionFile path parameter, allowing authe...",
"description": "OpenClaw versions prior to 2026.2.12 fail to validate the sessionFile path parameter, allowing authenticated gateway clients to write transcript data to arbitrary locations on the host filesystem. Attackers can supply a sessionFile path outside the sessions directory to create files and append data repeatedly, potentially causing configuration corruption or denial of service.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1061,6 +1070,7 @@
"title": "OpenClaw version 2026.1.20 prior to 2026.2.1 contains a vulnerability in the Browser Relay (extensio...",
"description": "OpenClaw version 2026.1.20 prior to 2026.2.1 contains a vulnerability in the Browser Relay (extension must be installed and enabled) /cdp WebSocket endpoint in which it does not require authentication tokens, allowing websites to connect via loopback and access sensitive data. Attackers can exploit this by connecting to ws://127.0.0.1:18792/cdp to steal session cookies and execute JavaScript in other browser tabs.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1096,6 +1106,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a path traversal vulnerability in sandbox skill mirrori...",
"description": "OpenClaw versions prior to 2026.2.14 contain a path traversal vulnerability in sandbox skill mirroring (must be enabled) that uses the skill frontmatter name parameter unsanitized when copying skills into the sandbox workspace. Attackers who provide a crafted skill package with traversal sequences like ../ or absolute paths in the name field can write files outside the sandbox workspace root directory.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1131,6 +1142,7 @@
"title": "OpenClaw versions 2026.1.5 prior to 2026.2.14 contain a vulnerability in the Gateway in which it doe...",
"description": "OpenClaw versions 2026.1.5 prior to 2026.2.14 contain a vulnerability in the Gateway in which it does not sufficiently constrain configured hook module paths before passing them to dynamic import(), allowing code execution. An attacker with gateway configuration modification access can load and execute unintended local modules in the Node.js process.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1166,6 +1178,7 @@
"title": "OpenClaw versions prior to 2026.2.2 fail to validate webhook secrets in Telegram webhook mode (must ...",
"description": "OpenClaw versions prior to 2026.2.2 fail to validate webhook secrets in Telegram webhook mode (must be enabled), allowing unauthenticated HTTP POST requests to the webhook endpoint that trust attacker-controlled JSON payloads. Remote attackers can forge Telegram updates by spoofing message.from.id and chat.id fields to bypass sender allowlists and execute privileged bot commands.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1201,6 +1214,7 @@
"title": "OpenClaw versions prior to 2026.2.14 fail to validate TAR archive entry paths during extraction, all...",
"description": "OpenClaw versions prior to 2026.2.14 fail to validate TAR archive entry paths during extraction, allowing path traversal sequences to write files outside the intended directory. Attackers can craft malicious archives with traversal sequences like ../../ to write files outside extraction boundaries, potentially enabling configuration tampering and code execution.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1236,6 +1250,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a denial of service vulnerability in the extractArchive...",
"description": "OpenClaw versions prior to 2026.2.14 contain a denial of service vulnerability in the extractArchive function within src/infra/archive.ts that allows attackers to consume excessive CPU, memory, and disk resources through high-expansion ZIP and TAR archives. Remote attackers can trigger resource exhaustion by providing maliciously crafted archive files during install or update operations, causing service degradation or system unavailability.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1266,8 +1281,8 @@
{
"id": "CVE-2026-28451",
"severity": "high",
"type": "unspecified_weakness",
"nvd_category_id": null,
"type": "server_side_request_forgery",
"nvd_category_id": "CWE-918",
"title": "OpenClaw versions prior to 2026.2.14 contain server-side request forgery vulnerabilities in the Feis...",
"description": "OpenClaw versions prior to 2026.2.14 contain server-side request forgery vulnerabilities in the Feishu extension that allow attackers to fetch attacker-controlled remote URLs without SSRF protections via sendMediaFeishu function and markdown image processing. Attackers can influence tool calls through direct manipulation or prompt injection to trigger requests to internal services and re-upload responses as Feishu media.",
"affected": [
@@ -1301,8 +1316,8 @@
{
"id": "CVE-2026-28450",
"severity": "medium",
"type": "unspecified_weakness",
"nvd_category_id": null,
"type": "missing_authentication_for_critical_function",
"nvd_category_id": "CWE-306",
"title": "OpenClaw versions prior to 2026.2.12 with the optional Nostr plugin enabled expose unauthenticated H...",
"description": "OpenClaw versions prior to 2026.2.12 with the optional Nostr plugin enabled expose unauthenticated HTTP endpoints at /api/channels/nostr/:accountId/profile and /api/channels/nostr/:accountId/profile/import that allow reading and modifying Nostr profiles without gateway authentication. Remote attackers can exploit these endpoints to read sensitive profile data, modify Nostr profiles, persist malicious changes to gateway configuration, and publish signed Nostr events using the bot's private key when the gateway HTTP port is accessible beyond localhost.",
"affected": [
@@ -1446,6 +1461,7 @@
"title": "OpenClaw version 2026.1.14-1 prior to 2026.2.12 contain an improper network binding vulnerability in...",
"description": "OpenClaw version 2026.1.14-1 prior to 2026.2.12 contain an improper network binding vulnerability in the Chrome extension (must be installed and enabled) relay server that treats wildcard hosts as loopback addresses, allowing the relay HTTP/WS server to bind to all interfaces when a wildcard cdpUrl is configured. Remote attackers can access relay HTTP endpoints off-host to leak service presence and port information, or conduct denial-of-service and brute-force attacks against the relay token header.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1481,6 +1497,7 @@
"title": "OpenClaw versions prior to 2026.2.15 contain a denial of service vulnerability in the web_fetch tool...",
"description": "OpenClaw versions prior to 2026.2.15 contain a denial of service vulnerability in the web_fetch tool that allows attackers to crash the Gateway process through memory exhaustion by parsing oversized or deeply nested HTML responses. Remote attackers can social-engineer users into fetching malicious URLs with pathological HTML structures to exhaust server memory and cause service unavailability.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1581,11 +1598,12 @@
{
"id": "CVE-2026-28391",
"severity": "critical",
"type": "unspecified_weakness",
"nvd_category_id": null,
"type": "os_command_injection",
"nvd_category_id": "CWE-78",
"title": "OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe metacharacters in allo...",
"description": "OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe metacharacters in allowlist-gated exec requests (non-default configuration), allowing attackers to bypass command approval restrictions. Remote attackers can craft command strings with shell metacharacters like & or %...% to execute unapproved commands beyond the allowlisted operations.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
+1 -1
View File
@@ -1 +1 @@
qNd1mJmbXNyIP+5CjBppoCIDu0PNRWYNFWpmzgtIFPJ6P62epcDaQKgi+dTDRUbk8jANIb+Ukf8vk+iz3CrIDg==
t39IWpreVBdG2SDMBYrKw3On1UlrimlglhnIiBzvfXTV2gBvxOI815tHsGqfMWsRTvZ6gqbTO1njQy44392pBQ==
+13 -11
View File
@@ -18,7 +18,7 @@
},
"devDependencies": {
"@eslint/js": "~9.28.0",
"@types/node": "^25.2.3",
"@types/node": "^25.4.0",
"@typescript-eslint/eslint-plugin": "^8.55.0",
"@typescript-eslint/parser": "^8.56.0",
"@vitejs/plugin-react": "^5.1.4",
@@ -26,7 +26,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"fast-check": "^4.5.3",
"typescript": "~5.8.2",
"typescript": "~5.9.3",
"vite": "^7.3.1"
}
},
@@ -1357,13 +1357,13 @@
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="
},
"node_modules/@types/node": {
"version": "25.2.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz",
"integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==",
"version": "25.4.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.4.0.tgz",
"integrity": "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
"undici-types": "~7.18.0"
}
},
"node_modules/@types/react": {
@@ -5629,9 +5629,11 @@
}
},
"node_modules/typescript": {
"version": "5.8.3",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -5658,9 +5660,9 @@
}
},
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"dev": true,
"license": "MIT"
},
+2 -2
View File
@@ -23,7 +23,7 @@
},
"devDependencies": {
"@eslint/js": "~9.28.0",
"@types/node": "^25.2.3",
"@types/node": "^25.4.0",
"@typescript-eslint/eslint-plugin": "^8.55.0",
"@typescript-eslint/parser": "^8.56.0",
"@vitejs/plugin-react": "^5.1.4",
@@ -31,7 +31,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"fast-check": "^4.5.3",
"typescript": "~5.8.2",
"typescript": "~5.9.3",
"vite": "^7.3.1"
},
"overrides": {
+27 -9
View File
@@ -1,6 +1,6 @@
{
"version": "0.0.3",
"updated": "2026-03-09T06:19:31Z",
"updated": "2026-03-10T06:12:56Z",
"description": "Community-driven security advisory feed for ClawSec. Automatically updated with OpenClaw-related CVEs from NVD and community-reported security incidents.",
"advisories": [
{
@@ -641,6 +641,7 @@
"title": "OpenClaw versions prior to 2026.2.2 contain a vulnerability in the gateway WebSocket connect handsha...",
"description": "OpenClaw versions prior to 2026.2.2 contain a vulnerability in the gateway WebSocket connect handshake in which it allows skipping device identity checks when auth.token is present but not validated. Attackers can connect to the gateway without providing device identity or pairing by exploiting the presence check instead of validation, potentially gaining operator access in vulnerable deployments.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -746,6 +747,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a webhook routing vulnerability in the Google Chat moni...",
"description": "OpenClaw versions prior to 2026.2.14 contain a webhook routing vulnerability in the Google Chat monitor component that allows cross-account policy context misrouting when multiple webhook targets share the same HTTP path. Attackers can exploit first-match request verification semantics to process inbound webhook events under incorrect account contexts, bypassing intended allowlists and session policies.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -816,6 +818,7 @@
"title": "OpenClaw versions prior to 2026.2.2 contain a server-side request forgery vulnerability in attachmen...",
"description": "OpenClaw versions prior to 2026.2.2 contain a server-side request forgery vulnerability in attachment and media URL hydration that allows remote attackers to fetch arbitrary HTTP(S) URLs. Attackers who can influence media URLs through model-controlled sendAttachment or auto-reply mechanisms can trigger SSRF to internal resources and exfiltrate fetched response bytes as outbound attachments.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -851,6 +854,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a vulnerability in the gateway in which it fails to san...",
"description": "OpenClaw versions prior to 2026.2.14 contain a vulnerability in the gateway in which it fails to sanitize internal approval fields in node.invoke parameters, allowing authenticated clients to bypass exec approval gating for system.run commands. Attackers with valid gateway credentials can inject approval control fields to execute arbitrary commands on connected node hosts, potentially compromising developer workstations and CI runners.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -881,11 +885,12 @@
{
"id": "CVE-2026-28465",
"severity": "medium",
"type": "unknown_cwe_345",
"nvd_category_id": "CWE-345",
"type": "unknown_cwe_290",
"nvd_category_id": "CWE-290",
"title": "OpenClaw's voice-call plugin versions before 2026.2.3 contain an improper authentication vulnerabili...",
"description": "OpenClaw's voice-call plugin versions before 2026.2.3 contain an improper authentication vulnerability in webhook verification that allows remote attackers to bypass verification by supplying untrusted forwarded headers. Attackers can spoof webhook events by manipulating Forwarded or X-Forwarded-* headers in reverse-proxy configurations that implicitly trust these headers.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -921,6 +926,7 @@
"title": "OpenClaw versions prior to 2026.2.12 use non-constant-time string comparison for hook token validati...",
"description": "OpenClaw versions prior to 2026.2.12 use non-constant-time string comparison for hook token validation, allowing attackers to infer tokens through timing measurements. Remote attackers with network access to the hooks endpoint can exploit timing side-channels across multiple requests to gradually determine the authentication token.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -956,6 +962,7 @@
"title": "OpenClaw exec-approvals allowlist validation checks pre-expansion argv tokens but execution uses rea...",
"description": "OpenClaw exec-approvals allowlist validation checks pre-expansion argv tokens but execution uses real shell expansion, allowing safe bins like head, tail, or grep to read arbitrary local files via glob patterns or environment variables. Authorized callers or prompt-injection attacks can exploit this to disclose files readable by the gateway or node process when host execution is enabled in allowlist mode.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -991,6 +998,7 @@
"title": "OpenClaw versions prior to 2026.2.13 contain a vulnerability in the browser control API in which it ...",
"description": "OpenClaw versions prior to 2026.2.13 contain a vulnerability in the browser control API in which it accepts user-supplied output paths for trace and download files without consistently constraining writes to temporary directories. Attackers with API access can exploit path traversal in POST /trace/stop, POST /wait/download, and POST /download endpoints to write files outside intended temp roots.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1026,6 +1034,7 @@
"title": "OpenClaw versions prior to 2026.2.12 fail to validate the sessionFile path parameter, allowing authe...",
"description": "OpenClaw versions prior to 2026.2.12 fail to validate the sessionFile path parameter, allowing authenticated gateway clients to write transcript data to arbitrary locations on the host filesystem. Attackers can supply a sessionFile path outside the sessions directory to create files and append data repeatedly, potentially causing configuration corruption or denial of service.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1061,6 +1070,7 @@
"title": "OpenClaw version 2026.1.20 prior to 2026.2.1 contains a vulnerability in the Browser Relay (extensio...",
"description": "OpenClaw version 2026.1.20 prior to 2026.2.1 contains a vulnerability in the Browser Relay (extension must be installed and enabled) /cdp WebSocket endpoint in which it does not require authentication tokens, allowing websites to connect via loopback and access sensitive data. Attackers can exploit this by connecting to ws://127.0.0.1:18792/cdp to steal session cookies and execute JavaScript in other browser tabs.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1096,6 +1106,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a path traversal vulnerability in sandbox skill mirrori...",
"description": "OpenClaw versions prior to 2026.2.14 contain a path traversal vulnerability in sandbox skill mirroring (must be enabled) that uses the skill frontmatter name parameter unsanitized when copying skills into the sandbox workspace. Attackers who provide a crafted skill package with traversal sequences like ../ or absolute paths in the name field can write files outside the sandbox workspace root directory.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1131,6 +1142,7 @@
"title": "OpenClaw versions 2026.1.5 prior to 2026.2.14 contain a vulnerability in the Gateway in which it doe...",
"description": "OpenClaw versions 2026.1.5 prior to 2026.2.14 contain a vulnerability in the Gateway in which it does not sufficiently constrain configured hook module paths before passing them to dynamic import(), allowing code execution. An attacker with gateway configuration modification access can load and execute unintended local modules in the Node.js process.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1166,6 +1178,7 @@
"title": "OpenClaw versions prior to 2026.2.2 fail to validate webhook secrets in Telegram webhook mode (must ...",
"description": "OpenClaw versions prior to 2026.2.2 fail to validate webhook secrets in Telegram webhook mode (must be enabled), allowing unauthenticated HTTP POST requests to the webhook endpoint that trust attacker-controlled JSON payloads. Remote attackers can forge Telegram updates by spoofing message.from.id and chat.id fields to bypass sender allowlists and execute privileged bot commands.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1201,6 +1214,7 @@
"title": "OpenClaw versions prior to 2026.2.14 fail to validate TAR archive entry paths during extraction, all...",
"description": "OpenClaw versions prior to 2026.2.14 fail to validate TAR archive entry paths during extraction, allowing path traversal sequences to write files outside the intended directory. Attackers can craft malicious archives with traversal sequences like ../../ to write files outside extraction boundaries, potentially enabling configuration tampering and code execution.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1236,6 +1250,7 @@
"title": "OpenClaw versions prior to 2026.2.14 contain a denial of service vulnerability in the extractArchive...",
"description": "OpenClaw versions prior to 2026.2.14 contain a denial of service vulnerability in the extractArchive function within src/infra/archive.ts that allows attackers to consume excessive CPU, memory, and disk resources through high-expansion ZIP and TAR archives. Remote attackers can trigger resource exhaustion by providing maliciously crafted archive files during install or update operations, causing service degradation or system unavailability.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1266,8 +1281,8 @@
{
"id": "CVE-2026-28451",
"severity": "high",
"type": "unspecified_weakness",
"nvd_category_id": null,
"type": "server_side_request_forgery",
"nvd_category_id": "CWE-918",
"title": "OpenClaw versions prior to 2026.2.14 contain server-side request forgery vulnerabilities in the Feis...",
"description": "OpenClaw versions prior to 2026.2.14 contain server-side request forgery vulnerabilities in the Feishu extension that allow attackers to fetch attacker-controlled remote URLs without SSRF protections via sendMediaFeishu function and markdown image processing. Attackers can influence tool calls through direct manipulation or prompt injection to trigger requests to internal services and re-upload responses as Feishu media.",
"affected": [
@@ -1301,8 +1316,8 @@
{
"id": "CVE-2026-28450",
"severity": "medium",
"type": "unspecified_weakness",
"nvd_category_id": null,
"type": "missing_authentication_for_critical_function",
"nvd_category_id": "CWE-306",
"title": "OpenClaw versions prior to 2026.2.12 with the optional Nostr plugin enabled expose unauthenticated H...",
"description": "OpenClaw versions prior to 2026.2.12 with the optional Nostr plugin enabled expose unauthenticated HTTP endpoints at /api/channels/nostr/:accountId/profile and /api/channels/nostr/:accountId/profile/import that allow reading and modifying Nostr profiles without gateway authentication. Remote attackers can exploit these endpoints to read sensitive profile data, modify Nostr profiles, persist malicious changes to gateway configuration, and publish signed Nostr events using the bot's private key when the gateway HTTP port is accessible beyond localhost.",
"affected": [
@@ -1446,6 +1461,7 @@
"title": "OpenClaw version 2026.1.14-1 prior to 2026.2.12 contain an improper network binding vulnerability in...",
"description": "OpenClaw version 2026.1.14-1 prior to 2026.2.12 contain an improper network binding vulnerability in the Chrome extension (must be installed and enabled) relay server that treats wildcard hosts as loopback addresses, allowing the relay HTTP/WS server to bind to all interfaces when a wildcard cdpUrl is configured. Remote attackers can access relay HTTP endpoints off-host to leak service presence and port information, or conduct denial-of-service and brute-force attacks against the relay token header.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1481,6 +1497,7 @@
"title": "OpenClaw versions prior to 2026.2.15 contain a denial of service vulnerability in the web_fetch tool...",
"description": "OpenClaw versions prior to 2026.2.15 contain a denial of service vulnerability in the web_fetch tool that allows attackers to crash the Gateway process through memory exhaustion by parsing oversized or deeply nested HTML responses. Remote attackers can social-engineer users into fetching malicious URLs with pathological HTML structures to exhaust server memory and cause service unavailability.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
@@ -1581,11 +1598,12 @@
{
"id": "CVE-2026-28391",
"severity": "critical",
"type": "unspecified_weakness",
"nvd_category_id": null,
"type": "os_command_injection",
"nvd_category_id": "CWE-78",
"title": "OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe metacharacters in allo...",
"description": "OpenClaw versions prior to 2026.2.2 fail to properly validate Windows cmd.exe metacharacters in allowlist-gated exec requests (non-default configuration), allowing attackers to bypass command approval restrictions. Remote attackers can craft command strings with shell metacharacters like & or %...% to execute unapproved commands beyond the allowlisted operations.",
"affected": [
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*",
"openclaw@*"
],
"platforms": [
+1 -1
View File
@@ -1 +1 @@
qNd1mJmbXNyIP+5CjBppoCIDu0PNRWYNFWpmzgtIFPJ6P62epcDaQKgi+dTDRUbk8jANIb+Ukf8vk+iz3CrIDg==
t39IWpreVBdG2SDMBYrKw3On1UlrimlglhnIiBzvfXTV2gBvxOI815tHsGqfMWsRTvZ6gqbTO1njQy44392pBQ==
+14
View File
@@ -5,6 +5,20 @@ All notable changes to the ClawSec Scanner will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.0.2] - 2026-03-10
### Changed
- Replaced simulated DAST checks with real OpenClaw hook execution harness testing
- Updated DAST semantics so high-severity findings are emitted for actual hook execution failures/timeouts, not static payload pattern matches
- Reclassified DAST harness capability limitations (for example missing TypeScript compiler for `.ts` hooks) to `info` coverage findings instead of high severity
- Added DAST harness mode guard to prevent recursive scanner execution when hook handlers are tested in isolation
### Added
- New DAST helper executor script for isolated per-hook execution and timeout enforcement
- DAST harness regression tests covering no-false-positive baseline and malicious-input crash detection
## [0.0.1] - 2026-02-27
### Added
+16 -8
View File
@@ -1,7 +1,7 @@
---
name: clawsec-scanner
version: 0.0.1
description: Automated vulnerability scanner for agent platforms. Performs dependency scanning (npm audit, pip-audit), multi-database CVE lookup (OSV, NVD, GitHub Advisory), SAST analysis (Semgrep, Bandit), and basic DAST security testing for skill hooks.
version: 0.0.2
description: Automated vulnerability scanner for agent platforms. Performs dependency scanning (npm audit, pip-audit), multi-database CVE lookup (OSV, NVD, GitHub Advisory), SAST analysis (Semgrep, Bandit), and agent-specific DAST hook execution testing for OpenClaw hooks.
homepage: https://clawsec.prompt.security
clawdis:
emoji: "🔍"
@@ -16,7 +16,7 @@ Comprehensive security scanner for agent platforms that automates vulnerability
- **Dependency Scanning**: Analyzes npm and Python dependencies using `npm audit` and `pip-audit` with structured JSON output parsing
- **CVE Database Integration**: Queries OSV (primary), NVD 2.0, and GitHub Advisory Database for vulnerability enrichment
- **SAST Analysis**: Static code analysis using Semgrep (JavaScript/TypeScript) and Bandit (Python) to detect hardcoded secrets, command injection, path traversal, and unsafe deserialization
- **DAST Framework**: Basic dynamic analysis for skill hook security testing (input validation, timeout enforcement)
- **DAST Framework**: Agent-specific dynamic analysis with real OpenClaw hook execution harness (malicious input, timeout, output bounds, event mutation safety)
- **Unified Reporting**: Consolidated vulnerability reports with severity classification and remediation guidance
- **Continuous Monitoring**: OpenClaw hook integration for automated periodic scanning
@@ -43,8 +43,8 @@ The scanner orchestrates four complementary scan types to provide comprehensive
- Identifies: hardcoded secrets (API keys, tokens), command injection (`eval`, `exec`), path traversal, unsafe deserialization
4. **Dynamic Analysis (DAST)**
- Test framework for skill hook security validation
- Verifies: malicious input handling, timeout enforcement, resource limits
- Real hook execution harness for OpenClaw hook handlers discovered from `HOOK.md` metadata
- Verifies: malicious input resilience, timeout behavior, output amplification bounds, and core event mutation safety
- Note: Traditional web DAST tools (ZAP, Burp) do not apply to agent platforms - this provides agent-specific testing
### Unified Reporting
@@ -248,7 +248,8 @@ scripts/runner.sh # Orchestration layer
├── scan_dependencies.mjs # npm audit + pip-audit
├── query_cve_databases.mjs # OSV/NVD/GitHub API queries
├── sast_analyzer.mjs # Semgrep + Bandit static analysis
── dast_runner.mjs # Dynamic security testing
── dast_runner.mjs # Dynamic security testing orchestration
└── dast_hook_executor.mjs # Isolated real hook execution harness
lib/
├── report.mjs # Result aggregation and formatting
@@ -325,6 +326,11 @@ proc.on('close', code => {
- Requires Python 3.8+ runtime
- Alternative: use Docker image `returntocorp/semgrep`
**"TypeScript hook not executable in DAST harness"**
- The DAST harness executes real hook handlers and transpiles `handler.ts` files when a TypeScript compiler is available
- Install TypeScript in the scanner environment: `npm install -D typescript` (or provide `handler.js`/`handler.mjs`)
- Without a compiler, scanner reports an `info`-level coverage finding instead of a high-severity vulnerability
**"Concurrent scan detected"**
- Lockfile exists: `/tmp/clawsec-scanner.lock`
- Wait for running scan to complete or manually remove lockfile
@@ -342,6 +348,7 @@ Check scanner is working correctly:
node test/dependency_scanner.test.mjs
node test/cve_integration.test.mjs
node test/sast_engine.test.mjs
node test/dast_harness.test.mjs
# Validate skill structure
python ../../utils/validate_skill.py .
@@ -364,6 +371,7 @@ done
node test/dependency_scanner.test.mjs # Dependency scanning
node test/cve_integration.test.mjs # CVE database APIs
node test/sast_engine.test.mjs # Static analysis
node test/dast_harness.test.mjs # DAST harness execution
```
### Linting
@@ -448,11 +456,11 @@ npx clawhub@latest install clawsec-suite
## Roadmap
### v0.1.0 (Current)
### v0.0.2 (Current)
- [x] Dependency scanning (npm audit, pip-audit)
- [x] CVE database integration (OSV, NVD, GitHub Advisory)
- [x] SAST analysis (Semgrep, Bandit)
- [x] Basic DAST framework for skill hooks
- [x] Real OpenClaw hook execution harness for DAST
- [x] Unified JSON reporting
- [x] OpenClaw hook integration
@@ -20,7 +20,7 @@ The hook orchestrates four independent scanning engines:
1. **Dependency Scanning**: Executes `npm audit` and `pip-audit` to detect known vulnerabilities in JavaScript and Python dependencies
2. **SAST (Static Analysis)**: Runs Semgrep (JS/TS) and Bandit (Python) to detect security issues like hardcoded secrets, command injection, and path traversal
3. **CVE Database Lookup**: Queries OSV API (primary), NVD 2.0 (optional), and GitHub Advisory Database (optional) for vulnerability enrichment
4. **DAST (Dynamic Analysis)**: Tests skill hook security including input validation, timeout enforcement, and resource limits
4. **DAST (Dynamic Analysis)**: Executes real OpenClaw hook handlers in an isolated harness and tests malicious-input resilience, timeout behavior, output bounds, and event mutation safety
## Safety Contract
@@ -196,6 +196,11 @@ function buildAlertMessage(report: ScanReport, format: string): string {
}
const handler = async (event: HookEvent, _context: HookContext): Promise<void> => {
// DAST harness mode executes hook handlers directly; skip recursive scanner runs.
if (process.env.CLAWSEC_DAST_HARNESS === "1" || _context?.dastMode === true) {
return;
}
if (!shouldHandleEvent(event)) return;
const installRoot = configuredPath(
@@ -0,0 +1,273 @@
#!/usr/bin/env node
import fs from "node:fs/promises";
import path from "node:path";
import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";
function parseArgs(argv) {
const parsed = {
handler: "",
exportName: "default",
eventB64: "",
contextB64: "",
};
for (let i = 0; i < argv.length; i += 1) {
const token = argv[i];
if (token === "--handler") {
parsed.handler = String(argv[i + 1] ?? "").trim();
i += 1;
continue;
}
if (token === "--export") {
parsed.exportName = String(argv[i + 1] ?? "default").trim() || "default";
i += 1;
continue;
}
if (token === "--event") {
parsed.eventB64 = String(argv[i + 1] ?? "").trim();
i += 1;
continue;
}
if (token === "--context") {
parsed.contextB64 = String(argv[i + 1] ?? "").trim();
i += 1;
continue;
}
throw new Error(`Unknown argument: ${token}`);
}
if (!parsed.handler) {
throw new Error("Missing required --handler");
}
if (!parsed.eventB64) {
throw new Error("Missing required --event");
}
if (!parsed.contextB64) {
throw new Error("Missing required --context");
}
return parsed;
}
function decodeBase64Json(value, label) {
try {
const decoded = Buffer.from(value, "base64").toString("utf8");
return JSON.parse(decoded);
} catch (error) {
throw new Error(`Failed to decode ${label}: ${error instanceof Error ? error.message : String(error)}`);
}
}
async function fileExists(filePath) {
try {
await fs.access(filePath);
return true;
} catch {
return false;
}
}
async function loadTypeScriptCompiler() {
if (process.env.CLAWSEC_DAST_DISABLE_TYPESCRIPT === "1") {
return null;
}
try {
const imported = await import("typescript");
return imported.default || imported;
} catch {
// Ignore and try require path next.
}
try {
const req = createRequire(import.meta.url);
return req("typescript");
} catch {
return null;
}
}
async function importTypeScriptModule(tsPath) {
const tsCompiler = await loadTypeScriptCompiler();
if (!tsCompiler || typeof tsCompiler.transpileModule !== "function") {
throw new Error(
`Cannot execute TypeScript hook (${tsPath}): typescript compiler not available. ` +
"Install 'typescript' or provide a JavaScript handler file.",
);
}
const source = await fs.readFile(tsPath, "utf8");
const transpiled = tsCompiler.transpileModule(source, {
compilerOptions: {
module: tsCompiler.ModuleKind.ESNext,
target: tsCompiler.ScriptTarget.ES2022,
moduleResolution: tsCompiler.ModuleResolutionKind.NodeNext,
esModuleInterop: true,
sourceMap: false,
inlineSourceMap: false,
declaration: false,
},
fileName: tsPath,
reportDiagnostics: false,
});
const tempFile = path.join(
path.dirname(tsPath),
`.clawsec-dast-${path.basename(tsPath, ".ts")}-${process.pid}-${Date.now()}.mjs`,
);
await fs.writeFile(tempFile, transpiled.outputText, "utf8");
try {
return await import(`${pathToFileURL(tempFile).href}?ts=${Date.now()}`);
} finally {
try {
await fs.unlink(tempFile);
} catch {
// best-effort cleanup
}
}
}
async function loadHookModule(handlerPath) {
const fullPath = path.resolve(handlerPath);
const exists = await fileExists(fullPath);
if (!exists) {
throw new Error(`Hook handler does not exist: ${fullPath}`);
}
const ext = path.extname(fullPath).toLowerCase();
if (ext === ".ts") {
return importTypeScriptModule(fullPath);
}
return import(`${pathToFileURL(fullPath).href}?v=${Date.now()}`);
}
function resolveHandlerExport(mod, exportName) {
if (exportName && exportName !== "default") {
if (typeof mod?.[exportName] === "function") {
return mod[exportName];
}
throw new Error(`Hook export '${exportName}' is not a function`);
}
if (typeof mod?.default === "function") {
return mod.default;
}
if (typeof mod?.handler === "function") {
return mod.handler;
}
throw new Error("Hook module does not export a handler function");
}
function normalizeTimestamp(event) {
const timestamp = event?.timestamp;
if (typeof timestamp === "string" || typeof timestamp === "number") {
const parsed = new Date(timestamp);
if (!Number.isNaN(parsed.getTime())) {
event.timestamp = parsed;
}
}
}
function summarizeMessages(messages) {
if (!Array.isArray(messages)) {
return {
count: 0,
charCount: 0,
};
}
let charCount = 0;
for (const message of messages) {
if (typeof message === "string") {
charCount += message.length;
continue;
}
try {
charCount += JSON.stringify(message).length;
} catch {
charCount += 0;
}
}
return {
count: messages.length,
charCount,
};
}
function coreEventShape(event) {
return {
type: event?.type ?? null,
action: event?.action ?? null,
sessionKey: event?.sessionKey ?? null,
};
}
async function main() {
const args = parseArgs(process.argv.slice(2));
const event = decodeBase64Json(args.eventB64, "event payload");
const context = decodeBase64Json(args.contextB64, "context payload");
normalizeTimestamp(event);
const startedAt = Date.now();
const before = coreEventShape(event);
try {
const mod = await loadHookModule(args.handler);
const handler = resolveHandlerExport(mod, args.exportName);
await handler(event, context);
const after = coreEventShape(event);
const messageSummary = summarizeMessages(event?.messages);
const payload = {
ok: true,
duration_ms: Date.now() - startedAt,
core_before: before,
core_after: after,
messages_count: messageSummary.count,
messages_char_count: messageSummary.charCount,
};
process.stdout.write(JSON.stringify(payload));
} catch (error) {
const after = coreEventShape(event);
const messageSummary = summarizeMessages(event?.messages);
const payload = {
ok: false,
duration_ms: Date.now() - startedAt,
core_before: before,
core_after: after,
messages_count: messageSummary.count,
messages_char_count: messageSummary.charCount,
error: error instanceof Error ? error.message : String(error),
};
process.stdout.write(JSON.stringify(payload));
}
}
main().catch((error) => {
process.stderr.write(`${error instanceof Error ? error.stack || error.message : String(error)}\n`);
process.exit(1);
});
File diff suppressed because it is too large Load Diff
@@ -73,6 +73,7 @@ function assertSourceHookExists() {
"scripts/scan_dependencies.mjs",
"scripts/sast_analyzer.mjs",
"scripts/dast_runner.mjs",
"scripts/dast_hook_executor.mjs",
"scripts/query_cve_databases.mjs",
];
for (const file of requiredScripts) {
+13 -3
View File
@@ -1,7 +1,7 @@
{
"name": "clawsec-scanner",
"version": "0.0.1",
"description": "Automated vulnerability scanner for agent platforms. Performs dependency scanning (npm audit, pip-audit), multi-database CVE lookup (OSV, NVD, GitHub Advisory), SAST analysis (Semgrep, Bandit), and basic DAST security testing for skill hooks.",
"version": "0.0.2",
"description": "Automated vulnerability scanner for agent platforms. Performs dependency scanning (npm audit, pip-audit), multi-database CVE lookup (OSV, NVD, GitHub Advisory), SAST analysis (Semgrep, Bandit), and agent-specific DAST hook execution testing for OpenClaw hooks.",
"author": "prompt-security",
"license": "AGPL-3.0-or-later",
"homepage": "https://clawsec.prompt.security/",
@@ -57,7 +57,12 @@
{
"path": "scripts/dast_runner.mjs",
"required": true,
"description": "Dynamic analysis framework for skill hook security testing"
"description": "Dynamic analysis harness executing OpenClaw hook handlers with malicious-input and timeout checks"
},
{
"path": "scripts/dast_hook_executor.mjs",
"required": true,
"description": "Isolated hook execution helper used by DAST for real OpenClaw harness testing"
},
{
"path": "scripts/setup_scanner_hook.mjs",
@@ -103,6 +108,11 @@
"path": "test/sast_engine.test.mjs",
"required": false,
"description": "Unit tests for SAST analysis (Semgrep, Bandit)"
},
{
"path": "test/dast_harness.test.mjs",
"required": false,
"description": "DAST harness tests for real hook execution and malicious-input failure detection"
}
]
},
@@ -0,0 +1,250 @@
#!/usr/bin/env node
import fs from "node:fs/promises";
import path from "node:path";
import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";
import {
pass,
fail,
report,
exitWithResults,
createTempDir,
} from "./lib/test_harness.mjs";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const SKILL_ROOT = path.resolve(__dirname, "..");
const DAST_SCRIPT = path.join(SKILL_ROOT, "scripts", "dast_runner.mjs");
/**
* @param {string} targetPath
* @param {number} timeoutMs
* @param {Record<string, string>} envOverrides
* @returns {Promise<{code: number, stdout: string, stderr: string, report: any}>}
*/
async function runDast(targetPath, timeoutMs = 3000, envOverrides = {}) {
return new Promise((resolve, reject) => {
const proc = spawn(
"node",
[DAST_SCRIPT, "--target", targetPath, "--format", "json", "--timeout", String(timeoutMs)],
{
cwd: SKILL_ROOT,
stdio: ["ignore", "pipe", "pipe"],
env: {
...process.env,
...envOverrides,
},
},
);
let stdout = "";
let stderr = "";
proc.stdout.on("data", (chunk) => {
stdout += String(chunk);
});
proc.stderr.on("data", (chunk) => {
stderr += String(chunk);
});
proc.on("error", reject);
proc.on("close", (code) => {
try {
const parsed = JSON.parse(stdout.trim());
resolve({
code: code ?? 1,
stdout,
stderr,
report: parsed,
});
} catch (error) {
reject(new Error(`Failed to parse DAST JSON output: ${String(error)}\nSTDOUT:\n${stdout}\nSTDERR:\n${stderr}`));
}
});
});
}
/**
* @param {string} hookDir
* @param {string} eventsLiteral
* @param {string} handlerSource
* @param {string} [handlerFile]
* @returns {Promise<void>}
*/
async function writeHookFixture(hookDir, eventsLiteral, handlerSource, handlerFile = "handler.js") {
await fs.mkdir(hookDir, { recursive: true });
const hookMd = `---
name: ${path.basename(hookDir)}
description: fixture hook
metadata: { "openclaw": { "events": [${eventsLiteral}] } }
---
# Fixture Hook
`;
await fs.writeFile(path.join(hookDir, "HOOK.md"), hookMd, "utf8");
await fs.writeFile(path.join(hookDir, handlerFile), handlerSource, "utf8");
}
async function testSafeHookExecutesAndDoesNotReportMisleadingHigh() {
const testName = "DAST harness: executes real hook and reports no misleading high findings";
const tmp = await createTempDir();
try {
const targetPath = path.join(tmp.path, "skill");
const hookDir = path.join(targetPath, "hooks", "safe-hook");
const markerFile = path.join(hookDir, "executed.marker");
await writeHookFixture(
hookDir,
'"command:new"',
`import fs from "node:fs/promises";
import path from "node:path";
const handler = async (event, context) => {
const marker = path.join(path.dirname(new URL(import.meta.url).pathname), "executed.marker");
await fs.writeFile(marker, String(context?.event || "unknown"), "utf8");
if (!Array.isArray(event.messages)) {
event.messages = [];
}
event.messages.push("hook executed");
};
export default handler;
`,
);
const result = await runDast(targetPath, 2500);
const markerExists = await fs
.access(markerFile)
.then(() => true)
.catch(() => false);
const cleanSummary =
result.report?.summary?.critical === 0
&& result.report?.summary?.high === 0
&& result.report?.summary?.medium === 0
&& result.report?.summary?.low === 0
&& result.report?.summary?.info === 0;
if (result.code === 0 && markerExists && cleanSummary) {
pass(testName);
} else {
fail(
testName,
`Expected exit=0, markerExists=true, clean summary. Got exit=${result.code}, markerExists=${markerExists}, summary=${JSON.stringify(result.report?.summary)} stderr=${result.stderr}`,
);
}
} catch (error) {
fail(testName, error);
} finally {
await tmp.cleanup();
}
}
async function testMaliciousCrashProducesHighFinding() {
const testName = "DAST harness: malicious input crash is reported as high";
const tmp = await createTempDir();
try {
const targetPath = path.join(tmp.path, "skill");
const hookDir = path.join(targetPath, "hooks", "crashy-hook");
await writeHookFixture(
hookDir,
'"message:preprocessed"',
`const handler = async (event) => {
const payload = String(event?.context?.content || "");
if (payload.includes("<script>")) {
throw new Error("Unhandled payload path");
}
};
export default handler;
`,
);
const result = await runDast(targetPath, 2500);
const hasHigh = Number(result.report?.summary?.high || 0) > 0;
const hasCrashFinding = Array.isArray(result.report?.vulnerabilities)
&& result.report.vulnerabilities.some((v) => String(v.id || "").includes("DAST-MALICIOUS-CRASH"));
if (result.code === 1 && hasHigh && hasCrashFinding) {
pass(testName);
} else {
fail(
testName,
`Expected exit=1 and malicious crash high finding. Got exit=${result.code}, summary=${JSON.stringify(result.report?.summary)}, findings=${JSON.stringify(result.report?.vulnerabilities || [])}`,
);
}
} catch (error) {
fail(testName, error);
} finally {
await tmp.cleanup();
}
}
async function testMissingTypeScriptCompilerIsCoverageInfo() {
const testName = "DAST harness: missing TypeScript compiler reports coverage info, not high";
const tmp = await createTempDir();
try {
const targetPath = path.join(tmp.path, "skill");
const hookDir = path.join(targetPath, "hooks", "ts-hook");
await writeHookFixture(
hookDir,
'"command:new"',
`type Ctx = { dastMode?: boolean };
const handler = async (_event: unknown, _context: Ctx): Promise<void> => {
return;
};
export default handler;
`,
"handler.ts",
);
const result = await runDast(
targetPath,
2500,
{ CLAWSEC_DAST_DISABLE_TYPESCRIPT: "1" },
);
const noHigh = Number(result.report?.summary?.high || 0) === 0
&& Number(result.report?.summary?.critical || 0) === 0;
const hasCoverageInfo = Array.isArray(result.report?.vulnerabilities)
&& result.report.vulnerabilities.some((v) => String(v.id || "").includes("DAST-COVERAGE"));
const hasInfoCount = Number(result.report?.summary?.info || 0) > 0;
if (result.code === 0 && noHigh && hasCoverageInfo && hasInfoCount) {
pass(testName);
} else {
fail(
testName,
`Expected coverage info only (no high/critical). Got exit=${result.code}, summary=${JSON.stringify(result.report?.summary)}, findings=${JSON.stringify(result.report?.vulnerabilities || [])}`,
);
}
} catch (error) {
fail(testName, error);
} finally {
await tmp.cleanup();
}
}
async function main() {
await testSafeHookExecutesAndDoesNotReportMisleadingHigh();
await testMaliciousCrashProducesHighFinding();
await testMissingTypeScriptCompilerIsCoverageInfo();
report();
exitWithResults();
}
await main();
+5 -3
View File
@@ -1,8 +1,8 @@
# Wiki Generation Metadata
- Commit hash: `d5aadfbee15b48ebb4872dfb838e4df88c611d56`
- Branch name: `codex/wiki-tab-ui`
- Generation timestamp (local): `2026-02-26T09:16:02+0200`
- Commit hash: `c3983a100581a9f27eb8cc3b5baa4f585e6c45e4`
- Branch name: `codex/clawsec-scanner-0.0.2-dast-harness`
- Generation timestamp (local): `2026-03-10T19:06:29+0200`
- Generation mode: `update`
- Output language: `English`
- Assets copied into `wiki/assets/`:
@@ -13,6 +13,7 @@
## Notes
- Migrated root documentation pages from `docs/` into dedicated `wiki/` operation pages.
- Updated index and cross-links to use `wiki/` as the documentation source of truth.
- Added a dedicated module page for `clawsec-scanner` and linked it from `wiki/INDEX.md`.
- Future updates should preserve existing headings and append `Update Notes` sections when making deltas.
## Source References
@@ -21,6 +22,7 @@
- AGENTS.md
- wiki/overview.md
- wiki/architecture.md
- wiki/modules/clawsec-scanner.md
- wiki/dependencies.md
- wiki/data-flow.md
- wiki/glossary.md
+4
View File
@@ -29,6 +29,7 @@
## Modules
- [Frontend Web App](modules/frontend-web.md)
- [ClawSec Suite Core](modules/clawsec-suite.md)
- [ClawSec Scanner](modules/clawsec-scanner.md)
- [NanoClaw Integration](modules/nanoclaw-integration.md)
- [Automation and Release Pipelines](modules/automation-release.md)
- [Local Validation and Packaging Tools](modules/local-tooling.md)
@@ -40,6 +41,7 @@
- [Generation Metadata](GENERATION.md)
## Update Notes
- 2026-03-10: Added ClawSec Scanner module documentation and linked it under Modules.
- 2026-02-26: Added Operations pages and updated navigation guidance after migrating root docs into wiki pages.
## Source References
@@ -50,4 +52,6 @@
- scripts/populate-local-feed.sh
- scripts/populate-local-skills.sh
- skills/clawsec-suite/skill.json
- skills/clawsec-scanner/skill.json
- wiki/modules/clawsec-scanner.md
- .github/workflows/ci.yml
+102
View File
@@ -0,0 +1,102 @@
# Module: ClawSec Scanner
## Responsibilities
- Provide multi-layer vulnerability scanning for OpenClaw-oriented skill repositories.
- Orchestrate dependency, SAST, and DAST engines into a single report contract.
- Execute real OpenClaw hook handlers in an isolated DAST harness to validate runtime security behavior.
- Support periodic scan execution through an OpenClaw hook integration.
- Normalize findings into severity buckets for downstream triage and automation.
## Key Files
- `skills/clawsec-scanner/skill.json`: skill metadata, SBOM paths, trigger phrases.
- `skills/clawsec-scanner/scripts/runner.sh`: main orchestrator for dependency/SAST/DAST scans.
- `skills/clawsec-scanner/scripts/scan_dependencies.mjs`: `npm audit` + `pip-audit` parsing.
- `skills/clawsec-scanner/scripts/sast_analyzer.mjs`: Semgrep and Bandit execution/parsing.
- `skills/clawsec-scanner/scripts/dast_runner.mjs`: hook discovery + real harness DAST evaluation.
- `skills/clawsec-scanner/scripts/dast_hook_executor.mjs`: isolated per-hook runtime executor.
- `skills/clawsec-scanner/hooks/clawsec-scanner-hook/handler.ts`: periodic OpenClaw event hook.
- `skills/clawsec-scanner/lib/report.mjs`: unified report generation and text/JSON formatting.
## Public Interfaces
| Interface | Consumer | Behavior |
| --- | --- | --- |
| `runner.sh` CLI | Operators/automation | Runs all enabled scan engines and emits merged report output. |
| `dast_runner.mjs` CLI | Operators/CI/hooks | Discovers hooks and runs isolated runtime DAST checks. |
| OpenClaw scanner hook default export | OpenClaw runtime | Handles `agent:bootstrap` and `command:new` scanner trigger events. |
| `ScanReport` JSON output | Humans and automation | Provides normalized severity summary + finding list. |
## Inputs and Outputs
Inputs/outputs are summarized in the table below.
| Type | Name | Location | Description |
| --- | --- | --- | --- |
| Input | Scan target path | `--target` CLI arg | Root directory where skills/hooks are scanned. |
| Input | Dependency manifests | `package-lock.json`, `requirements.txt`, `pyproject.toml` | Drives dependency vulnerability checks. |
| Input | Hook metadata and handlers | `**/HOOK.md`, `handler.{js,mjs,cjs,ts}` | DAST harness discovers and executes these handlers. |
| Input | Env configuration | `CLAWSEC_*`, `GITHUB_TOKEN` | Controls engine behavior, severity filtering, and output paths. |
| Output | Unified scan report | stdout or `--output` file | JSON/text report with severity summary and finding details. |
| Output | Runtime hook alerts | OpenClaw `event.messages` | New vulnerability alerts pushed into conversations. |
| Output | Scanner state file | `~/.openclaw/clawsec-scanner-state.json` by default | De-duplication memory for reported finding IDs. |
## Configuration
| Variable | Default | Module Effect |
| --- | --- | --- |
| `CLAWSEC_SCANNER_INTERVAL` | `86400` | Minimum interval between periodic hook-triggered scans. |
| `CLAWSEC_SCANNER_MIN_SEVERITY` | `medium` | Threshold for findings pushed to conversation alerts. |
| `CLAWSEC_SCANNER_FORMAT` | `text` | Hook alert serialization format (`text` or `json`). |
| `CLAWSEC_SKIP_DEPENDENCY_SCAN` | `0` | Disables dependency scanner when set to `1`. |
| `CLAWSEC_SKIP_SAST` | `0` | Disables Semgrep/Bandit scanner when set to `1`. |
| `CLAWSEC_SKIP_DAST` | `0` | Disables runtime hook DAST checks when set to `1`. |
| `CLAWSEC_SKIP_CVE_LOOKUP` | `0` | Disables CVE enrichment stage when set to `1`. |
| `CLAWSEC_DAST_HARNESS` | unset | Internal guard to avoid recursive scans during harness execution. |
| `CLAWSEC_DAST_DISABLE_TYPESCRIPT` | unset | Test/debug switch forcing TypeScript harness coverage fallback mode. |
## DAST Harness Behavior
- Hook discovery walks the target tree for `HOOK.md` and resolves adjacent handler files.
- Each declared event key is executed in a separate Node subprocess via `dast_hook_executor.mjs`.
- Findings are generated from real runtime behavior:
- Baseline execution crash or timeout.
- Malicious-input crash or timeout.
- Output amplification beyond message/character thresholds.
- Core event identity mutation (`type`, `action`, `sessionKey`).
- Harness capability gaps (for example missing TypeScript compiler for `.ts` handlers) are reported as `info` coverage findings, not high-severity vulnerabilities.
## Example Snippets
```bash
# run scanner end-to-end
bash skills/clawsec-scanner/scripts/runner.sh --target ./skills --format json
```
```bash
# run DAST harness directly
node skills/clawsec-scanner/scripts/dast_runner.mjs --target ./skills --format text --timeout 30000
```
## Tests
| Test File | Focus |
| --- | --- |
| `skills/clawsec-scanner/test/dast_harness.test.mjs` | Real hook execution path, malicious crash detection, TypeScript coverage fallback semantics. |
| `skills/clawsec-scanner/test/reviewer_regressions.test.mjs` | Runner behavior around non-zero DAST exit and merged reporting. |
| `skills/clawsec-scanner/test/dependency_scanner.test.mjs` | Dependency scanner utility/report contracts. |
| `skills/clawsec-scanner/test/sast_engine.test.mjs` | SAST parser/normalization behavior. |
| `skills/clawsec-scanner/test/cve_integration.test.mjs` | OSV/NVD/GitHub enrichment integration checks. |
## Update Notes
- 2026-03-10: Added module page for `clawsec-scanner` and documented the `0.0.2` real OpenClaw DAST harness execution model.
## Source References
- skills/clawsec-scanner/skill.json
- skills/clawsec-scanner/SKILL.md
- skills/clawsec-scanner/CHANGELOG.md
- skills/clawsec-scanner/scripts/runner.sh
- skills/clawsec-scanner/scripts/scan_dependencies.mjs
- skills/clawsec-scanner/scripts/sast_analyzer.mjs
- skills/clawsec-scanner/scripts/dast_runner.mjs
- skills/clawsec-scanner/scripts/dast_hook_executor.mjs
- skills/clawsec-scanner/scripts/setup_scanner_hook.mjs
- skills/clawsec-scanner/hooks/clawsec-scanner-hook/HOOK.md
- skills/clawsec-scanner/hooks/clawsec-scanner-hook/handler.ts
- skills/clawsec-scanner/lib/report.mjs
- skills/clawsec-scanner/lib/utils.mjs
- skills/clawsec-scanner/test/dast_harness.test.mjs
- skills/clawsec-scanner/test/reviewer_regressions.test.mjs