hackmyagent 0.11.6 → 0.11.8
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 +6 -7
- package/dist/cli.js +39 -19
- package/dist/cli.js.map +1 -1
- package/dist/hardening/scanner.d.ts +39 -0
- package/dist/hardening/scanner.d.ts.map +1 -1
- package/dist/hardening/scanner.js +583 -0
- package/dist/hardening/scanner.js.map +1 -1
- package/dist/hardening/security-check.d.ts +2 -0
- package/dist/hardening/security-check.d.ts.map +1 -1
- package/dist/hardening/taxonomy.d.ts.map +1 -1
- package/dist/hardening/taxonomy.js +13 -0
- package/dist/hardening/taxonomy.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp-server.js +1 -1
- package/dist/mcp-server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
> **[OpenA2A](https://github.com/opena2a-org/opena2a)**: [CLI](https://github.com/opena2a-org/opena2a) · [HackMyAgent](https://github.com/opena2a-org/hackmyagent) · [Secretless](https://github.com/opena2a-org/secretless-ai) · [AIM](https://github.com/opena2a-org/agent-identity-management) · [Browser Guard](https://github.com/opena2a-org/AI-BrowserGuard) · [DVAA](https://github.com/opena2a-org/damn-vulnerable-ai-agent)
|
|
2
|
-
|
|
1
|
+
> **[OpenA2A](https://github.com/opena2a-org/opena2a)**: [CLI](https://github.com/opena2a-org/opena2a) · [HackMyAgent](https://github.com/opena2a-org/hackmyagent) · [Secretless](https://github.com/opena2a-org/secretless-ai) · [AIM](https://github.com/opena2a-org/agent-identity-management) · [Browser Guard](https://github.com/opena2a-org/AI-BrowserGuard) · [DVAA](https://github.com/opena2a-org/damn-vulnerable-ai-agent)
|
|
3
2
|
# HackMyAgent
|
|
4
3
|
|
|
5
4
|
[](https://www.npmjs.com/package/hackmyagent)
|
|
6
5
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
6
|
[](https://github.com/opena2a-org/hackmyagent)
|
|
8
7
|
|
|
9
|
-
**
|
|
8
|
+
**187 security checks for AI agents. Find what can go wrong before an attacker does.**
|
|
10
9
|
|
|
11
10
|
Security scanner and red-team toolkit for Claude Code, Cursor, VS Code, and any MCP server setup.
|
|
12
11
|
|
|
@@ -32,7 +31,7 @@ npx opena2a-cli review
|
|
|
32
31
|
|
|
33
32
|
**Attack testing** -- 115 adversarial payloads across 11 categories (prompt injection, data exfiltration, jailbreak, MCP exploitation, supply chain, memory weaponization, A2A protocol attacks, context window attacks).
|
|
34
33
|
|
|
35
|
-
**Static analysis** --
|
|
34
|
+
**Static analysis** -- 187 security checks across 39 categories covering credentials, MCP configs, OpenClaw/NemoClaw, Unicode steganography, CVE detection, governance, supply chain, memory poisoning, agent identity, and sandbox escape patterns.
|
|
36
35
|
|
|
37
36
|
<details>
|
|
38
37
|
<summary>Attack testing details (115 payloads)</summary>
|
|
@@ -50,7 +49,7 @@ npx opena2a-cli review
|
|
|
50
49
|
</details>
|
|
51
50
|
|
|
52
51
|
<details>
|
|
53
|
-
<summary>Static analysis details (
|
|
52
|
+
<summary>Static analysis details (187 checks)</summary>
|
|
54
53
|
|
|
55
54
|
- **Unicode steganography** -- invisible codepoints, zero-width chars, bidi attacks, homoglyph confusables, GlassWorm decoders ([real-world: os-info-checker-es6 npm attack, May 2025](https://thehackernews.com/2025/05/malicious-npm-package-leverages-unicode.html))
|
|
56
55
|
- **Hardcoded credentials** -- API keys, tokens, and passwords in source or config files
|
|
@@ -66,7 +65,7 @@ npx opena2a-cli review
|
|
|
66
65
|
|
|
67
66
|
</details>
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
187 checks across 39 categories. 115 attack payloads. No flags needed.
|
|
70
69
|
|
|
71
70
|
---
|
|
72
71
|
|
|
@@ -108,7 +107,7 @@ npm install --save-dev hackmyagent
|
|
|
108
107
|
|
|
109
108
|
Step-by-step guides for common workflows:
|
|
110
109
|
|
|
111
|
-
- **[Scan my agent](docs/use-cases/scan-my-agent.md)** -- Run all
|
|
110
|
+
- **[Scan my agent](docs/use-cases/scan-my-agent.md)** -- Run all 187 checks and auto-fix findings (5 min)
|
|
112
111
|
- **[Red-team MCP servers](docs/use-cases/red-team-mcp.md)** -- Test MCP servers with adversarial payloads (10 min)
|
|
113
112
|
- **[Secure OpenClaw](docs/use-cases/openclaw-security.md)** -- OpenClaw-specific checks, CVE detection, ClawHavoc IOC scanning (10 min)
|
|
114
113
|
- **Secure NemoClaw** -- Scan NVIDIA NemoClaw sandbox installations for credential exposure, network misconfig, and sandbox escape vectors (5 min)
|
package/dist/cli.js
CHANGED
|
@@ -43,6 +43,7 @@ const index_1 = require("./index");
|
|
|
43
43
|
const resolve_mcp_1 = require("./resolve-mcp");
|
|
44
44
|
const nemoclaw_scanner_1 = require("./hardening/nemoclaw-scanner");
|
|
45
45
|
const program = new commander_1.Command();
|
|
46
|
+
program.showHelpAfterError('(run with --help for usage)');
|
|
46
47
|
// Write JSON to stdout synchronously with retry for pipe backpressure.
|
|
47
48
|
// process.stdout.write() is async and gets truncated when process.exit()
|
|
48
49
|
// runs before the stream flushes. fs.writeFileSync(1, ...) can fail with
|
|
@@ -104,7 +105,7 @@ program
|
|
|
104
105
|
.name('hackmyagent')
|
|
105
106
|
.description(`Find it. Break it. Fix it.
|
|
106
107
|
|
|
107
|
-
The hacker's toolkit for AI agents.
|
|
108
|
+
The hacker's toolkit for AI agents. 187 security checks, 115 attack
|
|
108
109
|
payloads, auto-fix with rollback, and OASB benchmark compliance.
|
|
109
110
|
|
|
110
111
|
Documentation: https://hackmyagent.com/docs
|
|
@@ -113,10 +114,10 @@ Updates (v${index_1.VERSION}):
|
|
|
113
114
|
- NemoClaw sandbox scanner (28 installation checks)
|
|
114
115
|
- 10 new static analysis patterns (NEMO series)
|
|
115
116
|
- Community trust contributions
|
|
116
|
-
-
|
|
117
|
+
- 187 checks across 39 categories
|
|
117
118
|
|
|
118
119
|
Examples:
|
|
119
|
-
$ hackmyagent secure Find vulnerabilities (
|
|
120
|
+
$ hackmyagent secure Find vulnerabilities (187 checks)
|
|
120
121
|
$ hackmyagent attack --local Break it with 115 attack payloads
|
|
121
122
|
$ hackmyagent secure --fix Fix issues automatically
|
|
122
123
|
$ hackmyagent fix-all Run all security plugins
|
|
@@ -125,7 +126,7 @@ Examples:
|
|
|
125
126
|
.option('--no-color', 'Disable colored output (also respects NO_COLOR env)');
|
|
126
127
|
program.addHelpText('beforeAll', `
|
|
127
128
|
Quick start:
|
|
128
|
-
$ hackmyagent secure Scan current directory (
|
|
129
|
+
$ hackmyagent secure Scan current directory (187 checks)
|
|
129
130
|
$ hackmyagent fix-all --with-aim Auto-fix + create agent identity
|
|
130
131
|
$ hackmyagent attack Red-team your agent
|
|
131
132
|
`);
|
|
@@ -1621,7 +1622,7 @@ program
|
|
|
1621
1622
|
.command('secure')
|
|
1622
1623
|
.description(`Scan and harden your agent setup
|
|
1623
1624
|
|
|
1624
|
-
Performs
|
|
1625
|
+
Performs 187 security checks across 39 categories:
|
|
1625
1626
|
• Credentials: API key exposure, secrets in configs
|
|
1626
1627
|
• MCP: Server configs, tool permissions, secrets
|
|
1627
1628
|
• Network: TLS, interface bindings, CORS
|
|
@@ -1679,7 +1680,7 @@ Examples:
|
|
|
1679
1680
|
.option('--ci', 'CI mode: suppress interactive prompts, exit non-zero on findings')
|
|
1680
1681
|
.action(async (directory, options) => {
|
|
1681
1682
|
try {
|
|
1682
|
-
const targetDir =
|
|
1683
|
+
const targetDir = require("path").resolve(directory);
|
|
1683
1684
|
// CI mode: force non-interactive defaults
|
|
1684
1685
|
if (options.ci) {
|
|
1685
1686
|
if (!options.format && !options.json)
|
|
@@ -1962,8 +1963,12 @@ Examples:
|
|
|
1962
1963
|
console.log(`${colors.green}No issues found.${RESET()}\n`);
|
|
1963
1964
|
}
|
|
1964
1965
|
else if (issues.length > 0) {
|
|
1965
|
-
// Print issues - clean format
|
|
1966
|
-
|
|
1966
|
+
// Print issues - clean format with fixable count
|
|
1967
|
+
const fixableCount = issues.filter((f) => f.fixable).length;
|
|
1968
|
+
const fixableNote = fixableCount > 0
|
|
1969
|
+
? ` (${fixableCount} auto-fixable with \`${CLI_PREFIX} secure --fix\`)`
|
|
1970
|
+
: '';
|
|
1971
|
+
console.log(`${issues.length} issue${issues.length === 1 ? '' : 's'} found${fixableNote}:\n`);
|
|
1967
1972
|
for (const finding of issues) {
|
|
1968
1973
|
const display = SEVERITY_DISPLAY[finding.severity];
|
|
1969
1974
|
const location = finding.file
|
|
@@ -2022,17 +2027,32 @@ Examples:
|
|
|
2022
2027
|
console.log(` No changes were made.\n`);
|
|
2023
2028
|
}
|
|
2024
2029
|
}
|
|
2025
|
-
// Print fixed findings
|
|
2030
|
+
// Print fixed findings with detailed summary
|
|
2026
2031
|
if (fixedFindings.length > 0) {
|
|
2027
|
-
|
|
2032
|
+
const verifiedCount = fixedFindings.filter((f) => f.fixVerified).length;
|
|
2033
|
+
const unverifiedCount = fixedFindings.filter((f) => f.fixVerified === false).length;
|
|
2034
|
+
console.log(`${colors.green}Fixed ${fixedFindings.length} issue${fixedFindings.length === 1 ? '' : 's'}${verifiedCount > 0 ? ` (${verifiedCount} verified)` : ''}:${RESET()}`);
|
|
2028
2035
|
for (const finding of fixedFindings) {
|
|
2029
|
-
const location = finding.file
|
|
2030
|
-
|
|
2036
|
+
const location = finding.file ? (finding.line ? `${finding.file}:${finding.line}` : finding.file) : '';
|
|
2037
|
+
const verified = finding.fixVerified;
|
|
2038
|
+
const verifyIcon = verified === true ? `${colors.green}✓✓${RESET()}` : verified === false ? `${colors.yellow}✓?${RESET()}` : `${colors.green}✓${RESET()}`;
|
|
2039
|
+
console.log(` ${verifyIcon} [${finding.checkId}] ${location} - ${finding.name}`);
|
|
2040
|
+
if (finding.fixMessage) {
|
|
2041
|
+
console.log(` ${colors.cyan}→${RESET()} ${finding.fixMessage}`);
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
if (unverifiedCount > 0) {
|
|
2045
|
+
console.log(`\n ${colors.yellow}${unverifiedCount} fix${unverifiedCount === 1 ? '' : 'es'} could not be verified. Review these manually.${RESET()}`);
|
|
2031
2046
|
}
|
|
2032
2047
|
console.log();
|
|
2048
|
+
// Remaining fixable issues
|
|
2049
|
+
const remainingFixable = issues.filter((f) => f.fixable && !f.fixed);
|
|
2050
|
+
if (remainingFixable.length > 0) {
|
|
2051
|
+
console.log(`${colors.yellow}${remainingFixable.length} more issue${remainingFixable.length === 1 ? '' : 's'} can be auto-fixed.${RESET()} Run \`${CLI_PREFIX} secure --fix\` again.\n`);
|
|
2052
|
+
}
|
|
2033
2053
|
if (result.backupPath) {
|
|
2034
|
-
console.log(
|
|
2035
|
-
console.log(
|
|
2054
|
+
console.log(`${colors.yellow}Backup created:${RESET()} ${result.backupPath}`);
|
|
2055
|
+
console.log(`${colors.yellow}Something wrong?${RESET()} Run \`${CLI_PREFIX} rollback ${directory}\` to undo all changes.\n`);
|
|
2036
2056
|
}
|
|
2037
2057
|
}
|
|
2038
2058
|
// Registry reporting: only when explicitly requested via --version-id (CI) or --registry-report
|
|
@@ -2644,7 +2664,7 @@ Examples:
|
|
|
2644
2664
|
.argument('[directory]', 'Directory to rollback (defaults to current directory)', '.')
|
|
2645
2665
|
.action(async (directory) => {
|
|
2646
2666
|
try {
|
|
2647
|
-
const targetDir =
|
|
2667
|
+
const targetDir = require("path").resolve(directory);
|
|
2648
2668
|
console.log(`\nRolling back changes in ${targetDir}...\n`);
|
|
2649
2669
|
const scanner = new index_1.HardeningScanner();
|
|
2650
2670
|
await scanner.rollback(targetDir);
|
|
@@ -4096,7 +4116,7 @@ Examples:
|
|
|
4096
4116
|
.option('-t, --tool <name>', 'Force specific tool: claude, cursor, vscode')
|
|
4097
4117
|
.action(async (directory, options) => {
|
|
4098
4118
|
try {
|
|
4099
|
-
const targetDir =
|
|
4119
|
+
const targetDir = require("path").resolve(directory);
|
|
4100
4120
|
const { initMcp } = await Promise.resolve().then(() => __importStar(require('./init-mcp')));
|
|
4101
4121
|
const result = initMcp(targetDir, options.tool);
|
|
4102
4122
|
if (!result.created) {
|
|
@@ -4106,7 +4126,7 @@ Examples:
|
|
|
4106
4126
|
console.log(`\n Detected: ${result.tool}\n`);
|
|
4107
4127
|
console.log(` Added HackMyAgent MCP server to ${result.configPath}\n`);
|
|
4108
4128
|
console.log(` Available tools in ${result.tool}:`);
|
|
4109
|
-
console.log(` hackmyagent_scan —
|
|
4129
|
+
console.log(` hackmyagent_scan — 187 checks + structural analysis`);
|
|
4110
4130
|
console.log(` hackmyagent_deep_scan — Full analysis with LLM reasoning`);
|
|
4111
4131
|
console.log(` hackmyagent_analyze_file — Analyze a single file`);
|
|
4112
4132
|
console.log(` hackmyagent_benchmark — OASB-1 compliance assessment\n`);
|
|
@@ -4201,7 +4221,7 @@ Examples:
|
|
|
4201
4221
|
.option('--ci', 'CI mode: suppress interactive prompts, exit non-zero on findings')
|
|
4202
4222
|
.action(async (directory, options) => {
|
|
4203
4223
|
try {
|
|
4204
|
-
const targetDir =
|
|
4224
|
+
const targetDir = require("path").resolve(directory);
|
|
4205
4225
|
// CI mode: force non-interactive defaults
|
|
4206
4226
|
if (options.ci) {
|
|
4207
4227
|
if (options.contribute === undefined)
|
|
@@ -4418,7 +4438,7 @@ Examples:
|
|
|
4418
4438
|
.option('--json', 'Output as JSON')
|
|
4419
4439
|
.action(async (directory, options) => {
|
|
4420
4440
|
try {
|
|
4421
|
-
const targetDir =
|
|
4441
|
+
const targetDir = require("path").resolve(directory);
|
|
4422
4442
|
if (!require('fs').existsSync(targetDir)) {
|
|
4423
4443
|
process.stderr.write(`Error: Directory '${targetDir}' does not exist.\n`);
|
|
4424
4444
|
process.exit(1);
|