hackmyagent 0.11.6 → 0.11.7

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 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) · Registry (April 2026)
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
  [![npm version](https://img.shields.io/npm/v/hackmyagent.svg)](https://www.npmjs.com/package/hackmyagent)
6
5
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
6
  [![Tests](https://img.shields.io/badge/tests-1051%20passing-brightgreen)](https://github.com/opena2a-org/hackmyagent)
8
7
 
9
- **183 security checks for AI agents. Find what can go wrong before an attacker does.**
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** -- 183 security checks across 35 categories covering credentials, MCP configs, OpenClaw/NemoClaw, Unicode steganography, CVE detection, governance, supply chain, memory poisoning, agent identity, and sandbox escape patterns.
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 (183 checks)</summary>
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
- 183 checks across 35 categories. 115 attack payloads. No flags needed.
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 183 checks and auto-fix findings (5 min)
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. 183 security checks, 115 attack
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
- - 183 checks across 35 categories
117
+ - 187 checks across 39 categories
117
118
 
118
119
  Examples:
119
- $ hackmyagent secure Find vulnerabilities (183 checks)
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 (183 checks)
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 183 security checks across 35 categories:
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 = directory.startsWith('/') ? directory : process.cwd() + '/' + directory;
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
- console.log(`${issues.length} issue${issues.length === 1 ? '' : 's'} found:\n`);
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
- console.log(`${colors.green}Fixed ${fixedFindings.length} issue${fixedFindings.length === 1 ? '' : 's'}:${RESET()}`);
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
- console.log(` ${colors.green}✓${RESET()} ${location} - ${finding.name}`);
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(`Backup: ${result.backupPath}`);
2035
- console.log(`Undo: ${CLI_PREFIX} rollback ${directory}\n`);
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 = directory.startsWith('/') ? directory : process.cwd() + '/' + directory;
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 = directory.startsWith('/') ? directory : process.cwd() + '/' + directory;
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 — 183 checks + structural analysis`);
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 = directory.startsWith('/') ? directory : process.cwd() + '/' + directory;
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 = directory.startsWith('/') ? directory : process.cwd() + '/' + directory;
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);