hackmyagent-core 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +374 -355
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/registry/client.d.ts +74 -0
- package/dist/registry/client.d.ts.map +1 -0
- package/dist/registry/client.js +159 -0
- package/dist/registry/client.js.map +1 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/index.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,154 +1,192 @@
|
|
|
1
|
-
# HackMyAgent
|
|
1
|
+
# HackMyAgent
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/hackmyagent)
|
|
4
4
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
5
|
+
[](https://github.com/opena2a-org/hackmyagent)
|
|
5
6
|
|
|
6
|
-
**
|
|
7
|
+
**Find it. Break it. Fix it.**
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
The hacker's toolkit for AI agents. 147 security checks, 55 attack payloads, auto-fix with rollback, and OASB benchmark compliance. Scans Claude Code, Cursor, VS Code, and any MCP server setup for credential leaks, misconfigurations, prompt injection vectors, supply chain risks, and more.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
[Website](https://hackmyagent.com) | [Docs](https://hackmyagent.com/docs) | [OpenA2A](https://opena2a.org) | [Security Checks Reference](docs/SECURITY_CHECKS.md)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- **CVE-001:** Detect vulnerable OpenClaw versions (before v2026.1.29)
|
|
15
|
-
- **CVE-002:** Control UI origin restrictions (defense-in-depth hardening)
|
|
16
|
-
- **CVE-003:** CVE-2026-25157 — OS command injection via SSH path (CVSS 7.8)
|
|
17
|
-
- **CVE-004:** CVE-2026-24763 — Docker PATH command injection (CVSS 8.8)
|
|
18
|
-
- **SUPPLY-005–008:** ClawHavoc campaign IOCs (C2 IPs, malware filenames, ClickFix patterns)
|
|
19
|
-
- **GATEWAY-007–008, CONFIG-007–009:** Config hardening (open DM wildcards, disabled sandbox, weak tokens)
|
|
20
|
-
|
|
21
|
-
13 new checks. 147+ total.
|
|
22
|
-
|
|
23
|
-
## Disclaimer
|
|
13
|
+
---
|
|
24
14
|
|
|
25
|
-
|
|
15
|
+
## Quick Start
|
|
26
16
|
|
|
27
17
|
```bash
|
|
28
|
-
npx hackmyagent
|
|
29
|
-
npx hackmyagent secure
|
|
30
|
-
npx hackmyagent
|
|
31
|
-
npx hackmyagent scan example.com # scan for exposed infrastructure
|
|
32
|
-
npx hackmyagent attack --local # red team with 55 attack payloads
|
|
33
|
-
npx hackmyagent secure --benchmark oasb-1 # run OASB-1 security benchmark
|
|
18
|
+
npx hackmyagent secure # scan current directory (147 checks)
|
|
19
|
+
npx hackmyagent secure --fix # auto-fix what it finds
|
|
20
|
+
npx hackmyagent fix-all --with-aim # add agent identity + audit logging
|
|
34
21
|
```
|
|
35
22
|
|
|
36
|
-
|
|
23
|
+
No config files required. Works out of the box.
|
|
37
24
|
|
|
38
|
-
|
|
39
|
-
|------|----------|
|
|
40
|
-
| **[hackmyagent.com](https://hackmyagent.com)** | Scan external targets — check if your MCP servers, configs, or credentials are exposed on the internet |
|
|
41
|
-
| **`npx hackmyagent secure`** | Scan local projects — harden your agent setup before deploying |
|
|
42
|
-
|
|
43
|
-
## Why HackMyAgent?
|
|
25
|
+
---
|
|
44
26
|
|
|
45
|
-
|
|
27
|
+
## Table of Contents
|
|
28
|
+
|
|
29
|
+
- [Installation](#installation)
|
|
30
|
+
- [Commands](#commands)
|
|
31
|
+
- [secure](#hackmyagent-secure) — local agent hardening (147 checks)
|
|
32
|
+
- [fix-all](#hackmyagent-fix-all) — run all OpenA2A security plugins
|
|
33
|
+
- [check](#hackmyagent-check) — verify a skill before installing
|
|
34
|
+
- [scan](#hackmyagent-scan) — scan external infrastructure
|
|
35
|
+
- [attack](#hackmyagent-attack) — red team with adversarial payloads
|
|
36
|
+
- [secure --benchmark](#hackmyagent-secure---benchmark) — OASB-1 compliance benchmark
|
|
37
|
+
- [secure-openclaw](#hackmyagent-secure-openclaw) — OpenClaw-specific scanning
|
|
38
|
+
- [rollback](#hackmyagent-rollback) — undo auto-fix changes
|
|
39
|
+
- [Plugin Architecture](#plugin-architecture)
|
|
40
|
+
- [CI/CD Integration](#cicd-integration)
|
|
41
|
+
- [Exit Codes](#exit-codes)
|
|
42
|
+
- [Contributing](#contributing)
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
- **Secure** your agent setup (147+ security checks with auto-remediation)
|
|
49
|
-
- **Scan** external infrastructure (exposed MCP endpoints, leaked configs)
|
|
44
|
+
---
|
|
50
45
|
|
|
51
46
|
## Installation
|
|
52
47
|
|
|
53
48
|
```bash
|
|
54
|
-
#
|
|
49
|
+
# Run directly (no install needed)
|
|
55
50
|
npx hackmyagent secure
|
|
56
51
|
|
|
57
|
-
#
|
|
52
|
+
# Install globally
|
|
58
53
|
npm install -g hackmyagent
|
|
59
54
|
|
|
60
|
-
#
|
|
55
|
+
# Add to project devDependencies
|
|
61
56
|
npm install --save-dev hackmyagent
|
|
62
57
|
```
|
|
63
58
|
|
|
59
|
+
**Requirements:** Node.js 18+
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
64
63
|
## Commands
|
|
65
64
|
|
|
66
65
|
### `hackmyagent secure`
|
|
67
66
|
|
|
68
|
-
Scan and harden your local agent setup
|
|
67
|
+
Scan and harden your local agent setup. 147 checks across 30 categories with auto-remediation.
|
|
69
68
|
|
|
70
69
|
```bash
|
|
71
|
-
#
|
|
72
|
-
hackmyagent secure
|
|
70
|
+
hackmyagent secure # basic scan
|
|
71
|
+
hackmyagent secure ./my-project # scan specific directory
|
|
72
|
+
hackmyagent secure --fix # auto-fix issues
|
|
73
|
+
hackmyagent secure --fix --dry-run # preview fixes before applying
|
|
74
|
+
hackmyagent secure --ignore CRED-001,GIT-002 # skip specific checks
|
|
75
|
+
hackmyagent secure --json # JSON output for CI/CD
|
|
76
|
+
hackmyagent secure --verbose # show all checks including passed
|
|
77
|
+
hackmyagent secure --no-color # disable colored output
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
<details>
|
|
81
|
+
<summary>All 30 security categories</summary>
|
|
82
|
+
|
|
83
|
+
| Category | Checks | What it detects |
|
|
84
|
+
|----------|--------|-----------------|
|
|
85
|
+
| CRED | 4 | Hardcoded API keys, tokens, passwords |
|
|
86
|
+
| MCP | 10 | MCP server misconfigurations |
|
|
87
|
+
| CLAUDE | 7 | Claude Code security issues |
|
|
88
|
+
| NET | 6 | Network exposure, open ports |
|
|
89
|
+
| PROMPT | 4 | Prompt injection vectors |
|
|
90
|
+
| INJ | 4 | XSS, SQL injection, command injection |
|
|
91
|
+
| ENCRYPT | 4 | Missing encryption at rest |
|
|
92
|
+
| SESSION | 4 | Session management flaws |
|
|
93
|
+
| AUDIT | 4 | Missing audit trails |
|
|
94
|
+
| SANDBOX | 4 | Process isolation gaps |
|
|
95
|
+
| TOOL | 4 | Tool permission boundaries |
|
|
96
|
+
| AUTH | 4 | Authentication weaknesses |
|
|
97
|
+
| DEP | 4 | Vulnerable dependencies |
|
|
98
|
+
| ENV | 4 | Insecure environment variables |
|
|
99
|
+
| GIT | 3 | Git security (gitignore, hooks) |
|
|
100
|
+
| IO | 4 | Input/output validation |
|
|
101
|
+
| LOG | 4 | Logging and monitoring gaps |
|
|
102
|
+
| PERM | 3 | Overly permissive file permissions |
|
|
103
|
+
| PROC | 4 | Process isolation issues |
|
|
104
|
+
| RATE | 4 | Missing rate limiting |
|
|
105
|
+
| SEC | 4 | Security headers |
|
|
106
|
+
| API | 4 | API security issues |
|
|
107
|
+
| VSCODE | 2 | VS Code configuration risks |
|
|
108
|
+
| CURSOR | 1 | Cursor IDE configuration risks |
|
|
109
|
+
| CVE | 4 | Known CVE detection |
|
|
110
|
+
| GATEWAY | 8 | Gateway misconfigurations |
|
|
111
|
+
| CONFIG | 9 | Insecure default settings |
|
|
112
|
+
| SUPPLY | 8 | Supply chain attack vectors |
|
|
113
|
+
| SKILL | 12 | Malicious skill/tool detection |
|
|
114
|
+
| HEARTBEAT | 6 | Heartbeat/cron abuse |
|
|
73
115
|
|
|
74
|
-
|
|
75
|
-
hackmyagent secure ./my-project
|
|
116
|
+
</details>
|
|
76
117
|
|
|
77
|
-
|
|
78
|
-
|
|
118
|
+
<details>
|
|
119
|
+
<summary>Auto-fix capabilities</summary>
|
|
79
120
|
|
|
80
|
-
|
|
81
|
-
|
|
121
|
+
**General (`hackmyagent secure --fix`):**
|
|
122
|
+
|
|
123
|
+
| Check | Issue | Auto-fix |
|
|
124
|
+
|-------|-------|----------|
|
|
125
|
+
| CRED-001 | Exposed API keys | Replace with env var reference |
|
|
126
|
+
| GIT-001 | Missing .gitignore | Create with secure defaults |
|
|
127
|
+
| GIT-002 | Incomplete .gitignore | Add missing patterns |
|
|
128
|
+
| PERM-001 | Overly permissive files | Set restrictive permissions |
|
|
129
|
+
| MCP-001 | Root filesystem access | Scope to project directory |
|
|
130
|
+
| NET-001 | Bound to 0.0.0.0 | Bind to 127.0.0.1 |
|
|
131
|
+
|
|
132
|
+
**OpenClaw (`hackmyagent secure-openclaw --fix`):**
|
|
133
|
+
|
|
134
|
+
| Check | Issue | Auto-fix |
|
|
135
|
+
|-------|-------|----------|
|
|
136
|
+
| GATEWAY-001 | Bound to 0.0.0.0 | Bind to 127.0.0.1 |
|
|
137
|
+
| GATEWAY-003 | Plaintext token | Replace with `${OPENCLAW_AUTH_TOKEN}` |
|
|
138
|
+
| GATEWAY-004 | Approvals disabled | Enable approvals |
|
|
139
|
+
| GATEWAY-005 | Sandbox disabled | Enable sandbox |
|
|
140
|
+
|
|
141
|
+
Use `--dry-run` first to preview changes. Backups are created automatically in `.hackmyagent-backup/`.
|
|
142
|
+
|
|
143
|
+
</details>
|
|
144
|
+
|
|
145
|
+
---
|
|
82
146
|
|
|
83
|
-
|
|
84
|
-
hackmyagent secure --ignore CRED-001,GIT-002
|
|
147
|
+
### `hackmyagent fix-all`
|
|
85
148
|
|
|
86
|
-
|
|
87
|
-
hackmyagent secure --json
|
|
149
|
+
Run all OpenA2A security plugins in sequence: scan, fix, report.
|
|
88
150
|
|
|
89
|
-
|
|
90
|
-
hackmyagent
|
|
151
|
+
```bash
|
|
152
|
+
hackmyagent fix-all # scan and fix current directory
|
|
153
|
+
hackmyagent fix-all ./my-agent # target specific directory
|
|
154
|
+
hackmyagent fix-all --dry-run # preview without applying
|
|
155
|
+
hackmyagent fix-all --scan-only # scan only, no fixes
|
|
156
|
+
hackmyagent fix-all --json # JSON output for CI
|
|
157
|
+
hackmyagent fix-all --with-aim # enable AIM identity + audit logging
|
|
158
|
+
hackmyagent fix-all -v # verbose output
|
|
91
159
|
```
|
|
92
160
|
|
|
93
|
-
**
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
| NET | 6 | Network security |
|
|
101
|
-
| PROMPT | 4 | Prompt injection defenses |
|
|
102
|
-
| INJ | 4 | Input validation (XSS, SQL, cmd) |
|
|
103
|
-
| ENCRYPT | 4 | Encryption at rest |
|
|
104
|
-
| SESSION | 4 | Session management |
|
|
105
|
-
| AUDIT | 4 | Audit trails |
|
|
106
|
-
| SANDBOX | 4 | Process isolation |
|
|
107
|
-
| TOOL | 4 | Tool permission boundaries |
|
|
108
|
-
| AUTH | 4 | Authentication checks |
|
|
109
|
-
| DEPS | 4 | Dependency security |
|
|
110
|
-
| ENV | 4 | Environment variable safety |
|
|
111
|
-
| GIT | 4 | Git security (.gitignore, secrets in history) |
|
|
112
|
-
| IO | 4 | Input/output validation |
|
|
113
|
-
| LOG | 4 | Logging and monitoring |
|
|
114
|
-
| PERM | 4 | File permissions |
|
|
115
|
-
| PROC | 4 | Process isolation |
|
|
116
|
-
| RATE | 4 | Rate limiting |
|
|
117
|
-
| SEC | 4 | General security headers |
|
|
118
|
-
| API | 4 | API security |
|
|
119
|
-
| VSCODE | 4 | VS Code configuration |
|
|
120
|
-
| CURSOR | 4 | Cursor IDE configuration |
|
|
121
|
-
| CVE | 4 | OpenClaw CVE detection |
|
|
122
|
-
| GATEWAY | 8 | Gateway misconfigurations |
|
|
123
|
-
| CONFIG | 9 | Insecure settings |
|
|
124
|
-
| SUPPLY | 8 | Supply chain attacks |
|
|
125
|
-
| SKILL | 12 | Malicious skill detection |
|
|
126
|
-
| HEARTBEAT | 6 | Heartbeat/cron abuse |
|
|
127
|
-
| WINDSURF | 3 | Windsurf IDE configuration |
|
|
161
|
+
**Plugin execution order:**
|
|
162
|
+
|
|
163
|
+
| # | Plugin | What it does |
|
|
164
|
+
|---|--------|--------------|
|
|
165
|
+
| 1 | **SkillGuard** | Hash pinning, tamper detection, dangerous pattern scanning (reverse shells, exfil, prompt injection) |
|
|
166
|
+
| 2 | **SignCrypt** | Ed25519 signing of SKILL.md and HEARTBEAT.md, SHA-256 hash pinning, signature verification |
|
|
167
|
+
| 3 | **Secretless** | Credential detection (10 patterns), env var replacement, AES-256-GCM encrypted store |
|
|
128
168
|
|
|
129
|
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
169
|
+
**`--with-aim` adds:**
|
|
170
|
+
- Ed25519 identity generation for the agent
|
|
171
|
+
- Cryptographic audit log at `.opena2a/aim/audit.jsonl`
|
|
172
|
+
- Capability policy enforcement via `policy.yaml`
|
|
173
|
+
- 8-factor trust scoring
|
|
174
|
+
|
|
175
|
+
---
|
|
132
176
|
|
|
133
177
|
### `hackmyagent check`
|
|
134
178
|
|
|
135
|
-
Verify a skill
|
|
179
|
+
Verify a skill before installing it.
|
|
136
180
|
|
|
137
181
|
```bash
|
|
138
182
|
hackmyagent check @publisher/skill-name
|
|
139
|
-
hackmyagent check @anthropic/claude-mcp --verbose
|
|
140
183
|
hackmyagent check @publisher/skill --json
|
|
141
|
-
hackmyagent check @publisher/skill --offline
|
|
184
|
+
hackmyagent check @publisher/skill --offline # skip DNS verification
|
|
142
185
|
```
|
|
143
186
|
|
|
144
|
-
|
|
145
|
-
- Publisher identity via DNS TXT records
|
|
146
|
-
- Permissions requested (filesystem, network, shell access)
|
|
147
|
-
- Revocation status against global blocklist
|
|
187
|
+
Checks: publisher identity (DNS TXT), permissions requested, revocation status.
|
|
148
188
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
**Risk Levels:** `low`, `medium`, `high`, `critical`
|
|
189
|
+
---
|
|
152
190
|
|
|
153
191
|
### `hackmyagent scan`
|
|
154
192
|
|
|
@@ -157,70 +195,50 @@ Scan external infrastructure for exposed AI agent endpoints.
|
|
|
157
195
|
```bash
|
|
158
196
|
hackmyagent scan example.com
|
|
159
197
|
hackmyagent scan 192.168.1.100 -p 3000,8080
|
|
160
|
-
hackmyagent scan example.com --verbose
|
|
161
198
|
hackmyagent scan example.com --json
|
|
162
199
|
```
|
|
163
200
|
|
|
164
|
-
|
|
165
|
-
- Exposed MCP SSE/tools endpoints
|
|
166
|
-
- Public configuration files
|
|
167
|
-
- API keys in responses
|
|
168
|
-
- Debug/admin interfaces
|
|
169
|
-
|
|
170
|
-
**Scoring:** A (90-100), B (80-89), C (70-79), D (60-69), F (<60)
|
|
171
|
-
|
|
172
|
-
### `hackmyagent attack`
|
|
173
|
-
|
|
174
|
-
Red team your AI agent with adversarial security testing. 55 attack payloads across 5 categories.
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
# Local simulation (no API calls - test payloads locally)
|
|
178
|
-
hackmyagent attack --local
|
|
179
|
-
hackmyagent attack --local --system-prompt "You are a helpful assistant"
|
|
201
|
+
Detects: exposed MCP SSE/tools endpoints, public configs, API keys in responses, debug interfaces.
|
|
180
202
|
|
|
181
|
-
|
|
182
|
-
hackmyagent attack https://api.example.com/v1/chat
|
|
183
|
-
hackmyagent attack https://api.example.com --api-format anthropic
|
|
203
|
+
Scoring: A (90-100), B (80-89), C (70-79), D (60-69), F (<60).
|
|
184
204
|
|
|
185
|
-
|
|
186
|
-
hackmyagent attack --local --category prompt-injection
|
|
187
|
-
hackmyagent attack --local --intensity aggressive
|
|
205
|
+
> Only scan systems you own or have written authorization to test.
|
|
188
206
|
|
|
189
|
-
|
|
190
|
-
hackmyagent attack https://api.example.com --payload-file custom.json
|
|
207
|
+
---
|
|
191
208
|
|
|
192
|
-
|
|
193
|
-
hackmyagent attack https://api.example.com --fail-on-vulnerable # any finding
|
|
194
|
-
hackmyagent attack https://api.example.com --fail-on-vulnerable medium # medium+
|
|
195
|
-
hackmyagent attack https://api.example.com --fail-on-vulnerable critical # critical only
|
|
209
|
+
### `hackmyagent attack`
|
|
196
210
|
|
|
197
|
-
|
|
198
|
-
hackmyagent attack --local -f json
|
|
199
|
-
hackmyagent attack --local -f sarif -o results.sarif
|
|
211
|
+
Red team your AI agent with 55 adversarial payloads across 5 categories.
|
|
200
212
|
|
|
201
|
-
|
|
202
|
-
hackmyagent attack --local
|
|
213
|
+
```bash
|
|
214
|
+
hackmyagent attack --local # local simulation
|
|
215
|
+
hackmyagent attack --local --system-prompt "You are helpful" # with custom prompt
|
|
216
|
+
hackmyagent attack https://api.example.com/v1/chat # test live endpoint
|
|
217
|
+
hackmyagent attack --local --category prompt-injection # single category
|
|
218
|
+
hackmyagent attack --local --intensity aggressive # full suite
|
|
219
|
+
hackmyagent attack --local -f sarif -o results.sarif # SARIF output
|
|
220
|
+
hackmyagent attack https://api.example.com --fail-on-vulnerable medium # CI gate
|
|
221
|
+
hackmyagent attack https://api.example.com --api-format anthropic # Anthropic API
|
|
222
|
+
hackmyagent attack https://api.example.com --model gpt-4o # specify model
|
|
223
|
+
hackmyagent attack https://api.example.com -H "Authorization: Bearer tk" # custom header
|
|
224
|
+
hackmyagent attack --local --timeout 5000 --delay 500 # timing controls
|
|
225
|
+
hackmyagent attack --local --stop-on-success # stop at first hit
|
|
203
226
|
```
|
|
204
227
|
|
|
205
|
-
|
|
228
|
+
<details>
|
|
229
|
+
<summary>Attack categories and custom payloads</summary>
|
|
206
230
|
|
|
207
231
|
| Category | Payloads | Description |
|
|
208
232
|
|----------|----------|-------------|
|
|
209
|
-
| `prompt-injection` | 12 | Manipulate agent behavior via
|
|
210
|
-
| `jailbreak` | 12 | Bypass safety guardrails and
|
|
211
|
-
| `data-exfiltration` | 11 | Extract sensitive
|
|
212
|
-
| `capability-abuse` | 10 | Misuse agent tools
|
|
233
|
+
| `prompt-injection` | 12 | Manipulate agent behavior via injected instructions |
|
|
234
|
+
| `jailbreak` | 12 | Bypass safety guardrails and system constraints |
|
|
235
|
+
| `data-exfiltration` | 11 | Extract sensitive data, system prompts, credentials |
|
|
236
|
+
| `capability-abuse` | 10 | Misuse agent tools for unintended actions |
|
|
213
237
|
| `context-manipulation` | 10 | Poison agent context or memory |
|
|
214
238
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
| Level | Description |
|
|
218
|
-
|-------|-------------|
|
|
219
|
-
| `passive` | Observation only, minimal risk |
|
|
220
|
-
| `active` | Standard attack payloads (default) |
|
|
221
|
-
| `aggressive` | Creative/risky payloads, full suite |
|
|
239
|
+
Intensity: `passive` (observation only), `active` (default), `aggressive` (full suite).
|
|
222
240
|
|
|
223
|
-
**Custom
|
|
241
|
+
**Custom payloads:** Create a JSON file and pass with `--payload-file custom.json`:
|
|
224
242
|
|
|
225
243
|
```json
|
|
226
244
|
{
|
|
@@ -239,302 +257,303 @@ hackmyagent attack --local --verbose
|
|
|
239
257
|
}
|
|
240
258
|
```
|
|
241
259
|
|
|
242
|
-
Only `id` and `payload` are required.
|
|
260
|
+
Only `id` and `payload` are required.
|
|
243
261
|
|
|
244
|
-
|
|
245
|
-
- `text` - Human-readable report (default)
|
|
246
|
-
- `json` - Machine-readable JSON
|
|
247
|
-
- `sarif` - SARIF 2.1.0 for GitHub Security tab integration
|
|
248
|
-
- `html` - Standalone HTML report
|
|
262
|
+
</details>
|
|
249
263
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
- 50-69: HIGH - Significant vulnerabilities, action required
|
|
254
|
-
- 70-100: CRITICAL - Severe vulnerabilities, immediate action needed
|
|
264
|
+
Output formats: `text`, `json`, `sarif` (GitHub Security tab), `html`.
|
|
265
|
+
|
|
266
|
+
---
|
|
255
267
|
|
|
256
268
|
### `hackmyagent secure --benchmark`
|
|
257
269
|
|
|
258
|
-
Run the [OASB-1](https://oasb.ai/oasb-1) (Open Agent Security Benchmark) — 46 controls across 10 categories
|
|
270
|
+
Run the [OASB-1](https://oasb.ai/oasb-1) (Open Agent Security Benchmark) — 46 controls across 10 categories.
|
|
259
271
|
|
|
260
272
|
```bash
|
|
261
|
-
#
|
|
262
|
-
hackmyagent secure
|
|
273
|
+
hackmyagent secure -b oasb-1 # L1 baseline (26 controls)
|
|
274
|
+
hackmyagent secure -b oasb-1 -l L2 # L2 standard (44 controls)
|
|
275
|
+
hackmyagent secure -b oasb-1 -l L3 # L3 hardened (46 controls)
|
|
276
|
+
hackmyagent secure -b oasb-1 -c "Input Security" # filter to one category
|
|
277
|
+
hackmyagent secure -b oasb-1 -v # verbose (every control)
|
|
278
|
+
hackmyagent secure -b oasb-1 -f html -o report.html # HTML report
|
|
279
|
+
hackmyagent secure -b oasb-1 --fail-below 70 # CI gate
|
|
280
|
+
```
|
|
263
281
|
|
|
264
|
-
|
|
265
|
-
|
|
282
|
+
<details>
|
|
283
|
+
<summary>OASB-1 categories and maturity levels</summary>
|
|
266
284
|
|
|
267
|
-
#
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
285
|
+
| # | Category | Controls |
|
|
286
|
+
|---|----------|----------|
|
|
287
|
+
| 1 | Identity & Provenance | 4 |
|
|
288
|
+
| 2 | Capability & Authorization | 5 |
|
|
289
|
+
| 3 | Input Security | 5 |
|
|
290
|
+
| 4 | Output Security | 4 |
|
|
291
|
+
| 5 | Credential Protection | 5 |
|
|
292
|
+
| 6 | Supply Chain Integrity | 5 |
|
|
293
|
+
| 7 | Agent-to-Agent Security | 4 |
|
|
294
|
+
| 8 | Memory & Context Integrity | 4 |
|
|
295
|
+
| 9 | Operational Security | 5 |
|
|
296
|
+
| 10 | Monitoring & Response | 5 |
|
|
271
297
|
|
|
272
|
-
|
|
273
|
-
hackmyagent secure -b oasb-1 -v
|
|
298
|
+
**Maturity levels:** L1 Essential (26 controls), L2 Standard (44), L3 Hardened (46).
|
|
274
299
|
|
|
275
|
-
|
|
276
|
-
hackmyagent secure -b oasb-1 --category "Credential Protection"
|
|
300
|
+
**Ratings:** Certified (100%), Compliant (L1=100% + L2>=90%), Passing (>=90%), Needs Improvement (>=70%), Failing (<70%).
|
|
277
301
|
|
|
278
|
-
|
|
279
|
-
hackmyagent secure -b oasb-1 -f json
|
|
280
|
-
hackmyagent secure -b oasb-1 -f sarif -o results.sarif
|
|
281
|
-
hackmyagent secure -b oasb-1 -f html -o report.html
|
|
282
|
-
hackmyagent secure -b oasb-1 -f asp -o profile.asp.json
|
|
302
|
+
</details>
|
|
283
303
|
|
|
284
|
-
|
|
285
|
-
hackmyagent secure -b oasb-1 --fail-below 70
|
|
286
|
-
```
|
|
304
|
+
Output formats: `text`, `json`, `sarif`, `html`, `asp` (Agent Security Profile).
|
|
287
305
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
| # | Category | Controls | What it checks |
|
|
291
|
-
|---|----------|----------|----------------|
|
|
292
|
-
| 1 | Identity & Provenance | 4 | Cryptographic identity, ownership, provenance chain |
|
|
293
|
-
| 2 | Capability & Authorization | 5 | Least privilege, capability boundaries, human-in-the-loop |
|
|
294
|
-
| 3 | Input Security | 5 | Prompt injection, input validation, URL/SSRF protection |
|
|
295
|
-
| 4 | Output Security | 4 | Output validation, destructive op confirmation, exfiltration prevention |
|
|
296
|
-
| 5 | Credential Protection | 5 | Hardcoded secrets, context window isolation, log redaction |
|
|
297
|
-
| 6 | Supply Chain Integrity | 5 | Dependency scanning, lockfiles, rug pull protection, SBOM |
|
|
298
|
-
| 7 | Agent-to-Agent Security | 4 | Mutual auth, message integrity, trust boundaries |
|
|
299
|
-
| 8 | Memory & Context Integrity | 4 | Context injection, memory isolation, summarization security |
|
|
300
|
-
| 9 | Operational Security | 5 | Non-root execution, sandboxing, network isolation, resource limits |
|
|
301
|
-
| 10 | Monitoring & Response | 5 | Security logging, anomaly detection, kill switch, incident response |
|
|
302
|
-
|
|
303
|
-
**Maturity Levels:**
|
|
304
|
-
|
|
305
|
-
| Level | Controls | Purpose |
|
|
306
|
-
|-------|----------|---------|
|
|
307
|
-
| L1 - Essential | 26 | Baseline security every agent should meet |
|
|
308
|
-
| L2 - Standard | 44 (L1 + 18) | Production-grade agent security |
|
|
309
|
-
| L3 - Hardened | 46 (L2 + 2) | High-security environments, multi-modal threats |
|
|
310
|
-
|
|
311
|
-
**Rating System:**
|
|
312
|
-
|
|
313
|
-
| Rating | L1 Criteria | L2 Criteria | L3 Criteria |
|
|
314
|
-
|--------|-------------|-------------|-------------|
|
|
315
|
-
| Certified | 100% | L1=100% + L2=100% | All 100% |
|
|
316
|
-
| Compliant | — | L1=100% + L2≥90% | L1=100% + L2≥90% |
|
|
317
|
-
| Passing | ≥90% | L1≥90% | L1≥90% |
|
|
318
|
-
| Needs Improvement | ≥70% | L1≥70% | L1≥70% |
|
|
319
|
-
| Failing | <70% | L1<70% | L1<70% |
|
|
320
|
-
|
|
321
|
-
**Output Formats:**
|
|
322
|
-
- `text` — Terminal report with category breakdown (default)
|
|
323
|
-
- `json` — Machine-readable JSON with full control details
|
|
324
|
-
- `sarif` — SARIF 2.1.0 for GitHub Security tab and IDE integration
|
|
325
|
-
- `html` — Standalone HTML report with donut chart, radar chart, and grades
|
|
326
|
-
- `asp` — Agent Security Profile (portable security posture document)
|
|
327
|
-
|
|
328
|
-
**Exit Codes:**
|
|
329
|
-
- `0` — Rating is Passing or better (or compliance above `--fail-below` threshold)
|
|
330
|
-
- `1` — Rating is Failing or Needs Improvement (or compliance below threshold)
|
|
306
|
+
---
|
|
331
307
|
|
|
332
308
|
### `hackmyagent secure-openclaw`
|
|
333
309
|
|
|
334
|
-
|
|
310
|
+
47 specialized checks for OpenClaw/Moltbot installations.
|
|
335
311
|
|
|
336
312
|
```bash
|
|
337
|
-
hackmyagent secure-openclaw
|
|
338
|
-
hackmyagent secure-openclaw ~/.moltbot
|
|
339
|
-
hackmyagent secure-openclaw --fix
|
|
340
|
-
hackmyagent secure-openclaw --fix --dry-run
|
|
341
|
-
hackmyagent secure-openclaw --json
|
|
313
|
+
hackmyagent secure-openclaw # scan default location
|
|
314
|
+
hackmyagent secure-openclaw ~/.moltbot # specific directory
|
|
315
|
+
hackmyagent secure-openclaw --fix # auto-fix gateway configs
|
|
316
|
+
hackmyagent secure-openclaw --fix --dry-run # preview fixes
|
|
317
|
+
hackmyagent secure-openclaw --json # JSON output
|
|
342
318
|
```
|
|
343
319
|
|
|
344
|
-
|
|
345
|
-
- CVE-2026-25253 vulnerable versions (before v2026.1.29)
|
|
346
|
-
- Missing `controlUi.allowedOrigins` (patch alone isn't enough)
|
|
347
|
-
- ClawHavoc C2 IP addresses and malware filenames
|
|
348
|
-
- ClickFix social engineering patterns
|
|
349
|
-
- Unsigned/malicious skills (ClawHavoc campaign patterns)
|
|
350
|
-
- Reverse shell backdoors
|
|
351
|
-
- Credential exfiltration (wallets, SSH keys, API keys)
|
|
352
|
-
- Heartbeat/cron abuse
|
|
353
|
-
- Gateway misconfigurations (GHSA-g8p2 vulnerability)
|
|
354
|
-
- Disabled sandbox/approval confirmations
|
|
355
|
-
|
|
356
|
-
**Auto-Fix (with `--fix`):**
|
|
357
|
-
| Check | Before | After |
|
|
358
|
-
|-------|--------|-------|
|
|
359
|
-
| GATEWAY-001 | `0.0.0.0` | `127.0.0.1` (local-only) |
|
|
360
|
-
| GATEWAY-003 | Plaintext token | `${OPENCLAW_AUTH_TOKEN}` env var |
|
|
361
|
-
| GATEWAY-004 | Approvals disabled | Approvals enabled |
|
|
362
|
-
| GATEWAY-005 | Sandbox disabled | Sandbox enabled |
|
|
363
|
-
|
|
364
|
-
**Check Categories:**
|
|
365
|
-
| Category | Checks | Description |
|
|
366
|
-
|----------|--------|-------------|
|
|
367
|
-
| SKILL | 12 | Malicious skill detection |
|
|
368
|
-
| HEARTBEAT | 6 | Heartbeat/cron abuse |
|
|
369
|
-
| GATEWAY | 8 | Gateway misconfigurations (4 auto-fixable) |
|
|
370
|
-
| CONFIG | 9 | Insecure settings |
|
|
371
|
-
| SUPPLY | 8 | Supply chain attacks |
|
|
372
|
-
| CVE | 4 | OpenClaw CVE detection |
|
|
320
|
+
Detects: CVE-2026-25253, ClawHavoc IOCs, reverse shells, credential exfiltration, gateway misconfigs, disabled sandbox.
|
|
373
321
|
|
|
374
322
|
See [SECURITY_CHECKS.md](docs/SECURITY_CHECKS.md#openclaw-security-checks) for full documentation.
|
|
375
323
|
|
|
324
|
+
---
|
|
325
|
+
|
|
376
326
|
### `hackmyagent rollback`
|
|
377
327
|
|
|
378
|
-
Undo auto-fix changes.
|
|
328
|
+
Undo auto-fix changes. Backups are created automatically in `.hackmyagent-backup/`.
|
|
379
329
|
|
|
380
330
|
```bash
|
|
381
|
-
hackmyagent rollback
|
|
382
|
-
hackmyagent rollback ./my-project
|
|
331
|
+
hackmyagent rollback # rollback current directory
|
|
332
|
+
hackmyagent rollback ./my-project # rollback specific directory
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Plugin Architecture
|
|
338
|
+
|
|
339
|
+
HackMyAgent uses a modular plugin system built on [`@opena2a/plugin-core`](packages/plugin-core). Each plugin implements `scan()` to detect issues and `fix()` to remediate them.
|
|
340
|
+
|
|
341
|
+
### Packages
|
|
342
|
+
|
|
343
|
+
| Package | npm | Description |
|
|
344
|
+
|---------|-----|-------------|
|
|
345
|
+
| [`@opena2a/plugin-core`](packages/plugin-core) | — | Plugin interface, registry, shared types |
|
|
346
|
+
| [`@opena2a/aim-core`](packages/aim-core) | — | Ed25519 identity, audit logging, capability policy, trust scoring |
|
|
347
|
+
| [`@opena2a/secretless-openclaw`](packages/secretless-openclaw) | — | Credential scanning (10 patterns), env var replacement, AES-256-GCM store |
|
|
348
|
+
| [`@opena2a/signcrypt-openclaw`](packages/signcrypt-openclaw) | — | Ed25519 file signing, SHA-256 hash pinning, signature verification |
|
|
349
|
+
| [`@opena2a/skillguard-openclaw`](packages/skillguard-openclaw) | — | Permission pinning, tamper detection, dangerous pattern scanning |
|
|
350
|
+
|
|
351
|
+
### Writing a Plugin
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import type {
|
|
355
|
+
OpenA2APlugin,
|
|
356
|
+
PluginMetadata,
|
|
357
|
+
PluginStatus,
|
|
358
|
+
Finding,
|
|
359
|
+
Remediation,
|
|
360
|
+
FixOptions,
|
|
361
|
+
PluginInitOptions,
|
|
362
|
+
} from '@opena2a/plugin-core';
|
|
363
|
+
|
|
364
|
+
export const metadata: PluginMetadata = {
|
|
365
|
+
packageName: '@my-org/my-plugin',
|
|
366
|
+
displayName: 'My Plugin',
|
|
367
|
+
description: 'Detects and fixes X',
|
|
368
|
+
version: '1.0.0',
|
|
369
|
+
findings: ['MY-001', 'MY-002'],
|
|
370
|
+
scoreImprovement: 10,
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
export class MyPlugin implements OpenA2APlugin {
|
|
374
|
+
readonly metadata = metadata;
|
|
375
|
+
|
|
376
|
+
async init(options?: PluginInitOptions): Promise<void> {
|
|
377
|
+
// Access AIM Core for identity-aware audit logging:
|
|
378
|
+
// const aimCore = options?.aimCore;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async scan(agentDir: string): Promise<Finding[]> {
|
|
382
|
+
// Scan the agent directory and return findings
|
|
383
|
+
return [
|
|
384
|
+
{
|
|
385
|
+
id: 'MY-001',
|
|
386
|
+
title: 'Insecure widget detected',
|
|
387
|
+
description: 'Widget at config.json line 12 uses plaintext.',
|
|
388
|
+
severity: 'high', // critical | high | medium | low
|
|
389
|
+
filePath: 'config.json',
|
|
390
|
+
line: 12,
|
|
391
|
+
autoFixable: true,
|
|
392
|
+
},
|
|
393
|
+
];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
async fix(agentDir: string, options?: FixOptions): Promise<Remediation[]> {
|
|
397
|
+
if (options?.dryRun) {
|
|
398
|
+
// Return what would be fixed without modifying files
|
|
399
|
+
return [{ findingId: 'MY-001', description: 'Would encrypt widget', filesModified: ['config.json'], rollbackAvailable: false }];
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Apply fixes and return what was changed
|
|
403
|
+
return [{ findingId: 'MY-001', description: 'Encrypted widget', filesModified: ['config.json'], rollbackAvailable: false }];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
async status(): Promise<PluginStatus> {
|
|
407
|
+
return { name: metadata.displayName, version: metadata.version, active: true, findingsCount: 0 };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async uninstall(): Promise<void> {}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export function createPlugin(): MyPlugin {
|
|
414
|
+
return new MyPlugin();
|
|
415
|
+
}
|
|
383
416
|
```
|
|
384
417
|
|
|
385
|
-
|
|
418
|
+
Register the plugin in `@opena2a/plugin-core`:
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { registerPlugin } from '@opena2a/plugin-core';
|
|
422
|
+
import { createPlugin, metadata } from '@my-org/my-plugin';
|
|
423
|
+
|
|
424
|
+
registerPlugin({
|
|
425
|
+
metadata,
|
|
426
|
+
create: createPlugin,
|
|
427
|
+
});
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Trust Score
|
|
431
|
+
|
|
432
|
+
AIM Core provides an 8-factor weighted trust score (0.0 to 1.0) for each agent:
|
|
433
|
+
|
|
434
|
+
| Factor | Weight | What it measures |
|
|
435
|
+
|--------|--------|------------------|
|
|
436
|
+
| `identity` | 0.20 | Ed25519 keypair exists and is valid |
|
|
437
|
+
| `capabilities` | 0.15 | Capabilities declared and pinned |
|
|
438
|
+
| `secretsManaged` | 0.15 | No hardcoded credentials |
|
|
439
|
+
| `auditLog` | 0.10 | Audit trail active |
|
|
440
|
+
| `configSigned` | 0.10 | Configuration integrity verified |
|
|
441
|
+
| `skillsVerified` | 0.10 | Skills cryptographically signed |
|
|
442
|
+
| `networkControlled` | 0.10 | Network access restricted |
|
|
443
|
+
| `heartbeatMonitored` | 0.10 | Heartbeat monitoring active |
|
|
444
|
+
|
|
445
|
+
Use `--with-aim` in `fix-all` to generate trust scores.
|
|
446
|
+
|
|
447
|
+
---
|
|
386
448
|
|
|
387
449
|
## CI/CD Integration
|
|
388
450
|
|
|
389
451
|
### GitHub Actions
|
|
390
452
|
|
|
391
453
|
```yaml
|
|
392
|
-
name: Security
|
|
454
|
+
name: Agent Security
|
|
393
455
|
on: [push, pull_request]
|
|
394
|
-
|
|
395
456
|
jobs:
|
|
396
|
-
|
|
457
|
+
scan:
|
|
397
458
|
runs-on: ubuntu-latest
|
|
398
459
|
steps:
|
|
399
460
|
- uses: actions/checkout@v4
|
|
400
461
|
- uses: actions/setup-node@v4
|
|
401
|
-
with:
|
|
402
|
-
node-version: '20'
|
|
462
|
+
with: { node-version: '20' }
|
|
403
463
|
- run: npx hackmyagent secure --json > security-report.json
|
|
464
|
+
- run: npx hackmyagent fix-all --scan-only --json > plugin-report.json
|
|
404
465
|
- uses: actions/upload-artifact@v4
|
|
405
|
-
with:
|
|
406
|
-
name: security-report
|
|
407
|
-
path: security-report.json
|
|
466
|
+
with: { name: security-reports, path: '*.json' }
|
|
408
467
|
```
|
|
409
468
|
|
|
410
|
-
### GitHub
|
|
469
|
+
### SARIF (GitHub Security Tab)
|
|
411
470
|
|
|
412
471
|
```yaml
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
jobs:
|
|
417
|
-
attack-scan:
|
|
418
|
-
runs-on: ubuntu-latest
|
|
419
|
-
steps:
|
|
420
|
-
- uses: actions/checkout@v4
|
|
421
|
-
- uses: actions/setup-node@v4
|
|
422
|
-
with:
|
|
423
|
-
node-version: '20'
|
|
424
|
-
- name: Run attack simulation
|
|
425
|
-
run: npx hackmyagent attack --local -f sarif -o attack-results.sarif --fail-on-vulnerable medium
|
|
426
|
-
- name: Upload SARIF to GitHub Security
|
|
427
|
-
uses: github/codeql-action/upload-sarif@v3
|
|
428
|
-
with:
|
|
429
|
-
sarif_file: attack-results.sarif
|
|
430
|
-
|
|
431
|
-
benchmark:
|
|
432
|
-
runs-on: ubuntu-latest
|
|
433
|
-
steps:
|
|
434
|
-
- uses: actions/checkout@v4
|
|
435
|
-
- uses: actions/setup-node@v4
|
|
436
|
-
with:
|
|
437
|
-
node-version: '20'
|
|
438
|
-
- name: Run OASB-1 benchmark
|
|
439
|
-
run: npx hackmyagent secure -b oasb-1 --fail-below 70
|
|
472
|
+
- run: npx hackmyagent attack --local -f sarif -o results.sarif --fail-on-vulnerable medium
|
|
473
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
474
|
+
with: { sarif_file: results.sarif }
|
|
440
475
|
```
|
|
441
476
|
|
|
442
477
|
### Pre-commit Hook
|
|
443
478
|
|
|
444
479
|
```bash
|
|
445
|
-
# .git/hooks/pre-commit
|
|
446
480
|
#!/bin/sh
|
|
481
|
+
# .git/hooks/pre-commit
|
|
447
482
|
npx hackmyagent secure --ignore LOG-001,RATE-001
|
|
448
483
|
```
|
|
449
484
|
|
|
450
|
-
### JSON
|
|
451
|
-
|
|
452
|
-
All commands support `--json` for machine-readable output:
|
|
485
|
+
### JSON Piping
|
|
453
486
|
|
|
454
487
|
```bash
|
|
488
|
+
# Filter critical findings
|
|
455
489
|
hackmyagent secure --json | jq '.findings[] | select(.severity == "critical")'
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
## Supported Platforms
|
|
459
490
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
- **Generic MCP** - Any MCP server setup
|
|
491
|
+
# Count issues by category
|
|
492
|
+
hackmyagent secure --json | jq '[.findings[].id | split("-")[0]] | group_by(.) | map({(.[0]): length}) | add'
|
|
493
|
+
```
|
|
464
494
|
|
|
465
|
-
|
|
495
|
+
---
|
|
466
496
|
|
|
467
|
-
|
|
497
|
+
## Exit Codes
|
|
468
498
|
|
|
469
|
-
|
|
499
|
+
| Code | Meaning | Commands |
|
|
500
|
+
|------|---------|----------|
|
|
501
|
+
| `0` | Clean — no critical/high issues | All commands |
|
|
502
|
+
| `1` | Critical or high severity issues remain after scan/fix | `secure`, `fix-all`, `attack` |
|
|
503
|
+
| `2` | Incomplete scan — one or more plugins failed to run | `fix-all` |
|
|
470
504
|
|
|
471
|
-
|
|
505
|
+
---
|
|
472
506
|
|
|
473
|
-
|
|
474
|
-
| Check ID | Issue | Auto-Fix Action |
|
|
475
|
-
|----------|-------|-----------------|
|
|
476
|
-
| CRED-001 | Exposed API keys | Replace with env var reference |
|
|
477
|
-
| GIT-001 | Missing .gitignore | Create with secure defaults |
|
|
478
|
-
| GIT-002 | Incomplete .gitignore | Add missing patterns |
|
|
479
|
-
| PERM-001 | Overly permissive files | Set restrictive permissions |
|
|
480
|
-
| MCP-001 | Root filesystem access | Scope to project directory |
|
|
481
|
-
| NET-001 | Bound to 0.0.0.0 | Bind to 127.0.0.1 |
|
|
507
|
+
## Supported Platforms
|
|
482
508
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
|
487
|
-
|
|
|
488
|
-
|
|
|
489
|
-
| GATEWAY-005 | Sandbox disabled | Enable sandbox mode |
|
|
509
|
+
| Platform | What HackMyAgent scans |
|
|
510
|
+
|----------|------------------------|
|
|
511
|
+
| **Claude Code** | CLAUDE.md, skills, MCP server configs |
|
|
512
|
+
| **Cursor** | .cursor/ rules, MCP configurations |
|
|
513
|
+
| **VS Code** | .vscode/mcp.json configurations |
|
|
514
|
+
| **Generic MCP** | Any MCP server setup |
|
|
490
515
|
|
|
491
|
-
|
|
516
|
+
---
|
|
492
517
|
|
|
493
518
|
## Environment Variables
|
|
494
519
|
|
|
495
520
|
| Variable | Description |
|
|
496
521
|
|----------|-------------|
|
|
497
522
|
| `NO_COLOR` | Disable colored output |
|
|
498
|
-
| `HACKMYAGENT_TIMEOUT` | Default timeout for scans (ms) |
|
|
499
|
-
|
|
500
|
-
## Test Fixtures
|
|
501
|
-
|
|
502
|
-
Sample projects with intentional security issues for testing:
|
|
503
|
-
|
|
504
|
-
```bash
|
|
505
|
-
# Test the scanner against example projects
|
|
506
|
-
npx hackmyagent secure test-fixtures/insecure-api # Score: 27/100
|
|
507
|
-
npx hackmyagent secure test-fixtures/insecure-mcp # Score: 0/100
|
|
508
|
-
npx hackmyagent secure test-fixtures/insecure-library # Score: 60/100
|
|
509
|
-
npx hackmyagent secure test-fixtures/clean-project # Score: 100/100
|
|
510
|
-
|
|
511
|
-
# Test auto-fix
|
|
512
|
-
npx hackmyagent secure test-fixtures/insecure-api --fix
|
|
513
|
-
```
|
|
514
523
|
|
|
515
|
-
|
|
524
|
+
---
|
|
516
525
|
|
|
517
526
|
## Contributing
|
|
518
527
|
|
|
519
|
-
Contributions welcome
|
|
528
|
+
Contributions welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
520
529
|
|
|
521
530
|
```bash
|
|
522
|
-
# Development setup
|
|
523
531
|
git clone https://github.com/opena2a-org/hackmyagent.git
|
|
524
532
|
cd hackmyagent
|
|
525
533
|
npm install
|
|
526
|
-
|
|
527
|
-
|
|
534
|
+
npx turbo build # build all 7 packages
|
|
535
|
+
npx turbo test # run 501 tests
|
|
528
536
|
```
|
|
529
537
|
|
|
530
|
-
|
|
538
|
+
### Monorepo Structure
|
|
531
539
|
|
|
532
|
-
|
|
540
|
+
```
|
|
541
|
+
packages/
|
|
542
|
+
cli/ # CLI entry point (hackmyagent command)
|
|
543
|
+
core/ # Scanner engine (147 checks)
|
|
544
|
+
aim-core/ # Ed25519 identity, audit, policy, trust
|
|
545
|
+
plugin-core/ # Plugin interface and registry
|
|
546
|
+
secretless-openclaw/ # Credential scanner plugin
|
|
547
|
+
signcrypt-openclaw/ # Signing and hash pinning plugin
|
|
548
|
+
skillguard-openclaw/ # Permission and pattern scanner plugin
|
|
549
|
+
```
|
|
533
550
|
|
|
534
551
|
---
|
|
535
552
|
|
|
536
|
-
##
|
|
553
|
+
## License
|
|
537
554
|
|
|
538
|
-
|
|
555
|
+
Apache-2.0
|
|
556
|
+
|
|
557
|
+
---
|
|
539
558
|
|
|
540
|
-
|
|
559
|
+
Built by [OpenA2A](https://opena2a.org). HackMyAgent finds vulnerabilities. [AIM](https://github.com/opena2a-org/agent-identity-management) manages identity and access.
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @hackmyagent/core
|
|
3
3
|
* Core library for HackMyAgent security scanning
|
|
4
4
|
*/
|
|
5
|
-
export declare const VERSION = "0.4.
|
|
5
|
+
export declare const VERSION = "0.4.4";
|
|
6
6
|
export { checkSkill, parseSkillIdentifier, analyzePermissions, } from './checker';
|
|
7
7
|
export type { CheckResult, CheckOptions, PublisherInfo, PermissionInfo, RevocationInfo, RiskLevel, SkillIdentifier, PermissionAnalysis, } from './checker';
|
|
8
8
|
export { HardeningScanner } from './hardening';
|
|
@@ -14,6 +14,8 @@ export { ATTACK_CATEGORIES, ALL_PAYLOADS, PAYLOAD_STATS, getPayloads, getPayload
|
|
|
14
14
|
export type { AttackCategory, AttackIntensity, AttackSeverity, AttackPayload, AttackResult, AttackReport, AttackTarget, AttackOptions, CustomPayloadInput, CustomPayloadFile, FailPolicy, } from './attack';
|
|
15
15
|
export { OASB_1_CATEGORIES, OASB_1_VERSION, OASB_1_NAME, getControlsForLevel, getControlsForCategory, getCheckIdsForLevel, calculateRating, AVAILABLE_BENCHMARKS, isValidBenchmark, } from './benchmarks';
|
|
16
16
|
export type { BenchmarkLevel, BenchmarkControl, BenchmarkCategory, BenchmarkResult, BenchmarkCategoryResult, BenchmarkControlResult, BenchmarkName, } from './benchmarks';
|
|
17
|
+
export { RegistryClient, buildScanReport, buildAttackReport, } from './registry';
|
|
18
|
+
export type { RegistryConfig, RegistryPackage, ScanReportPayload, } from './registry';
|
|
17
19
|
export interface ScanResult {
|
|
18
20
|
target: string;
|
|
19
21
|
findings: Finding[];
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAEnB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,EACf,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,qBAAa,OAAO;IACZ,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAQhD"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAEnB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,EACf,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,qBAAa,OAAO;IACZ,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAQhD"}
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Core library for HackMyAgent security scanning
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.Scanner = exports.isValidBenchmark = exports.AVAILABLE_BENCHMARKS = exports.calculateRating = exports.getCheckIdsForLevel = exports.getControlsForCategory = exports.getControlsForLevel = exports.OASB_1_NAME = exports.OASB_1_VERSION = exports.OASB_1_CATEGORIES = exports.shouldFail = exports.parseCustomPayloads = exports.getPayloadsByIntensity = exports.getPayloadsByCategory = exports.getPayloadById = exports.getPayloads = exports.PAYLOAD_STATS = exports.ALL_PAYLOADS = exports.ATTACK_CATEGORIES = exports.AttackScanner = exports.ExternalScanner = exports.HardeningScanner = exports.analyzePermissions = exports.parseSkillIdentifier = exports.checkSkill = exports.VERSION = void 0;
|
|
7
|
+
exports.Scanner = exports.buildAttackReport = exports.buildScanReport = exports.RegistryClient = exports.isValidBenchmark = exports.AVAILABLE_BENCHMARKS = exports.calculateRating = exports.getCheckIdsForLevel = exports.getControlsForCategory = exports.getControlsForLevel = exports.OASB_1_NAME = exports.OASB_1_VERSION = exports.OASB_1_CATEGORIES = exports.shouldFail = exports.parseCustomPayloads = exports.getPayloadsByIntensity = exports.getPayloadsByCategory = exports.getPayloadById = exports.getPayloads = exports.PAYLOAD_STATS = exports.ALL_PAYLOADS = exports.ATTACK_CATEGORIES = exports.AttackScanner = exports.ExternalScanner = exports.HardeningScanner = exports.analyzePermissions = exports.parseSkillIdentifier = exports.checkSkill = exports.VERSION = void 0;
|
|
8
8
|
exports.createScanner = createScanner;
|
|
9
|
-
exports.VERSION = '0.4.
|
|
9
|
+
exports.VERSION = '0.4.4';
|
|
10
10
|
// Checker module
|
|
11
11
|
var checker_1 = require("./checker");
|
|
12
12
|
Object.defineProperty(exports, "checkSkill", { enumerable: true, get: function () { return checker_1.checkSkill; } });
|
|
@@ -42,6 +42,11 @@ Object.defineProperty(exports, "getCheckIdsForLevel", { enumerable: true, get: f
|
|
|
42
42
|
Object.defineProperty(exports, "calculateRating", { enumerable: true, get: function () { return benchmarks_1.calculateRating; } });
|
|
43
43
|
Object.defineProperty(exports, "AVAILABLE_BENCHMARKS", { enumerable: true, get: function () { return benchmarks_1.AVAILABLE_BENCHMARKS; } });
|
|
44
44
|
Object.defineProperty(exports, "isValidBenchmark", { enumerable: true, get: function () { return benchmarks_1.isValidBenchmark; } });
|
|
45
|
+
// Registry module
|
|
46
|
+
var registry_1 = require("./registry");
|
|
47
|
+
Object.defineProperty(exports, "RegistryClient", { enumerable: true, get: function () { return registry_1.RegistryClient; } });
|
|
48
|
+
Object.defineProperty(exports, "buildScanReport", { enumerable: true, get: function () { return registry_1.buildScanReport; } });
|
|
49
|
+
Object.defineProperty(exports, "buildAttackReport", { enumerable: true, get: function () { return registry_1.buildAttackReport; } });
|
|
45
50
|
function createScanner() {
|
|
46
51
|
return new Scanner();
|
|
47
52
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAkHH,sCAEC;AAlHY,QAAA,OAAO,GAAG,OAAO,CAAC;AAE/B,iBAAiB;AACjB,qCAImB;AAHjB,qGAAA,UAAU,OAAA;AACV,+GAAA,oBAAoB,OAAA;AACpB,6GAAA,kBAAkB,OAAA;AAcpB,mBAAmB;AACnB,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AAGzB,0BAA0B;AAC1B,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AAQxB,gBAAgB;AAChB,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AAEtB,mCAUkB;AAThB,2GAAA,iBAAiB,OAAA;AACjB,sGAAA,YAAY,OAAA;AACZ,uGAAA,aAAa,OAAA;AACb,qGAAA,WAAW,OAAA;AACX,wGAAA,cAAc,OAAA;AACd,+GAAA,qBAAqB,OAAA;AACrB,gHAAA,sBAAsB,OAAA;AACtB,6GAAA,mBAAmB,OAAA;AACnB,oGAAA,UAAU,OAAA;AAiBZ,oBAAoB;AACpB,2CAUsB;AATpB,+GAAA,iBAAiB,OAAA;AACjB,4GAAA,cAAc,OAAA;AACd,yGAAA,WAAW,OAAA;AACX,iHAAA,mBAAmB,OAAA;AACnB,oHAAA,sBAAsB,OAAA;AACtB,iHAAA,mBAAmB,OAAA;AACnB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AACpB,8GAAA,gBAAgB,OAAA;AAalB,kBAAkB;AAClB,uCAIoB;AAHlB,0GAAA,cAAc,OAAA;AACd,2GAAA,eAAe,OAAA;AACf,6GAAA,iBAAiB,OAAA;AAuBnB,SAAgB,aAAa;IAC3B,OAAO,IAAI,OAAO,EAAE,CAAC;AACvB,CAAC;AAED,MAAa,OAAO;IAClB,KAAK,CAAC,IAAI,CAAC,MAAc;QACvB,6BAA6B;QAC7B,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC;IACJ,CAAC;CACF;AATD,0BASC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenA2A Registry client for posting scan results.
|
|
3
|
+
*
|
|
4
|
+
* Maps HackMyAgent scan findings to the registry's ScanResult format
|
|
5
|
+
* and POSTs them to the registry callback endpoint.
|
|
6
|
+
*/
|
|
7
|
+
import type { SecurityFinding } from '../hardening';
|
|
8
|
+
import type { AttackReport } from '../attack';
|
|
9
|
+
export interface ScanReportPayload {
|
|
10
|
+
versionId: string;
|
|
11
|
+
scanId: string;
|
|
12
|
+
status: 'passed' | 'failed' | 'warnings' | 'error';
|
|
13
|
+
completedAt: string;
|
|
14
|
+
vulnerabilities: VulnerabilityFinding[];
|
|
15
|
+
criticalCount: number;
|
|
16
|
+
highCount: number;
|
|
17
|
+
mediumCount: number;
|
|
18
|
+
lowCount: number;
|
|
19
|
+
observedCapabilities: string[];
|
|
20
|
+
observedExternalApis: string[];
|
|
21
|
+
capabilityMismatch: boolean;
|
|
22
|
+
behavioralFindings: BehavioralFinding[];
|
|
23
|
+
behavioralScore: number;
|
|
24
|
+
rawReport: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
interface VulnerabilityFinding {
|
|
27
|
+
id: string;
|
|
28
|
+
severity: string;
|
|
29
|
+
title: string;
|
|
30
|
+
description: string;
|
|
31
|
+
package?: string;
|
|
32
|
+
version?: string;
|
|
33
|
+
fixedIn?: string;
|
|
34
|
+
cves?: string[];
|
|
35
|
+
cvss?: number;
|
|
36
|
+
}
|
|
37
|
+
interface BehavioralFinding {
|
|
38
|
+
type: string;
|
|
39
|
+
severity: string;
|
|
40
|
+
description: string;
|
|
41
|
+
evidence?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface RegistryConfig {
|
|
44
|
+
registryUrl: string;
|
|
45
|
+
apiKey: string;
|
|
46
|
+
}
|
|
47
|
+
export interface RegistryPackage {
|
|
48
|
+
id: string;
|
|
49
|
+
publisherId: string;
|
|
50
|
+
name: string;
|
|
51
|
+
packageType: string;
|
|
52
|
+
}
|
|
53
|
+
export declare class RegistryClient {
|
|
54
|
+
private config;
|
|
55
|
+
constructor(config: RegistryConfig);
|
|
56
|
+
/**
|
|
57
|
+
* Post scan results to registry callback endpoint.
|
|
58
|
+
*/
|
|
59
|
+
reportScanResult(payload: ScanReportPayload): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Look up package info from registry.
|
|
62
|
+
*/
|
|
63
|
+
getPackage(publisherName: string, packageType: string, name: string): Promise<RegistryPackage | null>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build a ScanReportPayload from HMA hardening scan results.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildScanReport(versionId: string, findings: SecurityFinding[]): ScanReportPayload;
|
|
69
|
+
/**
|
|
70
|
+
* Build a ScanReportPayload from HMA attack results.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildAttackReport(versionId: string, report: AttackReport): ScanReportPayload;
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/registry/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAY,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,oBAAoB,EAAE,CAAC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,EAAE,cAAc;IAIlC;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjE;;OAEG;IACG,UAAU,CACd,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAmBnC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,EAAE,GAC1B,iBAAiB,CA2CnB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GACnB,iBAAiB,CA0CnB"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenA2A Registry client for posting scan results.
|
|
4
|
+
*
|
|
5
|
+
* Maps HackMyAgent scan findings to the registry's ScanResult format
|
|
6
|
+
* and POSTs them to the registry callback endpoint.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RegistryClient = void 0;
|
|
10
|
+
exports.buildScanReport = buildScanReport;
|
|
11
|
+
exports.buildAttackReport = buildAttackReport;
|
|
12
|
+
class RegistryClient {
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Post scan results to registry callback endpoint.
|
|
18
|
+
*/
|
|
19
|
+
async reportScanResult(payload) {
|
|
20
|
+
const url = `${this.config.registryUrl}/api/v1/registry/internal/scan-result`;
|
|
21
|
+
const response = await fetch(url, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
'Content-Type': 'application/json',
|
|
25
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
26
|
+
'User-Agent': 'HackMyAgent-CLI',
|
|
27
|
+
},
|
|
28
|
+
body: JSON.stringify(payload),
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
const body = await response.text().catch(() => '');
|
|
32
|
+
throw new Error(`Registry report failed (${response.status}): ${body}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Look up package info from registry.
|
|
37
|
+
*/
|
|
38
|
+
async getPackage(publisherName, packageType, name) {
|
|
39
|
+
const url = `${this.config.registryUrl}/api/v1/registry/${packageType}/${name}?publisher=${publisherName}`;
|
|
40
|
+
const response = await fetch(url, {
|
|
41
|
+
headers: {
|
|
42
|
+
'User-Agent': 'HackMyAgent-CLI',
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
if (response.status === 404) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`Registry lookup failed (${response.status})`);
|
|
50
|
+
}
|
|
51
|
+
return response.json();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.RegistryClient = RegistryClient;
|
|
55
|
+
/**
|
|
56
|
+
* Build a ScanReportPayload from HMA hardening scan results.
|
|
57
|
+
*/
|
|
58
|
+
function buildScanReport(versionId, findings) {
|
|
59
|
+
const failed = findings.filter(f => !f.passed && !f.fixed);
|
|
60
|
+
const counts = countBySeverity(failed);
|
|
61
|
+
const status = deriveStatus(counts);
|
|
62
|
+
// Map failed findings to vulnerability format
|
|
63
|
+
const vulnerabilities = failed.map(f => ({
|
|
64
|
+
id: f.checkId,
|
|
65
|
+
severity: f.severity,
|
|
66
|
+
title: f.name,
|
|
67
|
+
description: f.description,
|
|
68
|
+
}));
|
|
69
|
+
// Extract observed capabilities from capability-related checks
|
|
70
|
+
const observedCapabilities = [];
|
|
71
|
+
for (const f of findings) {
|
|
72
|
+
if (f.checkId.startsWith('FS-') && !f.passed)
|
|
73
|
+
observedCapabilities.push('filesystem');
|
|
74
|
+
if (f.checkId.startsWith('NET-') && !f.passed)
|
|
75
|
+
observedCapabilities.push('network');
|
|
76
|
+
if (f.checkId.startsWith('SHELL-') && !f.passed)
|
|
77
|
+
observedCapabilities.push('shell_exec');
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
versionId,
|
|
81
|
+
scanId: `hma-${Date.now()}`,
|
|
82
|
+
status,
|
|
83
|
+
completedAt: new Date().toISOString(),
|
|
84
|
+
vulnerabilities,
|
|
85
|
+
criticalCount: counts.critical,
|
|
86
|
+
highCount: counts.high,
|
|
87
|
+
mediumCount: counts.medium,
|
|
88
|
+
lowCount: counts.low,
|
|
89
|
+
observedCapabilities: [...new Set(observedCapabilities)],
|
|
90
|
+
observedExternalApis: [],
|
|
91
|
+
capabilityMismatch: false,
|
|
92
|
+
behavioralFindings: [],
|
|
93
|
+
behavioralScore: 0,
|
|
94
|
+
rawReport: {
|
|
95
|
+
generator: 'hackmyagent',
|
|
96
|
+
totalFindings: findings.length,
|
|
97
|
+
failedFindings: failed.length,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build a ScanReportPayload from HMA attack results.
|
|
103
|
+
*/
|
|
104
|
+
function buildAttackReport(versionId, report) {
|
|
105
|
+
const vulnerabilities = report.results
|
|
106
|
+
.filter(r => r.success)
|
|
107
|
+
.map(r => ({
|
|
108
|
+
id: r.payload.id,
|
|
109
|
+
severity: r.payload.severity,
|
|
110
|
+
title: `${r.payload.category}: ${r.payload.id}`,
|
|
111
|
+
description: r.response?.substring(0, 500) || 'Attack succeeded',
|
|
112
|
+
}));
|
|
113
|
+
const counts = {
|
|
114
|
+
critical: vulnerabilities.filter(v => v.severity === 'critical').length,
|
|
115
|
+
high: vulnerabilities.filter(v => v.severity === 'high').length,
|
|
116
|
+
medium: vulnerabilities.filter(v => v.severity === 'medium').length,
|
|
117
|
+
low: vulnerabilities.filter(v => v.severity === 'low').length,
|
|
118
|
+
};
|
|
119
|
+
const status = deriveStatus(counts);
|
|
120
|
+
return {
|
|
121
|
+
versionId,
|
|
122
|
+
scanId: `hma-attack-${Date.now()}`,
|
|
123
|
+
status,
|
|
124
|
+
completedAt: new Date().toISOString(),
|
|
125
|
+
vulnerabilities,
|
|
126
|
+
criticalCount: counts.critical,
|
|
127
|
+
highCount: counts.high,
|
|
128
|
+
mediumCount: counts.medium,
|
|
129
|
+
lowCount: counts.low,
|
|
130
|
+
observedCapabilities: [],
|
|
131
|
+
observedExternalApis: [],
|
|
132
|
+
capabilityMismatch: false,
|
|
133
|
+
behavioralFindings: [],
|
|
134
|
+
behavioralScore: 0,
|
|
135
|
+
rawReport: {
|
|
136
|
+
generator: 'hackmyagent-attack',
|
|
137
|
+
target: report.target,
|
|
138
|
+
riskRating: report.riskRating,
|
|
139
|
+
totalPayloads: report.summary.total,
|
|
140
|
+
successfulAttacks: report.summary.successful,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function countBySeverity(findings) {
|
|
145
|
+
return {
|
|
146
|
+
critical: findings.filter(f => f.severity === 'critical').length,
|
|
147
|
+
high: findings.filter(f => f.severity === 'high').length,
|
|
148
|
+
medium: findings.filter(f => f.severity === 'medium').length,
|
|
149
|
+
low: findings.filter(f => f.severity === 'low').length,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function deriveStatus(counts) {
|
|
153
|
+
if (counts.critical > 0 || counts.high > 0)
|
|
154
|
+
return 'failed';
|
|
155
|
+
if (counts.medium > 0 || counts.low > 0)
|
|
156
|
+
return 'warnings';
|
|
157
|
+
return 'passed';
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/registry/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAttackReport = exports.buildScanReport = exports.RegistryClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "RegistryClient", { enumerable: true, get: function () { return client_1.RegistryClient; } });
|
|
6
|
+
Object.defineProperty(exports, "buildScanReport", { enumerable: true, get: function () { return client_1.buildScanReport; } });
|
|
7
|
+
Object.defineProperty(exports, "buildAttackReport", { enumerable: true, get: function () { return client_1.buildAttackReport; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":";;;AAAA,mCAIkB;AAHhB,wGAAA,cAAc,OAAA;AACd,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA"}
|