hackmyagent 0.7.2 → 0.8.0
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/LICENSE +191 -0
- package/README.md +66 -28
- package/dist/arp/cli/index.d.ts +3 -0
- package/dist/arp/cli/index.d.ts.map +1 -0
- package/dist/arp/cli/index.js +219 -0
- package/dist/arp/cli/index.js.map +1 -0
- package/dist/arp/config/loader.d.ts +8 -0
- package/dist/arp/config/loader.d.ts.map +1 -0
- package/dist/arp/config/loader.js +102 -0
- package/dist/arp/config/loader.js.map +1 -0
- package/dist/arp/enforcement/kill-switch.d.ts +22 -0
- package/dist/arp/enforcement/kill-switch.d.ts.map +1 -0
- package/dist/arp/enforcement/kill-switch.js +122 -0
- package/dist/arp/enforcement/kill-switch.js.map +1 -0
- package/dist/arp/engine/event-engine.d.ts +29 -0
- package/dist/arp/engine/event-engine.d.ts.map +1 -0
- package/dist/arp/engine/event-engine.js +233 -0
- package/dist/arp/engine/event-engine.js.map +1 -0
- package/dist/arp/index.d.ts +81 -0
- package/dist/arp/index.d.ts.map +1 -0
- package/dist/arp/index.js +239 -0
- package/dist/arp/index.js.map +1 -0
- package/dist/arp/intelligence/adapters.d.ts +45 -0
- package/dist/arp/intelligence/adapters.d.ts.map +1 -0
- package/dist/arp/intelligence/adapters.js +222 -0
- package/dist/arp/intelligence/adapters.js.map +1 -0
- package/dist/arp/intelligence/anomaly.d.ts +32 -0
- package/dist/arp/intelligence/anomaly.d.ts.map +1 -0
- package/dist/arp/intelligence/anomaly.js +80 -0
- package/dist/arp/intelligence/anomaly.js.map +1 -0
- package/dist/arp/intelligence/budget.d.ts +33 -0
- package/dist/arp/intelligence/budget.d.ts.map +1 -0
- package/dist/arp/intelligence/budget.js +150 -0
- package/dist/arp/intelligence/budget.js.map +1 -0
- package/dist/arp/intelligence/coordinator.d.ts +43 -0
- package/dist/arp/intelligence/coordinator.d.ts.map +1 -0
- package/dist/arp/intelligence/coordinator.js +301 -0
- package/dist/arp/intelligence/coordinator.js.map +1 -0
- package/dist/arp/interceptors/a2a-protocol.d.ts +29 -0
- package/dist/arp/interceptors/a2a-protocol.d.ts.map +1 -0
- package/dist/arp/interceptors/a2a-protocol.js +111 -0
- package/dist/arp/interceptors/a2a-protocol.js.map +1 -0
- package/dist/arp/interceptors/filesystem.d.ts +33 -0
- package/dist/arp/interceptors/filesystem.d.ts.map +1 -0
- package/dist/arp/interceptors/filesystem.js +199 -0
- package/dist/arp/interceptors/filesystem.js.map +1 -0
- package/dist/arp/interceptors/mcp-protocol.d.ts +25 -0
- package/dist/arp/interceptors/mcp-protocol.d.ts.map +1 -0
- package/dist/arp/interceptors/mcp-protocol.js +126 -0
- package/dist/arp/interceptors/mcp-protocol.js.map +1 -0
- package/dist/arp/interceptors/network.d.ts +26 -0
- package/dist/arp/interceptors/network.d.ts.map +1 -0
- package/dist/arp/interceptors/network.js +146 -0
- package/dist/arp/interceptors/network.js.map +1 -0
- package/dist/arp/interceptors/process.d.ts +26 -0
- package/dist/arp/interceptors/process.d.ts.map +1 -0
- package/dist/arp/interceptors/process.js +157 -0
- package/dist/arp/interceptors/process.js.map +1 -0
- package/dist/arp/interceptors/prompt.d.ts +29 -0
- package/dist/arp/interceptors/prompt.d.ts.map +1 -0
- package/dist/arp/interceptors/prompt.js +82 -0
- package/dist/arp/interceptors/prompt.js.map +1 -0
- package/dist/arp/license/index.d.ts +59 -0
- package/dist/arp/license/index.d.ts.map +1 -0
- package/dist/arp/license/index.js +78 -0
- package/dist/arp/license/index.js.map +1 -0
- package/dist/arp/monitors/filesystem.d.ts +21 -0
- package/dist/arp/monitors/filesystem.d.ts.map +1 -0
- package/dist/arp/monitors/filesystem.js +141 -0
- package/dist/arp/monitors/filesystem.js.map +1 -0
- package/dist/arp/monitors/network.d.ts +32 -0
- package/dist/arp/monitors/network.d.ts.map +1 -0
- package/dist/arp/monitors/network.js +301 -0
- package/dist/arp/monitors/network.js.map +1 -0
- package/dist/arp/monitors/process.d.ts +24 -0
- package/dist/arp/monitors/process.d.ts.map +1 -0
- package/dist/arp/monitors/process.js +205 -0
- package/dist/arp/monitors/process.js.map +1 -0
- package/dist/arp/patterns/ai-threats.d.ts +48 -0
- package/dist/arp/patterns/ai-threats.d.ts.map +1 -0
- package/dist/arp/patterns/ai-threats.js +215 -0
- package/dist/arp/patterns/ai-threats.js.map +1 -0
- package/dist/arp/proxy/forward.d.ts +23 -0
- package/dist/arp/proxy/forward.d.ts.map +1 -0
- package/dist/arp/proxy/forward.js +152 -0
- package/dist/arp/proxy/forward.js.map +1 -0
- package/dist/arp/proxy/server.d.ts +45 -0
- package/dist/arp/proxy/server.d.ts.map +1 -0
- package/dist/arp/proxy/server.js +331 -0
- package/dist/arp/proxy/server.js.map +1 -0
- package/dist/arp/reporting/local-log.d.ts +22 -0
- package/dist/arp/reporting/local-log.d.ts.map +1 -0
- package/dist/arp/reporting/local-log.js +116 -0
- package/dist/arp/reporting/local-log.js.map +1 -0
- package/dist/arp/types.d.ts +230 -0
- package/dist/arp/types.d.ts.map +1 -0
- package/dist/arp/types.js +4 -0
- package/dist/arp/types.js.map +1 -0
- package/dist/attack/custom-payloads.d.ts +11 -0
- package/dist/attack/custom-payloads.d.ts.map +1 -0
- package/dist/attack/custom-payloads.js +108 -0
- package/dist/attack/custom-payloads.js.map +1 -0
- package/dist/attack/fail-policy.d.ts +16 -0
- package/dist/attack/fail-policy.d.ts.map +1 -0
- package/dist/attack/fail-policy.js +36 -0
- package/dist/attack/fail-policy.js.map +1 -0
- package/dist/attack/index.d.ts +12 -0
- package/dist/attack/index.d.ts.map +1 -0
- package/dist/attack/index.js +30 -0
- package/dist/attack/index.js.map +1 -0
- package/dist/attack/payloads/a2a-attacks.d.ts +12 -0
- package/dist/attack/payloads/a2a-attacks.d.ts.map +1 -0
- package/dist/attack/payloads/a2a-attacks.js +221 -0
- package/dist/attack/payloads/a2a-attacks.js.map +1 -0
- package/dist/attack/payloads/capability-abuse.d.ts +8 -0
- package/dist/attack/payloads/capability-abuse.d.ts.map +1 -0
- package/dist/attack/payloads/capability-abuse.js +222 -0
- package/dist/attack/payloads/capability-abuse.js.map +1 -0
- package/dist/attack/payloads/context-manipulation.d.ts +8 -0
- package/dist/attack/payloads/context-manipulation.d.ts.map +1 -0
- package/dist/attack/payloads/context-manipulation.js +217 -0
- package/dist/attack/payloads/context-manipulation.js.map +1 -0
- package/dist/attack/payloads/data-exfiltration.d.ts +8 -0
- package/dist/attack/payloads/data-exfiltration.d.ts.map +1 -0
- package/dist/attack/payloads/data-exfiltration.js +249 -0
- package/dist/attack/payloads/data-exfiltration.js.map +1 -0
- package/dist/attack/payloads/index.d.ts +29 -0
- package/dist/attack/payloads/index.d.ts.map +1 -0
- package/dist/attack/payloads/index.js +76 -0
- package/dist/attack/payloads/index.js.map +1 -0
- package/dist/attack/payloads/jailbreak.d.ts +8 -0
- package/dist/attack/payloads/jailbreak.d.ts.map +1 -0
- package/dist/attack/payloads/jailbreak.js +265 -0
- package/dist/attack/payloads/jailbreak.js.map +1 -0
- package/dist/attack/payloads/mcp-exploitation.d.ts +12 -0
- package/dist/attack/payloads/mcp-exploitation.d.ts.map +1 -0
- package/dist/attack/payloads/mcp-exploitation.js +221 -0
- package/dist/attack/payloads/mcp-exploitation.js.map +1 -0
- package/dist/attack/payloads/prompt-injection.d.ts +8 -0
- package/dist/attack/payloads/prompt-injection.d.ts.map +1 -0
- package/dist/attack/payloads/prompt-injection.js +262 -0
- package/dist/attack/payloads/prompt-injection.js.map +1 -0
- package/dist/attack/scanner.d.ts +84 -0
- package/dist/attack/scanner.d.ts.map +1 -0
- package/dist/attack/scanner.js +509 -0
- package/dist/attack/scanner.js.map +1 -0
- package/dist/attack/types.d.ts +153 -0
- package/dist/attack/types.d.ts.map +1 -0
- package/dist/attack/types.js +46 -0
- package/dist/attack/types.js.map +1 -0
- package/dist/benchmarks/index.d.ts +16 -0
- package/dist/benchmarks/index.d.ts.map +1 -0
- package/dist/benchmarks/index.js +27 -0
- package/dist/benchmarks/index.js.map +1 -0
- package/dist/benchmarks/oasb-1.d.ts +112 -0
- package/dist/benchmarks/oasb-1.d.ts.map +1 -0
- package/dist/benchmarks/oasb-1.js +1124 -0
- package/dist/benchmarks/oasb-1.js.map +1 -0
- package/dist/checker/check-skill.d.ts +48 -0
- package/dist/checker/check-skill.d.ts.map +1 -0
- package/dist/checker/check-skill.js +105 -0
- package/dist/checker/check-skill.js.map +1 -0
- package/dist/checker/index.d.ts +12 -0
- package/dist/checker/index.d.ts.map +1 -0
- package/dist/checker/index.js +16 -0
- package/dist/checker/index.js.map +1 -0
- package/dist/checker/permission-analyzer.d.ts +12 -0
- package/dist/checker/permission-analyzer.d.ts.map +1 -0
- package/dist/checker/permission-analyzer.js +84 -0
- package/dist/checker/permission-analyzer.js.map +1 -0
- package/dist/checker/publisher-verifier.d.ts +34 -0
- package/dist/checker/publisher-verifier.d.ts.map +1 -0
- package/dist/checker/publisher-verifier.js +121 -0
- package/dist/checker/publisher-verifier.js.map +1 -0
- package/dist/checker/skill-identifier.d.ts +14 -0
- package/dist/checker/skill-identifier.d.ts.map +1 -0
- package/dist/checker/skill-identifier.js +55 -0
- package/dist/checker/skill-identifier.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3534 -0
- package/dist/cli.js.map +1 -0
- package/dist/hardening/index.d.ts +7 -0
- package/dist/hardening/index.d.ts.map +1 -0
- package/dist/hardening/index.js +9 -0
- package/dist/hardening/index.js.map +1 -0
- package/dist/hardening/scanner.d.ts +147 -0
- package/dist/hardening/scanner.d.ts.map +1 -0
- package/dist/hardening/scanner.js +5445 -0
- package/dist/hardening/scanner.js.map +1 -0
- package/dist/hardening/security-check.d.ts +85 -0
- package/dist/hardening/security-check.d.ts.map +1 -0
- package/dist/hardening/security-check.js +6 -0
- package/dist/hardening/security-check.js.map +1 -0
- package/dist/index.d.ts +38 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -3525
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +10 -10
- package/dist/mcp-server.js.map +1 -1
- package/dist/oasb/config/dvaa-targets.d.ts +13 -0
- package/dist/oasb/config/dvaa-targets.d.ts.map +1 -0
- package/dist/oasb/config/dvaa-targets.js +89 -0
- package/dist/oasb/config/dvaa-targets.js.map +1 -0
- package/dist/oasb/harness/arp-wrapper.d.ts +29 -0
- package/dist/oasb/harness/arp-wrapper.d.ts.map +1 -0
- package/dist/oasb/harness/arp-wrapper.js +134 -0
- package/dist/oasb/harness/arp-wrapper.js.map +1 -0
- package/dist/oasb/harness/dvaa-client.d.ts +46 -0
- package/dist/oasb/harness/dvaa-client.d.ts.map +1 -0
- package/dist/oasb/harness/dvaa-client.js +98 -0
- package/dist/oasb/harness/dvaa-client.js.map +1 -0
- package/dist/oasb/harness/dvaa-manager.d.ts +17 -0
- package/dist/oasb/harness/dvaa-manager.d.ts.map +1 -0
- package/dist/oasb/harness/dvaa-manager.js +132 -0
- package/dist/oasb/harness/dvaa-manager.js.map +1 -0
- package/dist/oasb/harness/event-collector.d.ts +33 -0
- package/dist/oasb/harness/event-collector.d.ts.map +1 -0
- package/dist/oasb/harness/event-collector.js +86 -0
- package/dist/oasb/harness/event-collector.js.map +1 -0
- package/dist/oasb/harness/metrics.d.ts +14 -0
- package/dist/oasb/harness/metrics.d.ts.map +1 -0
- package/dist/oasb/harness/metrics.js +56 -0
- package/dist/oasb/harness/metrics.js.map +1 -0
- package/dist/oasb/harness/mock-llm-adapter.d.ts +34 -0
- package/dist/oasb/harness/mock-llm-adapter.d.ts.map +1 -0
- package/dist/oasb/harness/mock-llm-adapter.js +69 -0
- package/dist/oasb/harness/mock-llm-adapter.js.map +1 -0
- package/dist/oasb/harness/types.d.ts +74 -0
- package/dist/oasb/harness/types.d.ts.map +1 -0
- package/dist/oasb/harness/types.js +3 -0
- package/dist/oasb/harness/types.js.map +1 -0
- package/dist/plugins/core.d.ts +109 -0
- package/dist/plugins/core.d.ts.map +1 -0
- package/dist/plugins/core.js +30 -0
- package/dist/plugins/core.js.map +1 -0
- package/dist/plugins/credvault.d.ts +22 -0
- package/dist/plugins/credvault.d.ts.map +1 -0
- package/dist/plugins/credvault.js +374 -0
- package/dist/plugins/credvault.js.map +1 -0
- package/dist/plugins/signcrypt.d.ts +27 -0
- package/dist/plugins/signcrypt.d.ts.map +1 -0
- package/dist/plugins/signcrypt.js +317 -0
- package/dist/plugins/signcrypt.js.map +1 -0
- package/dist/plugins/skillguard.d.ts +25 -0
- package/dist/plugins/skillguard.d.ts.map +1 -0
- package/dist/plugins/skillguard.js +346 -0
- package/dist/plugins/skillguard.js.map +1 -0
- package/dist/registry/client.d.ts +125 -0
- package/dist/registry/client.d.ts.map +1 -0
- package/dist/registry/client.js +308 -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 +10 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/scanner/external-scanner.d.ts +13 -0
- package/dist/scanner/external-scanner.d.ts.map +1 -0
- package/dist/scanner/external-scanner.js +299 -0
- package/dist/scanner/external-scanner.js.map +1 -0
- package/dist/scanner/index.d.ts +6 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +9 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/types.d.ts +32 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +6 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/semantic/deep-scan.d.ts +13 -0
- package/dist/semantic/deep-scan.d.ts.map +1 -0
- package/dist/semantic/deep-scan.js +63 -0
- package/dist/semantic/deep-scan.js.map +1 -0
- package/dist/semantic/index.d.ts +17 -0
- package/dist/semantic/index.d.ts.map +1 -0
- package/dist/semantic/index.js +39 -0
- package/dist/semantic/index.js.map +1 -0
- package/dist/semantic/integration/cost-estimator.d.ts +17 -0
- package/dist/semantic/integration/cost-estimator.d.ts.map +1 -0
- package/dist/semantic/integration/cost-estimator.js +54 -0
- package/dist/semantic/integration/cost-estimator.js.map +1 -0
- package/dist/semantic/integration/finding-adapter.d.ts +34 -0
- package/dist/semantic/integration/finding-adapter.d.ts.map +1 -0
- package/dist/semantic/integration/finding-adapter.js +41 -0
- package/dist/semantic/integration/finding-adapter.js.map +1 -0
- package/dist/semantic/integration/oasb-upgrader.d.ts +20 -0
- package/dist/semantic/integration/oasb-upgrader.d.ts.map +1 -0
- package/dist/semantic/integration/oasb-upgrader.js +47 -0
- package/dist/semantic/integration/oasb-upgrader.js.map +1 -0
- package/dist/semantic/llm/budget.d.ts +50 -0
- package/dist/semantic/llm/budget.d.ts.map +1 -0
- package/dist/semantic/llm/budget.js +139 -0
- package/dist/semantic/llm/budget.js.map +1 -0
- package/dist/semantic/llm/cache.d.ts +36 -0
- package/dist/semantic/llm/cache.d.ts.map +1 -0
- package/dist/semantic/llm/cache.js +103 -0
- package/dist/semantic/llm/cache.js.map +1 -0
- package/dist/semantic/llm/client.d.ts +49 -0
- package/dist/semantic/llm/client.d.ts.map +1 -0
- package/dist/semantic/llm/client.js +64 -0
- package/dist/semantic/llm/client.js.map +1 -0
- package/dist/semantic/llm/index.d.ts +33 -0
- package/dist/semantic/llm/index.d.ts.map +1 -0
- package/dist/semantic/llm/index.js +129 -0
- package/dist/semantic/llm/index.js.map +1 -0
- package/dist/semantic/llm/prompts.d.ts +30 -0
- package/dist/semantic/llm/prompts.d.ts.map +1 -0
- package/dist/semantic/llm/prompts.js +120 -0
- package/dist/semantic/llm/prompts.js.map +1 -0
- package/dist/semantic/structural/credential-context.d.ts +14 -0
- package/dist/semantic/structural/credential-context.d.ts.map +1 -0
- package/dist/semantic/structural/credential-context.js +295 -0
- package/dist/semantic/structural/credential-context.js.map +1 -0
- package/dist/semantic/structural/index.d.ts +28 -0
- package/dist/semantic/structural/index.d.ts.map +1 -0
- package/dist/semantic/structural/index.js +138 -0
- package/dist/semantic/structural/index.js.map +1 -0
- package/dist/semantic/structural/instruction.d.ts +19 -0
- package/dist/semantic/structural/instruction.d.ts.map +1 -0
- package/dist/semantic/structural/instruction.js +167 -0
- package/dist/semantic/structural/instruction.js.map +1 -0
- package/dist/semantic/structural/mcp-config.d.ts +22 -0
- package/dist/semantic/structural/mcp-config.d.ts.map +1 -0
- package/dist/semantic/structural/mcp-config.js +294 -0
- package/dist/semantic/structural/mcp-config.js.map +1 -0
- package/dist/semantic/structural/permission-model.d.ts +16 -0
- package/dist/semantic/structural/permission-model.d.ts.map +1 -0
- package/dist/semantic/structural/permission-model.js +121 -0
- package/dist/semantic/structural/permission-model.js.map +1 -0
- package/dist/semantic/types.d.ts +122 -0
- package/dist/semantic/types.d.ts.map +1 -0
- package/dist/semantic/types.js +10 -0
- package/dist/semantic/types.js.map +1 -0
- package/package.json +25 -14
|
@@ -0,0 +1,308 @@
|
|
|
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
|
+
exports.buildCommunityReport = buildCommunityReport;
|
|
13
|
+
exports.buildCommunityAttackReport = buildCommunityAttackReport;
|
|
14
|
+
class RegistryClient {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Post scan results to registry callback endpoint.
|
|
20
|
+
*/
|
|
21
|
+
async reportScanResult(payload) {
|
|
22
|
+
const url = `${this.config.registryUrl}/internal/scan-result`;
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
28
|
+
'User-Agent': 'HackMyAgent-CLI',
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify(payload),
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
const body = await response.text().catch(() => '');
|
|
34
|
+
throw new Error(`Registry report failed (${response.status}): ${body}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Request a short-lived scan token for community scan submission.
|
|
39
|
+
* Returns the token response on success, or null on failure (never throws).
|
|
40
|
+
*/
|
|
41
|
+
async requestScanToken(packageName, options) {
|
|
42
|
+
const url = `${this.config.registryUrl}/api/v1/registry/community/request-scan-token`;
|
|
43
|
+
try {
|
|
44
|
+
const response = await fetch(url, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
'User-Agent': 'HackMyAgent-CLI',
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
packageName,
|
|
52
|
+
packageType: options?.packageType,
|
|
53
|
+
version: options?.version,
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
if (response.status === 404) {
|
|
57
|
+
console.error(`Registry: package "${packageName}" not found in registry`);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (response.status === 429) {
|
|
61
|
+
console.error('Registry: rate limited — try again later');
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
const body = await response.text().catch(() => '');
|
|
66
|
+
console.error(`Registry: scan token request failed (${response.status}): ${body}`);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return await response.json();
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
console.error('Registry: scan token request failed (network error)');
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Post community scan results with optional scan token.
|
|
78
|
+
* Returns { status: 'accepted' | 'unknown_package' | 'failed' }.
|
|
79
|
+
* Never throws — registry errors are non-fatal for the user's scan.
|
|
80
|
+
*/
|
|
81
|
+
async reportCommunityResult(payload, scanToken) {
|
|
82
|
+
const url = `${this.config.registryUrl}/api/v1/registry/community/scan-result`;
|
|
83
|
+
const body = JSON.stringify(payload);
|
|
84
|
+
const headers = {
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'User-Agent': 'HackMyAgent-CLI',
|
|
87
|
+
};
|
|
88
|
+
if (scanToken) {
|
|
89
|
+
headers['X-Scan-Token'] = scanToken;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const response = await fetch(url, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers,
|
|
95
|
+
body,
|
|
96
|
+
});
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
const errBody = await response.json().catch(() => ({}));
|
|
99
|
+
return {
|
|
100
|
+
status: 'failed',
|
|
101
|
+
message: errBody.message || `HTTP ${response.status}`,
|
|
102
|
+
code: errBody.code,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return await response.json();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return { status: 'failed', message: 'Network error' };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Look up package info from registry.
|
|
113
|
+
*/
|
|
114
|
+
async getPackage(publisherName, packageType, name) {
|
|
115
|
+
const url = `${this.config.registryUrl}/api/v1/registry/${packageType}/${name}?publisher=${publisherName}`;
|
|
116
|
+
const response = await fetch(url, {
|
|
117
|
+
headers: {
|
|
118
|
+
'User-Agent': 'HackMyAgent-CLI',
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
if (response.status === 404) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
throw new Error(`Registry lookup failed (${response.status})`);
|
|
126
|
+
}
|
|
127
|
+
return response.json();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.RegistryClient = RegistryClient;
|
|
131
|
+
/**
|
|
132
|
+
* Build a ScanReportPayload from HMA hardening scan results.
|
|
133
|
+
*/
|
|
134
|
+
function buildScanReport(versionId, findings) {
|
|
135
|
+
const failed = findings.filter(f => !f.passed && !f.fixed);
|
|
136
|
+
const counts = countBySeverity(failed);
|
|
137
|
+
const status = deriveStatus(counts);
|
|
138
|
+
// Map failed findings to vulnerability format
|
|
139
|
+
const vulnerabilities = failed.map(f => ({
|
|
140
|
+
id: f.checkId,
|
|
141
|
+
severity: f.severity,
|
|
142
|
+
title: f.name,
|
|
143
|
+
description: f.description,
|
|
144
|
+
}));
|
|
145
|
+
// Extract observed capabilities from capability-related checks
|
|
146
|
+
const observedCapabilities = [];
|
|
147
|
+
for (const f of findings) {
|
|
148
|
+
if (f.checkId.startsWith('FS-') && !f.passed)
|
|
149
|
+
observedCapabilities.push('filesystem');
|
|
150
|
+
if (f.checkId.startsWith('NET-') && !f.passed)
|
|
151
|
+
observedCapabilities.push('network');
|
|
152
|
+
if (f.checkId.startsWith('SHELL-') && !f.passed)
|
|
153
|
+
observedCapabilities.push('shell_exec');
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
versionId,
|
|
157
|
+
scanId: `hma-${Date.now()}`,
|
|
158
|
+
status,
|
|
159
|
+
completedAt: new Date().toISOString(),
|
|
160
|
+
vulnerabilities,
|
|
161
|
+
criticalCount: counts.critical,
|
|
162
|
+
highCount: counts.high,
|
|
163
|
+
mediumCount: counts.medium,
|
|
164
|
+
lowCount: counts.low,
|
|
165
|
+
observedCapabilities: [...new Set(observedCapabilities)],
|
|
166
|
+
observedExternalApis: [],
|
|
167
|
+
capabilityMismatch: false,
|
|
168
|
+
behavioralFindings: [],
|
|
169
|
+
behavioralScore: 0,
|
|
170
|
+
rawReport: {
|
|
171
|
+
generator: 'hackmyagent',
|
|
172
|
+
totalFindings: findings.length,
|
|
173
|
+
failedFindings: failed.length,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Build a ScanReportPayload from HMA attack results.
|
|
179
|
+
*/
|
|
180
|
+
function buildAttackReport(versionId, report) {
|
|
181
|
+
const vulnerabilities = report.results
|
|
182
|
+
.filter(r => r.success)
|
|
183
|
+
.map(r => ({
|
|
184
|
+
id: r.payload.id,
|
|
185
|
+
severity: r.payload.severity,
|
|
186
|
+
title: `${r.payload.category}: ${r.payload.id}`,
|
|
187
|
+
description: r.response?.substring(0, 500) || 'Attack succeeded',
|
|
188
|
+
}));
|
|
189
|
+
const counts = {
|
|
190
|
+
critical: vulnerabilities.filter(v => v.severity === 'critical').length,
|
|
191
|
+
high: vulnerabilities.filter(v => v.severity === 'high').length,
|
|
192
|
+
medium: vulnerabilities.filter(v => v.severity === 'medium').length,
|
|
193
|
+
low: vulnerabilities.filter(v => v.severity === 'low').length,
|
|
194
|
+
};
|
|
195
|
+
const status = deriveStatus(counts);
|
|
196
|
+
return {
|
|
197
|
+
versionId,
|
|
198
|
+
scanId: `hma-attack-${Date.now()}`,
|
|
199
|
+
status,
|
|
200
|
+
completedAt: new Date().toISOString(),
|
|
201
|
+
vulnerabilities,
|
|
202
|
+
criticalCount: counts.critical,
|
|
203
|
+
highCount: counts.high,
|
|
204
|
+
mediumCount: counts.medium,
|
|
205
|
+
lowCount: counts.low,
|
|
206
|
+
observedCapabilities: [],
|
|
207
|
+
observedExternalApis: [],
|
|
208
|
+
capabilityMismatch: false,
|
|
209
|
+
behavioralFindings: [],
|
|
210
|
+
behavioralScore: 0,
|
|
211
|
+
rawReport: {
|
|
212
|
+
generator: 'hackmyagent-attack',
|
|
213
|
+
target: report.target,
|
|
214
|
+
riskRating: report.riskRating,
|
|
215
|
+
totalPayloads: report.summary.total,
|
|
216
|
+
successfulAttacks: report.summary.successful,
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Build a CommunityScanPayload from HMA hardening scan results.
|
|
222
|
+
* Used for auto-publishing to the community endpoint (no version ID needed).
|
|
223
|
+
*/
|
|
224
|
+
function buildCommunityReport(packageName, findings, options) {
|
|
225
|
+
const failed = findings.filter(f => !f.passed && !f.fixed);
|
|
226
|
+
const counts = countBySeverity(failed);
|
|
227
|
+
const status = deriveStatus(counts);
|
|
228
|
+
const vulnerabilities = failed.map(f => ({
|
|
229
|
+
id: f.checkId,
|
|
230
|
+
severity: f.severity,
|
|
231
|
+
title: f.name,
|
|
232
|
+
description: f.description,
|
|
233
|
+
}));
|
|
234
|
+
return {
|
|
235
|
+
packageName,
|
|
236
|
+
packageType: options?.packageType,
|
|
237
|
+
version: options?.version,
|
|
238
|
+
scanId: `hma-community-${Date.now()}`,
|
|
239
|
+
status,
|
|
240
|
+
completedAt: new Date().toISOString(),
|
|
241
|
+
vulnerabilities,
|
|
242
|
+
criticalCount: counts.critical,
|
|
243
|
+
highCount: counts.high,
|
|
244
|
+
mediumCount: counts.medium,
|
|
245
|
+
lowCount: counts.low,
|
|
246
|
+
rawReport: {
|
|
247
|
+
generator: 'hackmyagent',
|
|
248
|
+
totalFindings: findings.length,
|
|
249
|
+
failedFindings: failed.length,
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Build a CommunityScanPayload from HMA attack results.
|
|
255
|
+
*/
|
|
256
|
+
function buildCommunityAttackReport(packageName, report, options) {
|
|
257
|
+
const vulnerabilities = report.results
|
|
258
|
+
.filter(r => r.success)
|
|
259
|
+
.map(r => ({
|
|
260
|
+
id: r.payload.id,
|
|
261
|
+
severity: r.payload.severity,
|
|
262
|
+
title: `${r.payload.category}: ${r.payload.id}`,
|
|
263
|
+
description: r.response?.substring(0, 500) || 'Attack succeeded',
|
|
264
|
+
}));
|
|
265
|
+
const counts = {
|
|
266
|
+
critical: vulnerabilities.filter(v => v.severity === 'critical').length,
|
|
267
|
+
high: vulnerabilities.filter(v => v.severity === 'high').length,
|
|
268
|
+
medium: vulnerabilities.filter(v => v.severity === 'medium').length,
|
|
269
|
+
low: vulnerabilities.filter(v => v.severity === 'low').length,
|
|
270
|
+
};
|
|
271
|
+
const status = deriveStatus(counts);
|
|
272
|
+
return {
|
|
273
|
+
packageName,
|
|
274
|
+
packageType: options?.packageType,
|
|
275
|
+
version: options?.version,
|
|
276
|
+
scanId: `hma-attack-community-${Date.now()}`,
|
|
277
|
+
status,
|
|
278
|
+
completedAt: new Date().toISOString(),
|
|
279
|
+
vulnerabilities,
|
|
280
|
+
criticalCount: counts.critical,
|
|
281
|
+
highCount: counts.high,
|
|
282
|
+
mediumCount: counts.medium,
|
|
283
|
+
lowCount: counts.low,
|
|
284
|
+
rawReport: {
|
|
285
|
+
generator: 'hackmyagent-attack',
|
|
286
|
+
target: report.target,
|
|
287
|
+
riskRating: report.riskRating,
|
|
288
|
+
totalPayloads: report.summary.total,
|
|
289
|
+
successfulAttacks: report.summary.successful,
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function countBySeverity(findings) {
|
|
294
|
+
return {
|
|
295
|
+
critical: findings.filter(f => f.severity === 'critical').length,
|
|
296
|
+
high: findings.filter(f => f.severity === 'high').length,
|
|
297
|
+
medium: findings.filter(f => f.severity === 'medium').length,
|
|
298
|
+
low: findings.filter(f => f.severity === 'low').length,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function deriveStatus(counts) {
|
|
302
|
+
if (counts.critical > 0 || counts.high > 0)
|
|
303
|
+
return 'failed';
|
|
304
|
+
if (counts.medium > 0 || counts.low > 0)
|
|
305
|
+
return 'warnings';
|
|
306
|
+
return 'passed';
|
|
307
|
+
}
|
|
308
|
+
//# 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,3 @@
|
|
|
1
|
+
export { RegistryClient, buildScanReport, buildAttackReport, buildCommunityReport, buildCommunityAttackReport, } from './client';
|
|
2
|
+
export type { RegistryConfig, RegistryPackage, ScanReportPayload, CommunityScanPayload, } from './client';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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,EACjB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCommunityAttackReport = exports.buildCommunityReport = 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
|
+
Object.defineProperty(exports, "buildCommunityReport", { enumerable: true, get: function () { return client_1.buildCommunityReport; } });
|
|
9
|
+
Object.defineProperty(exports, "buildCommunityAttackReport", { enumerable: true, get: function () { return client_1.buildCommunityAttackReport; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":";;;AAAA,mCAMkB;AALhB,wGAAA,cAAc,OAAA;AACd,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,8GAAA,oBAAoB,OAAA;AACpB,oHAAA,0BAA0B,OAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Scanner
|
|
3
|
+
* Scans remote targets for exposed MCP endpoints, configs, and credentials
|
|
4
|
+
*/
|
|
5
|
+
import type { ExternalScanResult, ScannerOptions } from './types';
|
|
6
|
+
export declare class ExternalScanner {
|
|
7
|
+
scan(target: string, options?: ScannerOptions): Promise<ExternalScanResult>;
|
|
8
|
+
private scanPorts;
|
|
9
|
+
private isPortOpen;
|
|
10
|
+
private checkPort;
|
|
11
|
+
private httpProbe;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=external-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/external-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAmB,cAAc,EAAmB,MAAM,SAAS,CAAC;AAoDpG,qBAAa,eAAe;IACpB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC;YA0CnE,SAAS;IAmBvB,OAAO,CAAC,UAAU;YAyBJ,SAAS;IAuHvB,OAAO,CAAC,SAAS;CA8ClB"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* External Scanner
|
|
4
|
+
* Scans remote targets for exposed MCP endpoints, configs, and credentials
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.ExternalScanner = void 0;
|
|
41
|
+
const net = __importStar(require("net"));
|
|
42
|
+
const http = __importStar(require("http"));
|
|
43
|
+
const https = __importStar(require("https"));
|
|
44
|
+
// Default ports to scan
|
|
45
|
+
const DEFAULT_PORTS = [80, 443, 3000, 3001, 4000, 5000, 8000, 8080, 8888, 18789, 18790];
|
|
46
|
+
// Config file paths to check
|
|
47
|
+
const CONFIG_PATHS = [
|
|
48
|
+
'/.claude/settings.json',
|
|
49
|
+
'/mcp.json',
|
|
50
|
+
'/.cursor/mcp.json',
|
|
51
|
+
'/.vscode/mcp.json',
|
|
52
|
+
'/config.json',
|
|
53
|
+
'/.env',
|
|
54
|
+
];
|
|
55
|
+
// MCP endpoint paths to check
|
|
56
|
+
const MCP_SSE_PATHS = ['/sse', '/events', '/mcp/sse', '/mcp/events'];
|
|
57
|
+
const MCP_TOOLS_PATHS = ['/tools', '/list', '/mcp/tools', '/mcp/list'];
|
|
58
|
+
// CLAUDE.md paths
|
|
59
|
+
const CLAUDE_MD_PATHS = ['/CLAUDE.md', '/.claude/CLAUDE.md'];
|
|
60
|
+
// API key patterns
|
|
61
|
+
const API_KEY_PATTERNS = [
|
|
62
|
+
{ name: 'Anthropic', pattern: /sk-ant-api\d{2}-[a-zA-Z0-9_-]{6,}/ },
|
|
63
|
+
{ name: 'OpenAI', pattern: /sk-proj-[a-zA-Z0-9]{6,}/ },
|
|
64
|
+
{ name: 'OpenAI', pattern: /sk-[a-zA-Z0-9]{20,}/ },
|
|
65
|
+
{ name: 'AWS', pattern: /AKIA[0-9A-Z]{16}/ },
|
|
66
|
+
{ name: 'GitHub', pattern: /ghp_[a-zA-Z0-9]{36}/ },
|
|
67
|
+
{ name: 'GitHub', pattern: /github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59}/ },
|
|
68
|
+
];
|
|
69
|
+
// Severity weights for scoring
|
|
70
|
+
const SEVERITY_WEIGHTS = {
|
|
71
|
+
critical: 25,
|
|
72
|
+
high: 15,
|
|
73
|
+
medium: 10,
|
|
74
|
+
low: 5,
|
|
75
|
+
};
|
|
76
|
+
function generateId() {
|
|
77
|
+
return Math.random().toString(36).substring(2, 10);
|
|
78
|
+
}
|
|
79
|
+
function calculateGrade(score) {
|
|
80
|
+
if (score >= 90)
|
|
81
|
+
return 'A';
|
|
82
|
+
if (score >= 80)
|
|
83
|
+
return 'B';
|
|
84
|
+
if (score >= 70)
|
|
85
|
+
return 'C';
|
|
86
|
+
if (score >= 60)
|
|
87
|
+
return 'D';
|
|
88
|
+
return 'F';
|
|
89
|
+
}
|
|
90
|
+
class ExternalScanner {
|
|
91
|
+
async scan(target, options) {
|
|
92
|
+
const startTime = Date.now();
|
|
93
|
+
const timeout = options?.timeout ?? 5000;
|
|
94
|
+
const ports = options?.ports ?? DEFAULT_PORTS;
|
|
95
|
+
const skipPortScan = options?.skipPortScan ?? false;
|
|
96
|
+
// Port scan
|
|
97
|
+
let openPorts = [];
|
|
98
|
+
if (!skipPortScan) {
|
|
99
|
+
openPorts = await this.scanPorts(target, ports, timeout);
|
|
100
|
+
}
|
|
101
|
+
// Run security checks on open ports
|
|
102
|
+
const findings = [];
|
|
103
|
+
for (const port of openPorts) {
|
|
104
|
+
const portFindings = await this.checkPort(target, port, timeout);
|
|
105
|
+
findings.push(...portFindings);
|
|
106
|
+
}
|
|
107
|
+
// Calculate score
|
|
108
|
+
let score = 100;
|
|
109
|
+
for (const finding of findings) {
|
|
110
|
+
score -= SEVERITY_WEIGHTS[finding.severity];
|
|
111
|
+
}
|
|
112
|
+
score = Math.max(0, score);
|
|
113
|
+
const grade = calculateGrade(score);
|
|
114
|
+
const duration = Date.now() - startTime;
|
|
115
|
+
return {
|
|
116
|
+
id: generateId(),
|
|
117
|
+
target,
|
|
118
|
+
score,
|
|
119
|
+
grade,
|
|
120
|
+
findings,
|
|
121
|
+
duration,
|
|
122
|
+
timestamp: new Date(),
|
|
123
|
+
openPorts,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async scanPorts(target, ports, timeout) {
|
|
127
|
+
const openPorts = [];
|
|
128
|
+
await Promise.all(ports.map(async (port) => {
|
|
129
|
+
const isOpen = await this.isPortOpen(target, port, timeout);
|
|
130
|
+
if (isOpen) {
|
|
131
|
+
openPorts.push(port);
|
|
132
|
+
}
|
|
133
|
+
}));
|
|
134
|
+
return openPorts.sort((a, b) => a - b);
|
|
135
|
+
}
|
|
136
|
+
isPortOpen(host, port, timeout) {
|
|
137
|
+
return new Promise((resolve) => {
|
|
138
|
+
const socket = new net.Socket();
|
|
139
|
+
socket.setTimeout(timeout);
|
|
140
|
+
socket.on('connect', () => {
|
|
141
|
+
socket.destroy();
|
|
142
|
+
resolve(true);
|
|
143
|
+
});
|
|
144
|
+
socket.on('timeout', () => {
|
|
145
|
+
socket.destroy();
|
|
146
|
+
resolve(false);
|
|
147
|
+
});
|
|
148
|
+
socket.on('error', () => {
|
|
149
|
+
socket.destroy();
|
|
150
|
+
resolve(false);
|
|
151
|
+
});
|
|
152
|
+
socket.connect(port, host);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async checkPort(target, port, timeout) {
|
|
156
|
+
const findings = [];
|
|
157
|
+
const useHttps = port === 443;
|
|
158
|
+
const baseUrl = `http${useHttps ? 's' : ''}://${target}:${port}`;
|
|
159
|
+
// Check MCP SSE endpoints
|
|
160
|
+
for (const path of MCP_SSE_PATHS) {
|
|
161
|
+
const result = await this.httpProbe(baseUrl + path, timeout);
|
|
162
|
+
if (result && result.contentType?.includes('text/event-stream')) {
|
|
163
|
+
findings.push({
|
|
164
|
+
id: generateId(),
|
|
165
|
+
checkId: 'MCP-SSE',
|
|
166
|
+
severity: 'critical',
|
|
167
|
+
title: 'MCP SSE Endpoint Exposed',
|
|
168
|
+
description: 'Server-Sent Events endpoint for MCP is publicly accessible',
|
|
169
|
+
port,
|
|
170
|
+
path,
|
|
171
|
+
evidence: `Content-Type: ${result.contentType}`,
|
|
172
|
+
impact: 'Attackers can connect to the MCP server and potentially execute commands',
|
|
173
|
+
fix: 'Restrict access with authentication or firewall rules',
|
|
174
|
+
});
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Check MCP tools endpoints
|
|
179
|
+
for (const path of MCP_TOOLS_PATHS) {
|
|
180
|
+
const result = await this.httpProbe(baseUrl + path, timeout);
|
|
181
|
+
if (result && result.status === 200 && result.body?.includes('tools')) {
|
|
182
|
+
findings.push({
|
|
183
|
+
id: generateId(),
|
|
184
|
+
checkId: 'MCP-TOOLS',
|
|
185
|
+
severity: 'critical',
|
|
186
|
+
title: 'MCP Tools Endpoint Exposed',
|
|
187
|
+
description: 'MCP tools listing is publicly accessible',
|
|
188
|
+
port,
|
|
189
|
+
path,
|
|
190
|
+
evidence: `Found tools listing at ${path}`,
|
|
191
|
+
impact: 'Attackers can enumerate available MCP tools and capabilities',
|
|
192
|
+
fix: 'Restrict access with authentication or remove from public access',
|
|
193
|
+
});
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Check config files
|
|
198
|
+
for (const path of CONFIG_PATHS) {
|
|
199
|
+
const result = await this.httpProbe(baseUrl + path, timeout);
|
|
200
|
+
if (result && result.status === 200 && result.body) {
|
|
201
|
+
// Check if it looks like JSON config
|
|
202
|
+
if (result.contentType?.includes('application/json') ||
|
|
203
|
+
result.body.trim().startsWith('{')) {
|
|
204
|
+
findings.push({
|
|
205
|
+
id: generateId(),
|
|
206
|
+
checkId: 'CONFIG-EXPOSED',
|
|
207
|
+
severity: 'critical',
|
|
208
|
+
title: 'Configuration File Exposed',
|
|
209
|
+
description: `Configuration file ${path} is publicly accessible`,
|
|
210
|
+
port,
|
|
211
|
+
path,
|
|
212
|
+
evidence: `HTTP 200 at ${path}`,
|
|
213
|
+
impact: 'Configuration files may contain sensitive settings, API keys, or server details',
|
|
214
|
+
fix: 'Remove file from public access or configure web server to deny access',
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Check CLAUDE.md
|
|
220
|
+
for (const path of CLAUDE_MD_PATHS) {
|
|
221
|
+
const result = await this.httpProbe(baseUrl + path, timeout);
|
|
222
|
+
if (result && result.status === 200 && result.body) {
|
|
223
|
+
findings.push({
|
|
224
|
+
id: generateId(),
|
|
225
|
+
checkId: 'CLAUDE-MD-EXPOSED',
|
|
226
|
+
severity: 'high',
|
|
227
|
+
title: 'CLAUDE.md System Instructions Exposed',
|
|
228
|
+
description: 'Agent system instructions file is publicly accessible',
|
|
229
|
+
port,
|
|
230
|
+
path,
|
|
231
|
+
evidence: `Found CLAUDE.md at ${path}`,
|
|
232
|
+
impact: 'System instructions reveal agent behavior, capabilities, and potential weaknesses',
|
|
233
|
+
fix: 'Remove file from public access or configure web server to deny access',
|
|
234
|
+
});
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Check root path for API keys in responses
|
|
239
|
+
const rootResult = await this.httpProbe(baseUrl + '/', timeout);
|
|
240
|
+
if (rootResult && rootResult.body) {
|
|
241
|
+
for (const { name, pattern } of API_KEY_PATTERNS) {
|
|
242
|
+
if (pattern.test(rootResult.body)) {
|
|
243
|
+
findings.push({
|
|
244
|
+
id: generateId(),
|
|
245
|
+
checkId: 'API-KEY-EXPOSED',
|
|
246
|
+
severity: 'critical',
|
|
247
|
+
title: `${name} API Key Exposed`,
|
|
248
|
+
description: `${name} API key found in HTTP response`,
|
|
249
|
+
port,
|
|
250
|
+
path: '/',
|
|
251
|
+
evidence: `Found ${name} API key pattern in response`,
|
|
252
|
+
impact: 'API keys can be used to access services, incur costs, or steal data',
|
|
253
|
+
fix: 'Remove API keys from responses and rotate compromised keys immediately',
|
|
254
|
+
});
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return findings;
|
|
260
|
+
}
|
|
261
|
+
httpProbe(url, timeout) {
|
|
262
|
+
return new Promise((resolve) => {
|
|
263
|
+
const isHttps = url.startsWith('https://');
|
|
264
|
+
const client = isHttps ? https : http;
|
|
265
|
+
const req = client.get(url, {
|
|
266
|
+
timeout,
|
|
267
|
+
headers: {
|
|
268
|
+
'User-Agent': 'HackMyAgent-Scanner/1.0',
|
|
269
|
+
'ngrok-skip-browser-warning': 'true',
|
|
270
|
+
},
|
|
271
|
+
rejectUnauthorized: false,
|
|
272
|
+
}, (res) => {
|
|
273
|
+
let body = '';
|
|
274
|
+
res.on('data', (chunk) => {
|
|
275
|
+
body += chunk;
|
|
276
|
+
// Limit body size
|
|
277
|
+
if (body.length > 10000) {
|
|
278
|
+
res.destroy();
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
res.on('end', () => {
|
|
282
|
+
resolve({
|
|
283
|
+
status: res.statusCode ?? 0,
|
|
284
|
+
contentType: res.headers['content-type'],
|
|
285
|
+
body: body.substring(0, 10000),
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
res.on('error', () => resolve(null));
|
|
289
|
+
});
|
|
290
|
+
req.on('timeout', () => {
|
|
291
|
+
req.destroy();
|
|
292
|
+
resolve(null);
|
|
293
|
+
});
|
|
294
|
+
req.on('error', () => resolve(null));
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.ExternalScanner = ExternalScanner;
|
|
299
|
+
//# sourceMappingURL=external-scanner.js.map
|