webmcp-cli 1.2.2 → 1.2.3
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/dist/analysis/form-to-tool-mapper.d.ts +61 -0
- package/dist/analysis/form-to-tool-mapper.js +360 -0
- package/dist/analysis/form-to-tool-mapper.js.map +1 -0
- package/dist/analysis/index.d.ts +84 -0
- package/dist/analysis/index.js +81 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/missing-tool-analyzer.d.ts +35 -0
- package/dist/analysis/missing-tool-analyzer.js +617 -0
- package/dist/analysis/missing-tool-analyzer.js.map +1 -0
- package/dist/audit/run-multi-page-audit.d.ts +34 -0
- package/dist/audit/run-multi-page-audit.js +233 -0
- package/dist/audit/run-multi-page-audit.js.map +1 -0
- package/dist/cli/commands/potential.d.ts +8 -0
- package/dist/cli/commands/potential.js +323 -0
- package/dist/cli/commands/potential.js.map +1 -0
- package/dist/cli/commands/report.d.ts +12 -0
- package/dist/cli/commands/report.js +89 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/index.js +35 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.d.ts +36 -0
- package/dist/config/defaults.js +33 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +22 -0
- package/dist/config/loader.js +91 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +280 -0
- package/dist/config/schema.js +42 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/types/audit.d.ts +1 -1
- package/dist/core/types/index.d.ts +1 -0
- package/dist/core/types/index.js +1 -0
- package/dist/core/types/index.js.map +1 -1
- package/dist/core/types/recon.d.ts +265 -0
- package/dist/core/types/recon.js +5 -0
- package/dist/core/types/recon.js.map +1 -0
- package/dist/core/types/rule.d.ts +1 -1
- package/dist/core/types/rule.js +7 -5
- package/dist/core/types/rule.js.map +1 -1
- package/dist/crawler/depth-crawler.d.ts +29 -0
- package/dist/crawler/depth-crawler.js +212 -0
- package/dist/crawler/depth-crawler.js.map +1 -0
- package/dist/crawler/index.d.ts +2 -0
- package/dist/crawler/index.js +3 -0
- package/dist/crawler/index.js.map +1 -0
- package/dist/crawler/link-extractor.d.ts +1 -0
- package/dist/crawler/link-extractor.js +49 -0
- package/dist/crawler/link-extractor.js.map +1 -0
- package/dist/generators/index.d.ts +10 -0
- package/dist/generators/index.js +8 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/report-html.d.ts +12 -0
- package/dist/generators/report-html.js +470 -0
- package/dist/generators/report-html.js.map +1 -0
- package/dist/generators/report-json.d.ts +95 -0
- package/dist/generators/report-json.js +144 -0
- package/dist/generators/report-json.js.map +1 -0
- package/dist/generators/report-manager.d.ts +31 -0
- package/dist/generators/report-manager.js +208 -0
- package/dist/generators/report-manager.js.map +1 -0
- package/dist/generators/tool-code-generator.d.ts +31 -0
- package/dist/generators/tool-code-generator.js +201 -0
- package/dist/generators/tool-code-generator.js.map +1 -0
- package/dist/potential/ai-recommender.d.ts +33 -0
- package/dist/potential/ai-recommender.js +414 -0
- package/dist/potential/ai-recommender.js.map +1 -0
- package/dist/potential/analyzer.d.ts +32 -0
- package/dist/potential/analyzer.js +383 -0
- package/dist/potential/analyzer.js.map +1 -0
- package/dist/potential/index.d.ts +3 -0
- package/dist/potential/index.js +4 -0
- package/dist/potential/index.js.map +1 -0
- package/dist/potential/prompts.d.ts +20 -0
- package/dist/potential/prompts.js +42 -0
- package/dist/potential/prompts.js.map +1 -0
- package/dist/potential/types.d.ts +40 -0
- package/dist/potential/types.js +2 -0
- package/dist/potential/types.js.map +1 -0
- package/dist/recon/index.d.ts +20 -0
- package/dist/recon/index.js +143 -0
- package/dist/recon/index.js.map +1 -0
- package/dist/recon/manifest.d.ts +16 -0
- package/dist/recon/manifest.js +108 -0
- package/dist/recon/manifest.js.map +1 -0
- package/dist/recon/meta-extractor.d.ts +11 -0
- package/dist/recon/meta-extractor.js +276 -0
- package/dist/recon/meta-extractor.js.map +1 -0
- package/dist/recon/robots.d.ts +16 -0
- package/dist/recon/robots.js +158 -0
- package/dist/recon/robots.js.map +1 -0
- package/dist/recon/route-discovery.d.ts +25 -0
- package/dist/recon/route-discovery.js +303 -0
- package/dist/recon/route-discovery.js.map +1 -0
- package/dist/recon/sitemap.d.ts +12 -0
- package/dist/recon/sitemap.js +177 -0
- package/dist/recon/sitemap.js.map +1 -0
- package/dist/rules/accessibility/AXE-001.d.ts +9 -0
- package/dist/rules/accessibility/AXE-001.js +109 -0
- package/dist/rules/accessibility/AXE-001.js.map +1 -0
- package/dist/rules/accessibility/AXE-002.d.ts +8 -0
- package/dist/rules/accessibility/AXE-002.js +85 -0
- package/dist/rules/accessibility/AXE-002.js.map +1 -0
- package/dist/rules/accessibility/AXE-003.d.ts +8 -0
- package/dist/rules/accessibility/AXE-003.js +94 -0
- package/dist/rules/accessibility/AXE-003.js.map +1 -0
- package/dist/rules/accessibility/AXE-004.d.ts +8 -0
- package/dist/rules/accessibility/AXE-004.js +101 -0
- package/dist/rules/accessibility/AXE-004.js.map +1 -0
- package/dist/rules/accessibility/AXE-005.d.ts +9 -0
- package/dist/rules/accessibility/AXE-005.js +89 -0
- package/dist/rules/accessibility/AXE-005.js.map +1 -0
- package/dist/rules/best-practices/BP-004.d.ts +9 -0
- package/dist/rules/best-practices/BP-004.js +96 -0
- package/dist/rules/best-practices/BP-004.js.map +1 -0
- package/dist/rules/best-practices/BP-005.d.ts +8 -0
- package/dist/rules/best-practices/BP-005.js +94 -0
- package/dist/rules/best-practices/BP-005.js.map +1 -0
- package/dist/rules/best-practices/BP-006.d.ts +8 -0
- package/dist/rules/best-practices/BP-006.js +80 -0
- package/dist/rules/best-practices/BP-006.js.map +1 -0
- package/dist/rules/best-practices/BP-007.d.ts +8 -0
- package/dist/rules/best-practices/BP-007.js +92 -0
- package/dist/rules/best-practices/BP-007.js.map +1 -0
- package/dist/rules/best-practices/BP-008.d.ts +12 -0
- package/dist/rules/best-practices/BP-008.js +86 -0
- package/dist/rules/best-practices/BP-008.js.map +1 -0
- package/dist/rules/best-practices/BP-009.d.ts +9 -0
- package/dist/rules/best-practices/BP-009.js +77 -0
- package/dist/rules/best-practices/BP-009.js.map +1 -0
- package/dist/rules/best-practices/BP-010.d.ts +8 -0
- package/dist/rules/best-practices/BP-010.js +85 -0
- package/dist/rules/best-practices/BP-010.js.map +1 -0
- package/dist/rules/coverage/COV-002.d.ts +8 -0
- package/dist/rules/coverage/COV-002.js +68 -0
- package/dist/rules/coverage/COV-002.js.map +1 -0
- package/dist/rules/coverage/COV-003.d.ts +8 -0
- package/dist/rules/coverage/COV-003.js +68 -0
- package/dist/rules/coverage/COV-003.js.map +1 -0
- package/dist/rules/coverage/COV-004.d.ts +8 -0
- package/dist/rules/coverage/COV-004.js +89 -0
- package/dist/rules/coverage/COV-004.js.map +1 -0
- package/dist/rules/coverage/COV-005.d.ts +8 -0
- package/dist/rules/coverage/COV-005.js +67 -0
- package/dist/rules/coverage/COV-005.js.map +1 -0
- package/dist/rules/coverage/COV-006.d.ts +9 -0
- package/dist/rules/coverage/COV-006.js +76 -0
- package/dist/rules/coverage/COV-006.js.map +1 -0
- package/dist/rules/coverage/COV-007.d.ts +8 -0
- package/dist/rules/coverage/COV-007.js +67 -0
- package/dist/rules/coverage/COV-007.js.map +1 -0
- package/dist/rules/coverage/COV-008.d.ts +9 -0
- package/dist/rules/coverage/COV-008.js +87 -0
- package/dist/rules/coverage/COV-008.js.map +1 -0
- package/dist/rules/coverage/COV-009.d.ts +8 -0
- package/dist/rules/coverage/COV-009.js +73 -0
- package/dist/rules/coverage/COV-009.js.map +1 -0
- package/dist/rules/coverage/COV-010.d.ts +9 -0
- package/dist/rules/coverage/COV-010.js +82 -0
- package/dist/rules/coverage/COV-010.js.map +1 -0
- package/dist/rules/description/DESC-001.d.ts +9 -0
- package/dist/rules/description/DESC-001.js +88 -0
- package/dist/rules/description/DESC-001.js.map +1 -0
- package/dist/rules/description/DESC-002.d.ts +10 -0
- package/dist/rules/description/DESC-002.js +99 -0
- package/dist/rules/description/DESC-002.js.map +1 -0
- package/dist/rules/description/DESC-006.d.ts +9 -0
- package/dist/rules/description/DESC-006.js +78 -0
- package/dist/rules/description/DESC-006.js.map +1 -0
- package/dist/rules/description/DESC-007.d.ts +9 -0
- package/dist/rules/description/DESC-007.js +70 -0
- package/dist/rules/description/DESC-007.js.map +1 -0
- package/dist/rules/description/DESC-008.d.ts +9 -0
- package/dist/rules/description/DESC-008.js +70 -0
- package/dist/rules/description/DESC-008.js.map +1 -0
- package/dist/rules/description/DESC-009.d.ts +8 -0
- package/dist/rules/description/DESC-009.js +55 -0
- package/dist/rules/description/DESC-009.js.map +1 -0
- package/dist/rules/description/DESC-010.d.ts +9 -0
- package/dist/rules/description/DESC-010.js +92 -0
- package/dist/rules/description/DESC-010.js.map +1 -0
- package/dist/rules/description/DESC-011.d.ts +9 -0
- package/dist/rules/description/DESC-011.js +81 -0
- package/dist/rules/description/DESC-011.js.map +1 -0
- package/dist/rules/description/DESC-012.d.ts +9 -0
- package/dist/rules/description/DESC-012.js +98 -0
- package/dist/rules/description/DESC-012.js.map +1 -0
- package/dist/rules/implementation/IMP-002.d.ts +9 -0
- package/dist/rules/implementation/IMP-002.js +59 -0
- package/dist/rules/implementation/IMP-002.js.map +1 -0
- package/dist/rules/implementation/IMP-006.d.ts +9 -0
- package/dist/rules/implementation/IMP-006.js +48 -0
- package/dist/rules/implementation/IMP-006.js.map +1 -0
- package/dist/rules/implementation/IMP-008.d.ts +9 -0
- package/dist/rules/implementation/IMP-008.js +46 -0
- package/dist/rules/implementation/IMP-008.js.map +1 -0
- package/dist/rules/implementation/IMP-009.d.ts +9 -0
- package/dist/rules/implementation/IMP-009.js +48 -0
- package/dist/rules/implementation/IMP-009.js.map +1 -0
- package/dist/rules/implementation/IMP-010.d.ts +9 -0
- package/dist/rules/implementation/IMP-010.js +66 -0
- package/dist/rules/implementation/IMP-010.js.map +1 -0
- package/dist/rules/implementation/IMP-011.d.ts +9 -0
- package/dist/rules/implementation/IMP-011.js +82 -0
- package/dist/rules/implementation/IMP-011.js.map +1 -0
- package/dist/rules/implementation/IMP-012.d.ts +9 -0
- package/dist/rules/implementation/IMP-012.js +88 -0
- package/dist/rules/implementation/IMP-012.js.map +1 -0
- package/dist/rules/implementation/IMP-014.d.ts +9 -0
- package/dist/rules/implementation/IMP-014.js +58 -0
- package/dist/rules/implementation/IMP-014.js.map +1 -0
- package/dist/rules/implementation/IMP-015.d.ts +9 -0
- package/dist/rules/implementation/IMP-015.js +64 -0
- package/dist/rules/implementation/IMP-015.js.map +1 -0
- package/dist/rules/implementation/IMP-016.d.ts +9 -0
- package/dist/rules/implementation/IMP-016.js +52 -0
- package/dist/rules/implementation/IMP-016.js.map +1 -0
- package/dist/rules/implementation/IMP-017.d.ts +8 -0
- package/dist/rules/implementation/IMP-017.js +51 -0
- package/dist/rules/implementation/IMP-017.js.map +1 -0
- package/dist/rules/implementation/IMP-018.d.ts +8 -0
- package/dist/rules/implementation/IMP-018.js +52 -0
- package/dist/rules/implementation/IMP-018.js.map +1 -0
- package/dist/rules/implementation/IMP-019.d.ts +8 -0
- package/dist/rules/implementation/IMP-019.js +53 -0
- package/dist/rules/implementation/IMP-019.js.map +1 -0
- package/dist/rules/implementation/IMP-020.d.ts +9 -0
- package/dist/rules/implementation/IMP-020.js +62 -0
- package/dist/rules/implementation/IMP-020.js.map +1 -0
- package/dist/rules/implementation/IMP-021.d.ts +8 -0
- package/dist/rules/implementation/IMP-021.js +64 -0
- package/dist/rules/implementation/IMP-021.js.map +1 -0
- package/dist/rules/implementation/IMP-022.d.ts +8 -0
- package/dist/rules/implementation/IMP-022.js +70 -0
- package/dist/rules/implementation/IMP-022.js.map +1 -0
- package/dist/rules/index.d.ts +73 -6
- package/dist/rules/index.js +141 -6
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/schema/SCHEMA-004.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-004.js +57 -0
- package/dist/rules/schema/SCHEMA-004.js.map +1 -0
- package/dist/rules/schema/SCHEMA-005.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-005.js +61 -0
- package/dist/rules/schema/SCHEMA-005.js.map +1 -0
- package/dist/rules/schema/SCHEMA-006.d.ts +10 -0
- package/dist/rules/schema/SCHEMA-006.js +85 -0
- package/dist/rules/schema/SCHEMA-006.js.map +1 -0
- package/dist/rules/schema/SCHEMA-007.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-007.js +73 -0
- package/dist/rules/schema/SCHEMA-007.js.map +1 -0
- package/dist/rules/schema/SCHEMA-008.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-008.js +70 -0
- package/dist/rules/schema/SCHEMA-008.js.map +1 -0
- package/dist/rules/schema/SCHEMA-009.d.ts +10 -0
- package/dist/rules/schema/SCHEMA-009.js +80 -0
- package/dist/rules/schema/SCHEMA-009.js.map +1 -0
- package/dist/rules/schema/SCHEMA-010.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-010.js +96 -0
- package/dist/rules/schema/SCHEMA-010.js.map +1 -0
- package/dist/rules/schema/SCHEMA-012.d.ts +9 -0
- package/dist/rules/schema/SCHEMA-012.js +65 -0
- package/dist/rules/schema/SCHEMA-012.js.map +1 -0
- package/dist/rules/security/SEC-002.d.ts +8 -0
- package/dist/rules/security/SEC-002.js +81 -0
- package/dist/rules/security/SEC-002.js.map +1 -0
- package/dist/rules/security/SEC-003.d.ts +8 -0
- package/dist/rules/security/SEC-003.js +85 -0
- package/dist/rules/security/SEC-003.js.map +1 -0
- package/dist/rules/security/SEC-004.d.ts +9 -0
- package/dist/rules/security/SEC-004.js +87 -0
- package/dist/rules/security/SEC-004.js.map +1 -0
- package/dist/rules/security/SEC-005.d.ts +8 -0
- package/dist/rules/security/SEC-005.js +87 -0
- package/dist/rules/security/SEC-005.js.map +1 -0
- package/dist/rules/security/SEC-006.d.ts +10 -0
- package/dist/rules/security/SEC-006.js +108 -0
- package/dist/rules/security/SEC-006.js.map +1 -0
- package/dist/rules/security/SEC-007.d.ts +9 -0
- package/dist/rules/security/SEC-007.js +108 -0
- package/dist/rules/security/SEC-007.js.map +1 -0
- package/dist/rules/security/SEC-008.d.ts +8 -0
- package/dist/rules/security/SEC-008.js +109 -0
- package/dist/rules/security/SEC-008.js.map +1 -0
- package/dist/rules/security/SEC-009.d.ts +9 -0
- package/dist/rules/security/SEC-009.js +93 -0
- package/dist/rules/security/SEC-009.js.map +1 -0
- package/dist/rules/security/SEC-010.d.ts +8 -0
- package/dist/rules/security/SEC-010.js +78 -0
- package/dist/rules/security/SEC-010.js.map +1 -0
- package/dist/rules/security/SEC-011.d.ts +8 -0
- package/dist/rules/security/SEC-011.js +93 -0
- package/dist/rules/security/SEC-011.js.map +1 -0
- package/dist/rules/security/SEC-012.d.ts +8 -0
- package/dist/rules/security/SEC-012.js +79 -0
- package/dist/rules/security/SEC-012.js.map +1 -0
- package/dist/rules/security/SEC-013.d.ts +9 -0
- package/dist/rules/security/SEC-013.js +107 -0
- package/dist/rules/security/SEC-013.js.map +1 -0
- package/dist/scoring/calculator.js +1 -0
- package/dist/scoring/calculator.js.map +1 -1
- package/dist/ui/ink/components/AIRecommendationCard.d.ts +11 -0
- package/dist/ui/ink/components/AIRecommendationCard.js +23 -0
- package/dist/ui/ink/components/AIRecommendationCard.js.map +1 -0
- package/dist/ui/ink/components/OpportunityList.d.ts +10 -0
- package/dist/ui/ink/components/OpportunityList.js +48 -0
- package/dist/ui/ink/components/OpportunityList.js.map +1 -0
- package/dist/ui/ink/components/PotentialPageCard.d.ts +13 -0
- package/dist/ui/ink/components/PotentialPageCard.js +43 -0
- package/dist/ui/ink/components/PotentialPageCard.js.map +1 -0
- package/dist/ui/ink/components/PotentialProgress.d.ts +16 -0
- package/dist/ui/ink/components/PotentialProgress.js +44 -0
- package/dist/ui/ink/components/PotentialProgress.js.map +1 -0
- package/dist/ui/ink/components/PotentialSummary.d.ts +10 -0
- package/dist/ui/ink/components/PotentialSummary.js +86 -0
- package/dist/ui/ink/components/PotentialSummary.js.map +1 -0
- package/dist/ui/ink/components/SuggestionCard.d.ts +34 -0
- package/dist/ui/ink/components/SuggestionCard.js +36 -0
- package/dist/ui/ink/components/SuggestionCard.js.map +1 -0
- package/dist/ui/ink/components/views/MultiPageCrawlView.d.ts +21 -0
- package/dist/ui/ink/components/views/MultiPageCrawlView.js +55 -0
- package/dist/ui/ink/components/views/MultiPageCrawlView.js.map +1 -0
- package/dist/ui/ink/components/views/PotentialView.d.ts +18 -0
- package/dist/ui/ink/components/views/PotentialView.js +74 -0
- package/dist/ui/ink/components/views/PotentialView.js.map +1 -0
- package/dist/ui/ink/components/views/ReconView.d.ts +22 -0
- package/dist/ui/ink/components/views/ReconView.js +30 -0
- package/dist/ui/ink/components/views/ReconView.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-003.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-003.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-004: Over-Parameterization Check
|
|
3
|
+
*
|
|
4
|
+
* Checks that tools don't request excessive personal or sensitive data.
|
|
5
|
+
* Classifies parameters by sensitivity and flags tools that collect
|
|
6
|
+
* too many sensitive fields.
|
|
7
|
+
*/
|
|
8
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
9
|
+
export declare const SEC_004: Rule;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-004: Over-Parameterization Check
|
|
3
|
+
*
|
|
4
|
+
* Checks that tools don't request excessive personal or sensitive data.
|
|
5
|
+
* Classifies parameters by sensitivity and flags tools that collect
|
|
6
|
+
* too many sensitive fields.
|
|
7
|
+
*/
|
|
8
|
+
import { createRuleResult } from '../runner.js';
|
|
9
|
+
const SENSITIVE_PARAM_PATTERNS = [
|
|
10
|
+
{ pattern: /\bssn\b|social.?security/i, level: 'high' },
|
|
11
|
+
{ pattern: /\bpassword\b|\bpasswd\b/i, level: 'high' },
|
|
12
|
+
{ pattern: /\bcredit.?card\b|\bcc.?num/i, level: 'high' },
|
|
13
|
+
{ pattern: /\bcvv\b|\bcvc\b|\bsecurity.?code/i, level: 'high' },
|
|
14
|
+
{ pattern: /\bbank.?account\b|\brouting.?number/i, level: 'high' },
|
|
15
|
+
{ pattern: /\bpin\b/i, level: 'high' },
|
|
16
|
+
{ pattern: /\bdate.?of.?birth\b|\bdob\b|\bbirthday/i, level: 'medium' },
|
|
17
|
+
{ pattern: /\bemail\b/i, level: 'medium' },
|
|
18
|
+
{ pattern: /\bphone\b|\bmobile\b|\bcell/i, level: 'medium' },
|
|
19
|
+
{ pattern: /\baddress\b|\bstreet\b|\bzip.?code\b|\bpostal/i, level: 'medium' },
|
|
20
|
+
{ pattern: /\bfull.?name\b|\bfirst.?name\b|\blast.?name\b/i, level: 'medium' },
|
|
21
|
+
{ pattern: /\bdriver.?licen/i, level: 'high' },
|
|
22
|
+
{ pattern: /\bpassport\b/i, level: 'high' },
|
|
23
|
+
{ pattern: /\btax.?id\b/i, level: 'high' },
|
|
24
|
+
];
|
|
25
|
+
const MAX_SENSITIVE_PARAMS = 3;
|
|
26
|
+
export const SEC_004 = {
|
|
27
|
+
id: 'SEC-004',
|
|
28
|
+
category: 'security',
|
|
29
|
+
name: 'Over-Parameterization Check',
|
|
30
|
+
description: 'Tools should not request excessive personal or sensitive data',
|
|
31
|
+
severity: 'warning',
|
|
32
|
+
maxScore: 8,
|
|
33
|
+
async check(context) {
|
|
34
|
+
const tools = context.tools;
|
|
35
|
+
if (tools.length === 0) {
|
|
36
|
+
return createRuleResult('SEC-004', 8, {
|
|
37
|
+
passed: true,
|
|
38
|
+
score: 8,
|
|
39
|
+
message: 'No tools detected (rule not applicable)',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const violations = [];
|
|
43
|
+
for (const tool of tools) {
|
|
44
|
+
const schema = tool.inputSchema;
|
|
45
|
+
if (!schema?.properties)
|
|
46
|
+
continue;
|
|
47
|
+
const sensitiveParams = [];
|
|
48
|
+
let highCount = 0;
|
|
49
|
+
for (const [paramName, prop] of Object.entries(schema.properties)) {
|
|
50
|
+
const textToCheck = `${paramName} ${prop.description ?? ''}`;
|
|
51
|
+
for (const { pattern, level } of SENSITIVE_PARAM_PATTERNS) {
|
|
52
|
+
if (pattern.test(textToCheck)) {
|
|
53
|
+
sensitiveParams.push(paramName);
|
|
54
|
+
if (level === 'high')
|
|
55
|
+
highCount++;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (sensitiveParams.length > MAX_SENSITIVE_PARAMS || highCount >= 2) {
|
|
61
|
+
violations.push({ name: tool.name, sensitiveParams, highCount });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (violations.length === 0) {
|
|
65
|
+
return createRuleResult('SEC-004', 8, {
|
|
66
|
+
passed: true,
|
|
67
|
+
score: 8,
|
|
68
|
+
message: 'No tools request excessive sensitive data',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const penalty = violations.length * 4;
|
|
72
|
+
const score = Math.max(0, 8 - penalty);
|
|
73
|
+
return createRuleResult('SEC-004', 8, {
|
|
74
|
+
passed: false,
|
|
75
|
+
score,
|
|
76
|
+
message: `${violations.length} tool(s) request excessive sensitive data`,
|
|
77
|
+
details: violations.map((v) => `Tool "${v.name}" collects ${v.sensitiveParams.length} sensitive params (${v.highCount} high-sensitivity): [${v.sensitiveParams.join(', ')}]`),
|
|
78
|
+
suggestions: [
|
|
79
|
+
'Minimize the amount of personal data collected per tool',
|
|
80
|
+
'Split tools that need many sensitive fields into focused sub-tools',
|
|
81
|
+
'Only request data that is strictly necessary for the tool\'s function',
|
|
82
|
+
],
|
|
83
|
+
affectedTools: violations.map((v) => v.name),
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=SEC-004.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-004.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-004.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-005: Sensitive Action Confirmation
|
|
3
|
+
*
|
|
4
|
+
* Checks that destructive or financial tools use requestUserInteraction()
|
|
5
|
+
* or requiresConfirmation to ensure human oversight.
|
|
6
|
+
*/
|
|
7
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
8
|
+
export declare const SEC_005: Rule;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-005: Sensitive Action Confirmation
|
|
3
|
+
*
|
|
4
|
+
* Checks that destructive or financial tools use requestUserInteraction()
|
|
5
|
+
* or requiresConfirmation to ensure human oversight.
|
|
6
|
+
*/
|
|
7
|
+
import { createRuleResult } from '../runner.js';
|
|
8
|
+
import { CRITICAL_DESTRUCTIVE_KEYWORDS, hasKeyword, findMatchedKeywords, } from '../utils/keywords.js';
|
|
9
|
+
const FINANCIAL_KEYWORDS = [
|
|
10
|
+
'purchase',
|
|
11
|
+
'buy',
|
|
12
|
+
'checkout',
|
|
13
|
+
'pay',
|
|
14
|
+
'transfer',
|
|
15
|
+
'withdraw',
|
|
16
|
+
'send money',
|
|
17
|
+
'subscribe',
|
|
18
|
+
'charge',
|
|
19
|
+
'refund',
|
|
20
|
+
'invoice',
|
|
21
|
+
];
|
|
22
|
+
const CONFIRMATION_PATTERNS = [
|
|
23
|
+
/requestUserInteraction/,
|
|
24
|
+
/confirm\s*\(/,
|
|
25
|
+
/requiresConfirmation/,
|
|
26
|
+
/userConfirm/i,
|
|
27
|
+
/awaitConfirmation/i,
|
|
28
|
+
];
|
|
29
|
+
export const SEC_005 = {
|
|
30
|
+
id: 'SEC-005',
|
|
31
|
+
category: 'security',
|
|
32
|
+
name: 'Sensitive Action Confirmation',
|
|
33
|
+
description: 'Destructive or financial tools must use requestUserInteraction() or requiresConfirmation',
|
|
34
|
+
severity: 'critical',
|
|
35
|
+
maxScore: 12,
|
|
36
|
+
async check(context) {
|
|
37
|
+
const tools = context.tools;
|
|
38
|
+
if (tools.length === 0) {
|
|
39
|
+
return createRuleResult('SEC-005', 12, {
|
|
40
|
+
passed: true,
|
|
41
|
+
score: 12,
|
|
42
|
+
message: 'No tools detected (rule not applicable)',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const allSensitiveKeywords = [
|
|
46
|
+
...CRITICAL_DESTRUCTIVE_KEYWORDS,
|
|
47
|
+
...FINANCIAL_KEYWORDS,
|
|
48
|
+
];
|
|
49
|
+
const violations = [];
|
|
50
|
+
for (const tool of tools) {
|
|
51
|
+
const textToSearch = `${tool.name} ${tool.description}`;
|
|
52
|
+
if (!hasKeyword(textToSearch, allSensitiveKeywords))
|
|
53
|
+
continue;
|
|
54
|
+
// Check annotation
|
|
55
|
+
const hasAnnotationConfirm = tool.annotations?.requiresConfirmation === true;
|
|
56
|
+
// Check execute source for confirmation calls
|
|
57
|
+
const src = tool.executeSource ?? '';
|
|
58
|
+
const hasCodeConfirm = CONFIRMATION_PATTERNS.some((p) => p.test(src));
|
|
59
|
+
if (!hasAnnotationConfirm && !hasCodeConfirm) {
|
|
60
|
+
const matchedKeywords = findMatchedKeywords(textToSearch, allSensitiveKeywords);
|
|
61
|
+
violations.push({ name: tool.name, keywords: matchedKeywords });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (violations.length === 0) {
|
|
65
|
+
return createRuleResult('SEC-005', 12, {
|
|
66
|
+
passed: true,
|
|
67
|
+
score: 12,
|
|
68
|
+
message: 'All sensitive tools require confirmation before execution',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const penalty = violations.length * 4;
|
|
72
|
+
const score = Math.max(0, 12 - penalty);
|
|
73
|
+
return createRuleResult('SEC-005', 12, {
|
|
74
|
+
passed: false,
|
|
75
|
+
score,
|
|
76
|
+
message: `${violations.length} sensitive tool(s) lack confirmation requirement`,
|
|
77
|
+
details: violations.map((v) => `Tool "${v.name}" performs sensitive actions [${v.keywords.join(', ')}] without confirmation`),
|
|
78
|
+
suggestions: [
|
|
79
|
+
'Add requiresConfirmation: true to annotations for destructive/financial tools',
|
|
80
|
+
'Use requestUserInteraction() in execute function before performing sensitive actions',
|
|
81
|
+
'Example: await navigator.modelContext.requestUserInteraction({ type: "confirmation" })',
|
|
82
|
+
],
|
|
83
|
+
affectedTools: violations.map((v) => v.name),
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=SEC-005.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-005.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-005.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,6BAA6B,EAC7B,UAAU,EACV,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,kBAAkB,GAAG;IACzB,UAAU;IACV,KAAK;IACL,UAAU;IACV,KAAK;IACL,UAAU;IACV,UAAU;IACV,YAAY;IACZ,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,SAAS;CACV,CAAC;AAEF,MAAM,qBAAqB,GAAG;IAC5B,wBAAwB;IACxB,cAAc;IACd,sBAAsB;IACtB,cAAc;IACd,oBAAoB;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAS;IAC3B,EAAE,EAAE,SAAS;IACb,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,+BAA+B;IACrC,WAAW,EACT,0FAA0F;IAC5F,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,EAAE;IAEZ,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;gBACrC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE;gBACT,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC;QACL,CAAC;QAED,MAAM,oBAAoB,GAAG;YAC3B,GAAG,6BAA6B;YAChC,GAAG,kBAAkB;SACtB,CAAC;QACF,MAAM,UAAU,GAA2C,EAAE,CAAC;QAE9D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAExD,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,oBAAoB,CAAC;gBAAE,SAAS;YAE9D,mBAAmB;YACnB,MAAM,oBAAoB,GACxB,IAAI,CAAC,WAAW,EAAE,oBAAoB,KAAK,IAAI,CAAC;YAElD,8CAA8C;YAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;YACrC,MAAM,cAAc,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAEtE,IAAI,CAAC,oBAAoB,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC7C,MAAM,eAAe,GAAG,mBAAmB,CACzC,YAAY,EACZ,oBAAoB,CACrB,CAAC;gBACF,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;gBACrC,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,EAAE;gBACT,OAAO,EACL,2DAA2D;aAC9D,CAAC,CAAC;QACL,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC;QAExC,OAAO,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE;YACrC,MAAM,EAAE,KAAK;YACb,KAAK;YACL,OAAO,EAAE,GAAG,UAAU,CAAC,MAAM,kDAAkD;YAC/E,OAAO,EAAE,UAAU,CAAC,GAAG,CACrB,CAAC,CAAC,EAAE,EAAE,CACJ,SAAS,CAAC,CAAC,IAAI,iCAAiC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAChG;YACD,WAAW,EAAE;gBACX,+EAA+E;gBAC/E,sFAAsF;gBACtF,wFAAwF;aACzF;YACD,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-006: Misrepresentation (Static)
|
|
3
|
+
*
|
|
4
|
+
* Checks that tool descriptions match the detectable behavior
|
|
5
|
+
* of execute functions. Flags tools where the description says one thing
|
|
6
|
+
* but the code does something different (e.g., claims "read-only"
|
|
7
|
+
* but performs writes).
|
|
8
|
+
*/
|
|
9
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
10
|
+
export declare const SEC_006: Rule;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-006: Misrepresentation (Static)
|
|
3
|
+
*
|
|
4
|
+
* Checks that tool descriptions match the detectable behavior
|
|
5
|
+
* of execute functions. Flags tools where the description says one thing
|
|
6
|
+
* but the code does something different (e.g., claims "read-only"
|
|
7
|
+
* but performs writes).
|
|
8
|
+
*/
|
|
9
|
+
import { createRuleResult } from '../runner.js';
|
|
10
|
+
import { hasKeyword, READONLY_KEYWORDS, DESTRUCTIVE_KEYWORDS } from '../utils/keywords.js';
|
|
11
|
+
const WRITE_PATTERNS = [
|
|
12
|
+
/\.remove\s*\(/,
|
|
13
|
+
/\.delete\s*\(/,
|
|
14
|
+
/fetch\s*\(.*method\s*:\s*['"](?:POST|PUT|DELETE|PATCH)/i,
|
|
15
|
+
/\.submit\s*\(/,
|
|
16
|
+
/localStorage\.setItem/,
|
|
17
|
+
/sessionStorage\.setItem/,
|
|
18
|
+
/document\.cookie\s*=/,
|
|
19
|
+
/\.set\s*\(/,
|
|
20
|
+
/\.save\s*\(/,
|
|
21
|
+
/\.update\s*\(/,
|
|
22
|
+
/\.create\s*\(/,
|
|
23
|
+
/\.push\s*\(/,
|
|
24
|
+
/\.splice\s*\(/,
|
|
25
|
+
];
|
|
26
|
+
const READ_PATTERNS = [
|
|
27
|
+
/fetch\s*\(.*method\s*:\s*['"]GET/i,
|
|
28
|
+
/\.get\s*\(/,
|
|
29
|
+
/\.find\s*\(/,
|
|
30
|
+
/\.filter\s*\(/,
|
|
31
|
+
/\.query\s*\(/,
|
|
32
|
+
/localStorage\.getItem/,
|
|
33
|
+
/sessionStorage\.getItem/,
|
|
34
|
+
/\.search\s*\(/,
|
|
35
|
+
/\.textContent\b/,
|
|
36
|
+
/\.innerText\b/,
|
|
37
|
+
];
|
|
38
|
+
export const SEC_006 = {
|
|
39
|
+
id: 'SEC-006',
|
|
40
|
+
category: 'security',
|
|
41
|
+
name: 'Misrepresentation (Static)',
|
|
42
|
+
description: 'Tool description should match detectable behavior of execute function',
|
|
43
|
+
severity: 'warning',
|
|
44
|
+
maxScore: 8,
|
|
45
|
+
async check(context) {
|
|
46
|
+
const tools = context.tools;
|
|
47
|
+
if (tools.length === 0) {
|
|
48
|
+
return createRuleResult('SEC-006', 8, {
|
|
49
|
+
passed: true,
|
|
50
|
+
score: 8,
|
|
51
|
+
message: 'No tools detected (rule not applicable)',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const toolsWithExecute = tools.filter((t) => t.executeSource && t.executeSource.length > 0);
|
|
55
|
+
if (toolsWithExecute.length === 0) {
|
|
56
|
+
return createRuleResult('SEC-006', 8, {
|
|
57
|
+
passed: true,
|
|
58
|
+
score: 8,
|
|
59
|
+
message: 'No execute functions available for analysis',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const violations = [];
|
|
63
|
+
for (const tool of toolsWithExecute) {
|
|
64
|
+
const desc = `${tool.name} ${tool.description}`;
|
|
65
|
+
const src = tool.executeSource ?? '';
|
|
66
|
+
const descLooksReadOnly = hasKeyword(desc, READONLY_KEYWORDS) &&
|
|
67
|
+
!hasKeyword(desc, DESTRUCTIVE_KEYWORDS);
|
|
68
|
+
const codeHasWrites = WRITE_PATTERNS.some((p) => p.test(src));
|
|
69
|
+
const codeHasReads = READ_PATTERNS.some((p) => p.test(src));
|
|
70
|
+
if (descLooksReadOnly && codeHasWrites && !codeHasReads) {
|
|
71
|
+
violations.push({
|
|
72
|
+
name: tool.name,
|
|
73
|
+
issue: 'Description implies read-only but execute function performs writes',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const descLooksDestructive = hasKeyword(desc, DESTRUCTIVE_KEYWORDS);
|
|
77
|
+
const codeOnlyReads = codeHasReads && !codeHasWrites;
|
|
78
|
+
if (descLooksDestructive && codeOnlyReads) {
|
|
79
|
+
violations.push({
|
|
80
|
+
name: tool.name,
|
|
81
|
+
issue: 'Description implies destructive action but execute only reads data',
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (violations.length === 0) {
|
|
86
|
+
return createRuleResult('SEC-006', 8, {
|
|
87
|
+
passed: true,
|
|
88
|
+
score: 8,
|
|
89
|
+
message: 'Tool descriptions match their execute function behavior',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const penalty = violations.length * 4;
|
|
93
|
+
const score = Math.max(0, 8 - penalty);
|
|
94
|
+
return createRuleResult('SEC-006', 8, {
|
|
95
|
+
passed: false,
|
|
96
|
+
score,
|
|
97
|
+
message: `${violations.length} tool(s) may misrepresent their behavior`,
|
|
98
|
+
details: violations.map((v) => `Tool "${v.name}": ${v.issue}`),
|
|
99
|
+
suggestions: [
|
|
100
|
+
'Ensure tool descriptions accurately reflect what the execute function does',
|
|
101
|
+
'A tool described as "read-only" should not perform writes',
|
|
102
|
+
'A tool described as "delete" should actually perform deletions',
|
|
103
|
+
],
|
|
104
|
+
affectedTools: violations.map((v) => v.name),
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=SEC-006.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-006.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-006.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-007: No Hidden Exfiltration
|
|
3
|
+
*
|
|
4
|
+
* Checks that execute functions don't make requests to unexpected domains.
|
|
5
|
+
* Flags tools that fetch/send data to third-party URLs not related to the
|
|
6
|
+
* page's own origin.
|
|
7
|
+
*/
|
|
8
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
9
|
+
export declare const SEC_007: Rule;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-007: No Hidden Exfiltration
|
|
3
|
+
*
|
|
4
|
+
* Checks that execute functions don't make requests to unexpected domains.
|
|
5
|
+
* Flags tools that fetch/send data to third-party URLs not related to the
|
|
6
|
+
* page's own origin.
|
|
7
|
+
*/
|
|
8
|
+
import { createRuleResult } from '../runner.js';
|
|
9
|
+
const URL_PATTERN = /(?:fetch|XMLHttpRequest|\.open)\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
10
|
+
const DYNAMIC_URL_PATTERN = /(?:fetch|XMLHttpRequest|\.open)\s*\(\s*(?!['"`])/g;
|
|
11
|
+
const SAFE_DOMAINS = [
|
|
12
|
+
'localhost',
|
|
13
|
+
'127.0.0.1',
|
|
14
|
+
'cdn.jsdelivr.net',
|
|
15
|
+
'unpkg.com',
|
|
16
|
+
'cdnjs.cloudflare.com',
|
|
17
|
+
];
|
|
18
|
+
function extractDomain(url) {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = new URL(url);
|
|
21
|
+
return parsed.hostname;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export const SEC_007 = {
|
|
28
|
+
id: 'SEC-007',
|
|
29
|
+
category: 'security',
|
|
30
|
+
name: 'No Hidden Exfiltration',
|
|
31
|
+
description: 'Execute functions should not make requests to unexpected external domains',
|
|
32
|
+
severity: 'critical',
|
|
33
|
+
maxScore: 12,
|
|
34
|
+
async check(context) {
|
|
35
|
+
const tools = context.tools;
|
|
36
|
+
if (tools.length === 0) {
|
|
37
|
+
return createRuleResult('SEC-007', 12, {
|
|
38
|
+
passed: true,
|
|
39
|
+
score: 12,
|
|
40
|
+
message: 'No tools detected (rule not applicable)',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const toolsWithExecute = tools.filter((t) => t.executeSource && t.executeSource.length > 0);
|
|
44
|
+
if (toolsWithExecute.length === 0) {
|
|
45
|
+
return createRuleResult('SEC-007', 12, {
|
|
46
|
+
passed: true,
|
|
47
|
+
score: 12,
|
|
48
|
+
message: 'No execute functions available for analysis',
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
let pageDomain = null;
|
|
52
|
+
try {
|
|
53
|
+
pageDomain = new URL(context.url).hostname;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// ignore
|
|
57
|
+
}
|
|
58
|
+
const violations = [];
|
|
59
|
+
for (const tool of toolsWithExecute) {
|
|
60
|
+
const src = tool.executeSource ?? '';
|
|
61
|
+
const foreignDomains = [];
|
|
62
|
+
// Check for static URLs in fetch/XHR calls
|
|
63
|
+
let match;
|
|
64
|
+
const urlRegex = new RegExp(URL_PATTERN.source, 'g');
|
|
65
|
+
while ((match = urlRegex.exec(src)) !== null) {
|
|
66
|
+
const url = match[1];
|
|
67
|
+
if (!url)
|
|
68
|
+
continue;
|
|
69
|
+
const domain = extractDomain(url);
|
|
70
|
+
if (!domain)
|
|
71
|
+
continue;
|
|
72
|
+
const isSameDomain = pageDomain && (domain === pageDomain || domain.endsWith(`.${pageDomain}`));
|
|
73
|
+
const isSafe = SAFE_DOMAINS.some((d) => domain === d || domain.endsWith(`.${d}`));
|
|
74
|
+
if (!isSameDomain && !isSafe && !url.startsWith('/')) {
|
|
75
|
+
foreignDomains.push(domain);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (foreignDomains.length > 0) {
|
|
79
|
+
violations.push({
|
|
80
|
+
name: tool.name,
|
|
81
|
+
domains: [...new Set(foreignDomains)],
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (violations.length === 0) {
|
|
86
|
+
return createRuleResult('SEC-007', 12, {
|
|
87
|
+
passed: true,
|
|
88
|
+
score: 12,
|
|
89
|
+
message: 'No suspicious external requests detected in execute functions',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const penalty = violations.length * 6;
|
|
93
|
+
const score = Math.max(0, 12 - penalty);
|
|
94
|
+
return createRuleResult('SEC-007', 12, {
|
|
95
|
+
passed: false,
|
|
96
|
+
score,
|
|
97
|
+
message: `${violations.length} tool(s) make requests to unexpected external domains`,
|
|
98
|
+
details: violations.map((v) => `Tool "${v.name}" sends data to external domains: [${v.domains.join(', ')}]`),
|
|
99
|
+
suggestions: [
|
|
100
|
+
'Ensure execute functions only communicate with the page\'s own domain',
|
|
101
|
+
'If external APIs are needed, document them in the tool description',
|
|
102
|
+
'Avoid sending user data to third-party domains without explicit disclosure',
|
|
103
|
+
],
|
|
104
|
+
affectedTools: violations.map((v) => v.name),
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=SEC-007.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-007.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-007.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-008: Annotations Accurate
|
|
3
|
+
*
|
|
4
|
+
* Checks that MCP annotations (readOnlyHint, destructiveHint) match
|
|
5
|
+
* the actual behavior detectable in the execute function.
|
|
6
|
+
*/
|
|
7
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
8
|
+
export declare const SEC_008: Rule;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-008: Annotations Accurate
|
|
3
|
+
*
|
|
4
|
+
* Checks that MCP annotations (readOnlyHint, destructiveHint) match
|
|
5
|
+
* the actual behavior detectable in the execute function.
|
|
6
|
+
*/
|
|
7
|
+
import { createRuleResult } from '../runner.js';
|
|
8
|
+
const WRITE_INDICATORS = [
|
|
9
|
+
/fetch\s*\(.*method\s*:\s*['"](?:POST|PUT|DELETE|PATCH)/i,
|
|
10
|
+
/\.submit\s*\(/,
|
|
11
|
+
/\.remove\s*\(/,
|
|
12
|
+
/\.delete\s*\(/,
|
|
13
|
+
/localStorage\.setItem/,
|
|
14
|
+
/sessionStorage\.setItem/,
|
|
15
|
+
/\.save\s*\(/,
|
|
16
|
+
/\.update\s*\(/,
|
|
17
|
+
/\.create\s*\(/,
|
|
18
|
+
/document\.cookie\s*=/,
|
|
19
|
+
];
|
|
20
|
+
const DESTRUCTIVE_INDICATORS = [
|
|
21
|
+
/\.remove\s*\(/,
|
|
22
|
+
/\.delete\s*\(/,
|
|
23
|
+
/fetch\s*\(.*method\s*:\s*['"]DELETE/i,
|
|
24
|
+
/\.destroy\s*\(/,
|
|
25
|
+
/\.drop\s*\(/,
|
|
26
|
+
/\.truncate\s*\(/,
|
|
27
|
+
/\.wipe\s*\(/,
|
|
28
|
+
/\.purge\s*\(/,
|
|
29
|
+
];
|
|
30
|
+
export const SEC_008 = {
|
|
31
|
+
id: 'SEC-008',
|
|
32
|
+
category: 'security',
|
|
33
|
+
name: 'Annotations Accurate',
|
|
34
|
+
description: 'MCP annotations (readOnlyHint, destructiveHint) should match execute function behavior',
|
|
35
|
+
severity: 'warning',
|
|
36
|
+
maxScore: 8,
|
|
37
|
+
async check(context) {
|
|
38
|
+
const tools = context.tools;
|
|
39
|
+
if (tools.length === 0) {
|
|
40
|
+
return createRuleResult('SEC-008', 8, {
|
|
41
|
+
passed: true,
|
|
42
|
+
score: 8,
|
|
43
|
+
message: 'No tools detected (rule not applicable)',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const toolsWithExecute = tools.filter((t) => t.executeSource && t.executeSource.length > 0 && t.annotations);
|
|
47
|
+
if (toolsWithExecute.length === 0) {
|
|
48
|
+
return createRuleResult('SEC-008', 8, {
|
|
49
|
+
passed: true,
|
|
50
|
+
score: 8,
|
|
51
|
+
message: 'No tools with both annotations and execute functions to analyze',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const violations = [];
|
|
55
|
+
for (const tool of toolsWithExecute) {
|
|
56
|
+
const src = tool.executeSource ?? '';
|
|
57
|
+
const annotations = tool.annotations;
|
|
58
|
+
if (!annotations)
|
|
59
|
+
continue;
|
|
60
|
+
const codeHasWrites = WRITE_INDICATORS.some((p) => p.test(src));
|
|
61
|
+
const codeHasDestructive = DESTRUCTIVE_INDICATORS.some((p) => p.test(src));
|
|
62
|
+
// readOnlyHint: true but code does writes
|
|
63
|
+
if (annotations.readOnlyHint === true && codeHasWrites) {
|
|
64
|
+
violations.push({
|
|
65
|
+
name: tool.name,
|
|
66
|
+
issue: 'readOnlyHint is true but execute function performs write operations',
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// destructiveHint: false but code has destructive patterns
|
|
70
|
+
if (annotations.destructiveHint === false && codeHasDestructive) {
|
|
71
|
+
violations.push({
|
|
72
|
+
name: tool.name,
|
|
73
|
+
issue: 'destructiveHint is false but execute function contains destructive operations',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// destructiveHint: true but code only does reads
|
|
77
|
+
if (annotations.destructiveHint === true &&
|
|
78
|
+
!codeHasWrites &&
|
|
79
|
+
!codeHasDestructive) {
|
|
80
|
+
violations.push({
|
|
81
|
+
name: tool.name,
|
|
82
|
+
issue: 'destructiveHint is true but execute function shows no write/destructive patterns',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (violations.length === 0) {
|
|
87
|
+
return createRuleResult('SEC-008', 8, {
|
|
88
|
+
passed: true,
|
|
89
|
+
score: 8,
|
|
90
|
+
message: 'Annotations match detected execute function behavior',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const penalty = violations.length * 4;
|
|
94
|
+
const score = Math.max(0, 8 - penalty);
|
|
95
|
+
return createRuleResult('SEC-008', 8, {
|
|
96
|
+
passed: false,
|
|
97
|
+
score,
|
|
98
|
+
message: `${violations.length} annotation mismatch(es) detected`,
|
|
99
|
+
details: violations.map((v) => `Tool "${v.name}": ${v.issue}`),
|
|
100
|
+
suggestions: [
|
|
101
|
+
'Update readOnlyHint to false if the tool performs any write operations',
|
|
102
|
+
'Set destructiveHint: true if the tool can delete or permanently modify data',
|
|
103
|
+
'Annotations should honestly reflect tool behavior to help agents make safe decisions',
|
|
104
|
+
],
|
|
105
|
+
affectedTools: [...new Set(violations.map((v) => v.name))],
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=SEC-008.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEC-008.js","sourceRoot":"","sources":["../../../src/rules/security/SEC-008.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEC-009: Cross-Origin Awareness
|
|
3
|
+
*
|
|
4
|
+
* Flags tools that send data to cross-origin destinations.
|
|
5
|
+
* This is informational — not necessarily bad, but agents should
|
|
6
|
+
* be aware of cross-origin data flow.
|
|
7
|
+
*/
|
|
8
|
+
import type { Rule } from '../../core/types/rule.js';
|
|
9
|
+
export declare const SEC_009: Rule;
|