@mcp-shark/mcp-shark 1.5.13 → 1.7.2

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.
Files changed (158) hide show
  1. package/README.md +482 -56
  2. package/bin/mcp-shark.js +146 -52
  3. package/core/cli/AutoFixEngine.js +93 -0
  4. package/core/cli/ConfigScanner.js +193 -0
  5. package/core/cli/DataLoader.js +200 -0
  6. package/core/cli/DeclarativeRuleEngine.js +363 -0
  7. package/core/cli/DoctorCommand.js +218 -0
  8. package/core/cli/FixHandlers.js +222 -0
  9. package/core/cli/HtmlReportGenerator.js +203 -0
  10. package/core/cli/IdeConfigPaths.js +175 -0
  11. package/core/cli/ListCommand.js +255 -0
  12. package/core/cli/LockCommand.js +164 -0
  13. package/core/cli/LockDiffEngine.js +152 -0
  14. package/core/cli/RuleRegistryConfig.js +131 -0
  15. package/core/cli/ScanCommand.js +244 -0
  16. package/core/cli/ScanService.js +200 -0
  17. package/core/cli/SecretDetector.js +92 -0
  18. package/core/cli/SharkScoreCalculator.js +109 -0
  19. package/core/cli/ToolClassifications.js +51 -0
  20. package/core/cli/ToxicFlowAnalyzer.js +212 -0
  21. package/core/cli/UpdateCommand.js +188 -0
  22. package/core/cli/WalkthroughGenerator.js +195 -0
  23. package/core/cli/WatchCommand.js +129 -0
  24. package/core/cli/YamlRuleEngine.js +197 -0
  25. package/core/cli/data/rule-packs/aauth-visibility.json +117 -0
  26. package/core/cli/data/rule-packs/agentic-security-2026.json +180 -0
  27. package/core/cli/data/rule-packs/general-security.json +173 -0
  28. package/core/cli/data/rule-packs/owasp-mcp-2026.json +244 -0
  29. package/core/cli/data/rule-packs/toxic-flow-heuristics.json +21 -0
  30. package/core/cli/data/rule-sources.json +5 -0
  31. package/core/cli/data/secret-patterns.json +18 -0
  32. package/core/cli/data/tool-classifications.json +111 -0
  33. package/core/cli/data/toxic-flow-rules.json +47 -0
  34. package/core/cli/index.js +23 -0
  35. package/core/cli/output/Banner.js +52 -0
  36. package/core/cli/output/Formatter.js +183 -0
  37. package/core/cli/output/JsonFormatter.js +106 -0
  38. package/core/cli/output/index.js +16 -0
  39. package/core/cli/secureRegistryFetch.js +157 -0
  40. package/core/cli/symbols.js +16 -0
  41. package/core/configs/environment.js +3 -1
  42. package/core/configs/index.js +3 -64
  43. package/core/container/DependencyContainer.js +4 -1
  44. package/core/mcp-server/index.js +4 -1
  45. package/core/mcp-server/server/external/all.js +10 -3
  46. package/core/mcp-server/server/external/config.js +62 -5
  47. package/core/models/RequestFilters.js +3 -0
  48. package/core/repositories/PacketRepository.js +16 -0
  49. package/core/services/AuditService.js +2 -0
  50. package/core/services/ConfigService.js +9 -1
  51. package/core/services/ConfigTransformService.js +34 -2
  52. package/core/services/RequestService.js +58 -5
  53. package/core/services/ServerManagementService.js +59 -4
  54. package/core/services/security/StaticRulesService.js +69 -13
  55. package/core/services/security/TrafficAnalysisService.js +19 -1
  56. package/core/services/security/TrafficToxicFlowService.js +154 -0
  57. package/core/services/security/aauthGraph.js +199 -0
  58. package/core/services/security/aauthParser.js +274 -0
  59. package/core/services/security/aauthSelfTest.js +346 -0
  60. package/core/services/security/index.js +2 -1
  61. package/core/services/security/rules/index.js +25 -59
  62. package/core/services/security/rules/scans/configPermissions.js +91 -0
  63. package/core/services/security/rules/scans/duplicateToolNames.js +85 -0
  64. package/core/services/security/rules/scans/insecureTransport.js +148 -0
  65. package/core/services/security/rules/scans/missingContainment.js +123 -0
  66. package/core/services/security/rules/scans/shellEnvInjection.js +101 -0
  67. package/core/services/security/rules/scans/unsafeDefaults.js +99 -0
  68. package/core/services/security/toolsListFromTrafficParser.js +70 -0
  69. package/core/tui/App.js +144 -0
  70. package/core/tui/FindingsPanel.js +115 -0
  71. package/core/tui/FixPanel.js +132 -0
  72. package/core/tui/Header.js +51 -0
  73. package/core/tui/HelpBar.js +42 -0
  74. package/core/tui/ServersPanel.js +109 -0
  75. package/core/tui/ToxicFlowsPanel.js +100 -0
  76. package/core/tui/h.js +8 -0
  77. package/core/tui/index.js +11 -0
  78. package/core/tui/render.js +22 -0
  79. package/package.json +24 -16
  80. package/ui/dist/assets/index-D6zDrtMV.js +81 -0
  81. package/ui/dist/index.html +1 -1
  82. package/ui/server/controllers/AauthController.js +279 -0
  83. package/ui/server/controllers/RequestController.js +12 -1
  84. package/ui/server/controllers/SecurityFindingsController.js +46 -1
  85. package/ui/server/routes/aauth.js +18 -0
  86. package/ui/server/routes/requests.js +8 -1
  87. package/ui/server/routes/security.js +5 -1
  88. package/ui/server/setup.js +224 -6
  89. package/ui/server/swagger/paths/components.js +55 -0
  90. package/ui/server/swagger/paths/securityTrafficFlows.js +59 -0
  91. package/ui/server/swagger/paths.js +2 -2
  92. package/ui/server/swagger/swagger.js +5 -2
  93. package/ui/server.js +1 -1
  94. package/ui/src/App.jsx +26 -52
  95. package/ui/src/PacketFilters.jsx +31 -1
  96. package/ui/src/PacketList.jsx +2 -2
  97. package/ui/src/Security.jsx +10 -0
  98. package/ui/src/TabNavigation.jsx +8 -0
  99. package/ui/src/components/AAuthBadge.jsx +92 -0
  100. package/ui/src/components/AauthExplorer/AauthExplorerGraph.jsx +231 -0
  101. package/ui/src/components/AauthExplorer/AauthExplorerView.jsx +387 -0
  102. package/ui/src/components/AauthExplorer/NodeDetailPanel.jsx +272 -0
  103. package/ui/src/components/App/ActionMenu.jsx +4 -31
  104. package/ui/src/components/App/ApiDocsButton.jsx +0 -1
  105. package/ui/src/components/App/ShutdownButton.jsx +0 -1
  106. package/ui/src/components/App/useAppState.js +19 -26
  107. package/ui/src/components/DetailsTab/AAuthIdentitySection.jsx +119 -0
  108. package/ui/src/components/DetailsTab/RequestDetailsSection.jsx +2 -0
  109. package/ui/src/components/DetailsTab/ResponseDetailsSection.jsx +2 -0
  110. package/ui/src/components/DetectedPathsList.jsx +1 -5
  111. package/ui/src/components/FileInput.jsx +0 -1
  112. package/ui/src/components/PacketFilters/AAuthPostureFilter.jsx +81 -0
  113. package/ui/src/components/RequestRow/RequestRowMain.jsx +7 -1
  114. package/ui/src/components/Security/AAuthPosturePanel.jsx +360 -0
  115. package/ui/src/components/Security/ScannerContent.jsx +33 -1
  116. package/ui/src/components/Security/TrafficToxicFlowsPanel.jsx +253 -0
  117. package/ui/src/components/Security/securityApi.js +15 -0
  118. package/ui/src/components/Security/useSecurity.js +60 -3
  119. package/ui/src/components/ServerControl.jsx +0 -1
  120. package/ui/src/components/TabNavigation/DesktopTabs.jsx +0 -11
  121. package/ui/src/components/TabNavigationIcons.jsx +5 -0
  122. package/ui/src/components/ViewModeTabs.jsx +0 -1
  123. package/ui/src/utils/animations.js +26 -9
  124. package/core/services/security/rules/scans/agentic01GoalHijack.js +0 -130
  125. package/core/services/security/rules/scans/agentic02ToolMisuse.js +0 -129
  126. package/core/services/security/rules/scans/agentic03IdentityAbuse.js +0 -130
  127. package/core/services/security/rules/scans/agentic04SupplyChain.js +0 -130
  128. package/core/services/security/rules/scans/agentic06MemoryPoisoning.js +0 -130
  129. package/core/services/security/rules/scans/agentic07InsecureCommunication.js +0 -135
  130. package/core/services/security/rules/scans/agentic08CascadingFailures.js +0 -135
  131. package/core/services/security/rules/scans/agentic09TrustExploitation.js +0 -135
  132. package/core/services/security/rules/scans/agentic10RogueAgent.js +0 -130
  133. package/core/services/security/rules/scans/hardcodedSecrets.js +0 -130
  134. package/core/services/security/rules/scans/mcp01TokenMismanagement.js +0 -127
  135. package/core/services/security/rules/scans/mcp02ScopeCreep.js +0 -130
  136. package/core/services/security/rules/scans/mcp03ToolPoisoning.js +0 -132
  137. package/core/services/security/rules/scans/mcp04SupplyChain.js +0 -131
  138. package/core/services/security/rules/scans/mcp06PromptInjection.js +0 -200
  139. package/core/services/security/rules/scans/mcp07InsufficientAuth.js +0 -130
  140. package/core/services/security/rules/scans/mcp08LackAudit.js +0 -129
  141. package/core/services/security/rules/scans/mcp09ShadowServers.js +0 -129
  142. package/core/services/security/rules/scans/mcp10ContextInjection.js +0 -130
  143. package/ui/dist/assets/index-CiCSDYf-.js +0 -97
  144. package/ui/server/routes/help.js +0 -44
  145. package/ui/server/swagger/paths/help.js +0 -82
  146. package/ui/src/HelpGuide/HelpGuideContent.jsx +0 -118
  147. package/ui/src/HelpGuide/HelpGuideFooter.jsx +0 -59
  148. package/ui/src/HelpGuide/HelpGuideHeader.jsx +0 -57
  149. package/ui/src/HelpGuide.jsx +0 -78
  150. package/ui/src/IntroTour.jsx +0 -154
  151. package/ui/src/components/App/HelpButton.jsx +0 -90
  152. package/ui/src/components/TourOverlay.jsx +0 -117
  153. package/ui/src/components/TourTooltip/TourTooltipButtons.jsx +0 -120
  154. package/ui/src/components/TourTooltip/TourTooltipHeader.jsx +0 -71
  155. package/ui/src/components/TourTooltip/TourTooltipIcons.jsx +0 -54
  156. package/ui/src/components/TourTooltip/useTooltipPosition.js +0 -135
  157. package/ui/src/components/TourTooltip.jsx +0 -91
  158. package/ui/src/config/tourSteps.jsx +0 -140
@@ -1,131 +0,0 @@
1
- import { convertPacketFinding, createRuleAdapter } from '../utils/adapter.js';
2
- import { packetToText, promptToText, resourceToText, toolToText } from '../utils/text.js';
3
-
4
- const RULE_ID = 'mcp04-supply-chain';
5
- const OWASP_ID = 'MCP04';
6
- const RECOMMENDATION =
7
- 'Pin all dependencies to specific versions. Verify package integrity and signatures. Use trusted repositories and registries.';
8
-
9
- const SUPPLY_CHAIN_PATTERNS = [
10
- /(?:unsigned|unverified|untrusted|unauthenticated)\s+(?:package|dependency|module|library)/i,
11
- /(?:tampered|modified|altered|compromised)\s+(?:package|dependency|module|library)/i,
12
- /(?:dependency|package|module)\s+(?:confusion|substitution|hijacking)/i,
13
- /(?:typosquatting|brandjacking|namespace)\s+(?:package|dependency|module)/i,
14
- /(?:unpinned|floating|wildcard)\s+(?:version|dependency|package)/i,
15
- /(?:from|source)\s+(?:unknown|unverified|suspicious|untrusted)\s+(?:source|repository|registry)/i,
16
- ];
17
-
18
- function scanText(text) {
19
- if (!text) {
20
- return null;
21
- }
22
- const matches = [];
23
- for (const pattern of SUPPLY_CHAIN_PATTERNS) {
24
- const match = text.match(pattern);
25
- if (match) {
26
- matches.push(match[0]);
27
- }
28
- }
29
- return matches.length > 0 ? matches : null;
30
- }
31
-
32
- function buildReason(entity, matches) {
33
- return `Potential supply chain vulnerability in ${entity}: ${matches.join(', ')}`;
34
- }
35
-
36
- export function scanMCP04SupplyChain(mcpData = {}) {
37
- const results = {
38
- toolFindings: [],
39
- resourceFindings: [],
40
- promptFindings: [],
41
- notablePatterns: [],
42
- recommendations: [RECOMMENDATION],
43
- };
44
-
45
- for (const tool of mcpData.tools || []) {
46
- const matches = scanText(toolToText(tool));
47
- if (matches) {
48
- results.toolFindings.push({
49
- issueType: 'Supply Chain',
50
- name: tool?.name || 'tool',
51
- severity: 'high',
52
- reasons: [buildReason(`tool "${tool?.name || 'unknown'}"`, matches)],
53
- tags: ['supply-chain', 'dependency-tampering'],
54
- mcpCategory: OWASP_ID,
55
- safeUseNotes:
56
- 'Verify all dependencies and packages. Use signed packages from trusted sources.',
57
- });
58
- }
59
- }
60
-
61
- for (const resource of mcpData.resources || []) {
62
- const matches = scanText(resourceToText(resource));
63
- if (matches) {
64
- results.resourceFindings.push({
65
- issueType: 'Supply Chain',
66
- uri: resource?.uri || resource?.name || 'resource',
67
- severity: 'high',
68
- reasons: [
69
- buildReason(`resource "${resource?.name || resource?.uri || 'unknown'}"`, matches),
70
- ],
71
- tags: ['supply-chain', 'dependency-tampering'],
72
- mcpCategory: OWASP_ID,
73
- });
74
- }
75
- }
76
-
77
- for (const prompt of mcpData.prompts || []) {
78
- const matches = scanText(promptToText(prompt));
79
- if (matches) {
80
- results.promptFindings.push({
81
- issueType: 'Supply Chain',
82
- name: prompt?.name || 'prompt',
83
- severity: 'medium',
84
- reasons: [buildReason(`prompt "${prompt?.name || 'unknown'}"`, matches)],
85
- tags: ['supply-chain', 'dependency-tampering'],
86
- mcpCategory: OWASP_ID,
87
- });
88
- }
89
- }
90
-
91
- return results;
92
- }
93
-
94
- const adapter = createRuleAdapter(scanMCP04SupplyChain, RULE_ID, OWASP_ID, RECOMMENDATION);
95
-
96
- export const analyzeTool = adapter.analyzeTool;
97
- export const analyzePrompt = adapter.analyzePrompt;
98
- export const analyzeResource = adapter.analyzeResource;
99
-
100
- export function analyzePacket(packet) {
101
- const text = packetToText(packet);
102
- const matches = scanText(text);
103
- if (!matches) {
104
- return [];
105
- }
106
- return [
107
- convertPacketFinding(
108
- {
109
- issueType: 'Supply Chain',
110
- severity: 'high',
111
- title: 'Supply Chain Pattern in Traffic',
112
- description: `Potential supply chain vulnerability in packet: ${matches.join(', ')}`,
113
- evidence: matches[0]?.substring(0, 50) || '',
114
- },
115
- RULE_ID,
116
- OWASP_ID,
117
- RECOMMENDATION,
118
- packet
119
- ),
120
- ];
121
- }
122
-
123
- export const ruleMetadata = {
124
- id: RULE_ID,
125
- name: 'Supply Chain Vulnerability Detection',
126
- owasp_id: OWASP_ID,
127
- severity: 'high',
128
- description: 'Detects potential supply chain vulnerabilities in MCP configurations.',
129
- source: 'static',
130
- type: 'owasp-mcp',
131
- };
@@ -1,200 +0,0 @@
1
- import { convertPacketFinding, createRuleAdapter } from '../utils/adapter.js';
2
- import { packetToText, promptToText, resourceToText, toolToText } from '../utils/text.js';
3
-
4
- const RULE_ID = 'mcp06-prompt-injection';
5
- const OWASP_ID = 'MCP06';
6
- const RECOMMENDATION =
7
- 'Implement prompt injection defenses. Validate and sanitize all user inputs. Use prompt isolation and output filtering.';
8
-
9
- const PROMPT_INJECTION_PATTERNS = [
10
- /(?:ignore|forget|disregard)\s+(?:\w+\s+)*(?:previous|prior|earlier|above|instructions|prompts|system)/i,
11
- /(?:new|different|override|replace)\s+(?:instructions|prompt|system|rules)/i,
12
- /(?:you\s+are|act\s+as|pretend\s+to\s+be|roleplay\s+as)/i,
13
- /(?:system|admin|root|sudo)\s+(?:access|privilege|permission|command)/i,
14
- /(?:extract|reveal|show|display|output)\s+(?:system|prompt|instruction|secret|password|token)/i,
15
- /(?:execute|run|perform)\s+(?:arbitrary|any|unrestricted|unlimited)\s+(?:command|action|code)/i,
16
- ];
17
-
18
- const SUSPICIOUS_TOOL_NAME_PATTERNS = [
19
- { pattern: /instruction_?override/i, name: 'Instruction Override Tool', severity: 'critical' },
20
- {
21
- pattern: /system_?prompt|systemprompt/i,
22
- name: 'System Prompt Access Tool',
23
- severity: 'critical',
24
- },
25
- { pattern: /ignore_?instruction/i, name: 'Ignore Instruction Tool', severity: 'critical' },
26
- { pattern: /bypass_?security/i, name: 'Security Bypass Tool', severity: 'critical' },
27
- { pattern: /admin_?override/i, name: 'Admin Override Tool', severity: 'critical' },
28
- { pattern: /privilege_?escalat/i, name: 'Privilege Escalation Tool', severity: 'high' },
29
- { pattern: /sudo|root_?access/i, name: 'Elevated Privilege Tool', severity: 'high' },
30
- { pattern: /hidden_?command/i, name: 'Hidden Command Tool', severity: 'high' },
31
- { pattern: /secret_?access/i, name: 'Secret Access Tool', severity: 'high' },
32
- ];
33
-
34
- function scanText(text) {
35
- if (!text) {
36
- return null;
37
- }
38
- const matches = [];
39
- for (const pattern of PROMPT_INJECTION_PATTERNS) {
40
- const match = text.match(pattern);
41
- if (match) {
42
- matches.push(match[0]);
43
- }
44
- }
45
- return matches.length > 0 ? matches : null;
46
- }
47
-
48
- function checkToolName(toolName) {
49
- if (!toolName) {
50
- return null;
51
- }
52
- for (const { pattern, name, severity } of SUSPICIOUS_TOOL_NAME_PATTERNS) {
53
- if (pattern.test(toolName)) {
54
- return { name, severity, match: toolName };
55
- }
56
- }
57
- return null;
58
- }
59
-
60
- function buildReason(entity, matches) {
61
- return `Potential prompt injection via contextual payloads in ${entity}: ${matches.join(', ')}`;
62
- }
63
-
64
- export function scanMCP06PromptInjection(mcpData = {}) {
65
- const results = {
66
- toolFindings: [],
67
- resourceFindings: [],
68
- promptFindings: [],
69
- notablePatterns: [],
70
- recommendations: [RECOMMENDATION],
71
- };
72
-
73
- for (const tool of mcpData.tools || []) {
74
- // Check tool name for suspicious patterns
75
- const nameCheck = checkToolName(tool?.name);
76
- if (nameCheck) {
77
- results.toolFindings.push({
78
- issueType: 'Prompt Injection Context',
79
- name: tool?.name || 'tool',
80
- severity: nameCheck.severity,
81
- reasons: [`Suspicious tool name detected: "${nameCheck.name}" pattern in "${tool.name}"`],
82
- tags: ['prompt-injection', 'suspicious-tool-name'],
83
- mcpCategory: OWASP_ID,
84
- safeUseNotes:
85
- 'This tool name suggests potential prompt injection or security bypass intent.',
86
- });
87
- }
88
-
89
- const matches = scanText(toolToText(tool));
90
- if (matches) {
91
- results.toolFindings.push({
92
- issueType: 'Prompt Injection Context',
93
- name: tool?.name || 'tool',
94
- severity: 'high',
95
- reasons: [buildReason(`tool "${tool?.name || 'unknown'}"`, matches)],
96
- tags: ['prompt-injection', 'context-injection'],
97
- mcpCategory: OWASP_ID,
98
- safeUseNotes:
99
- 'Review tool inputs for prompt injection vulnerabilities. Implement input validation and sanitization.',
100
- });
101
- }
102
- }
103
-
104
- for (const resource of mcpData.resources || []) {
105
- const matches = scanText(resourceToText(resource));
106
- if (matches) {
107
- results.resourceFindings.push({
108
- issueType: 'Prompt Injection Context',
109
- uri: resource?.uri || resource?.name || 'resource',
110
- severity: 'high',
111
- reasons: [
112
- buildReason(`resource "${resource?.name || resource?.uri || 'unknown'}"`, matches),
113
- ],
114
- tags: ['prompt-injection', 'context-injection'],
115
- mcpCategory: OWASP_ID,
116
- });
117
- }
118
- }
119
-
120
- for (const prompt of mcpData.prompts || []) {
121
- const matches = scanText(promptToText(prompt));
122
- if (matches) {
123
- results.promptFindings.push({
124
- issueType: 'Prompt Injection Context',
125
- name: prompt?.name || 'prompt',
126
- severity: 'critical',
127
- reasons: [buildReason(`prompt "${prompt?.name || 'unknown'}"`, matches)],
128
- tags: ['prompt-injection', 'context-injection'],
129
- mcpCategory: OWASP_ID,
130
- });
131
- }
132
- }
133
-
134
- return results;
135
- }
136
-
137
- const adapter = createRuleAdapter(scanMCP06PromptInjection, RULE_ID, OWASP_ID, RECOMMENDATION);
138
-
139
- export const analyzeTool = adapter.analyzeTool;
140
- export const analyzePrompt = adapter.analyzePrompt;
141
- export const analyzeResource = adapter.analyzeResource;
142
-
143
- export function analyzePacket(packet) {
144
- const findings = [];
145
- const text = packetToText(packet);
146
-
147
- // Check for suspicious tool names in tools/call requests
148
- if (packet.body?.method === 'tools/call' && packet.body?.params?.name) {
149
- const nameCheck = checkToolName(packet.body.params.name);
150
- if (nameCheck) {
151
- findings.push(
152
- convertPacketFinding(
153
- {
154
- issueType: 'Prompt Injection Context',
155
- severity: nameCheck.severity,
156
- title: `Suspicious Tool Call: ${nameCheck.name}`,
157
- description: `Tool "${packet.body.params.name}" matches suspicious pattern: ${nameCheck.name}`,
158
- evidence: packet.body.params.name,
159
- },
160
- RULE_ID,
161
- OWASP_ID,
162
- RECOMMENDATION,
163
- packet
164
- )
165
- );
166
- }
167
- }
168
-
169
- const matches = scanText(text);
170
- if (matches) {
171
- findings.push(
172
- convertPacketFinding(
173
- {
174
- issueType: 'Prompt Injection Context',
175
- severity: 'high',
176
- title: 'Prompt Injection Pattern in Traffic',
177
- description: `Potential prompt injection in packet: ${matches.join(', ')}`,
178
- evidence: matches[0]?.substring(0, 50) || '',
179
- },
180
- RULE_ID,
181
- OWASP_ID,
182
- RECOMMENDATION,
183
- packet
184
- )
185
- );
186
- }
187
-
188
- return findings;
189
- }
190
-
191
- export const ruleMetadata = {
192
- id: RULE_ID,
193
- name: 'Prompt Injection Detection',
194
- owasp_id: OWASP_ID,
195
- severity: 'critical',
196
- description:
197
- 'Detects prompt injection attempts via contextual payloads and suspicious tool names.',
198
- source: 'static',
199
- type: 'owasp-mcp',
200
- };
@@ -1,130 +0,0 @@
1
- import { convertPacketFinding, createRuleAdapter } from '../utils/adapter.js';
2
- import { packetToText, promptToText, resourceToText, toolToText } from '../utils/text.js';
3
-
4
- const RULE_ID = 'mcp07-insufficient-auth';
5
- const OWASP_ID = 'MCP07';
6
- const RECOMMENDATION =
7
- 'Implement proper authentication and authorization mechanisms. Enforce access controls for all tools and resources.';
8
-
9
- const INSUFFICIENT_AUTH_PATTERNS = [
10
- /(?:no|missing|lack|absent|without)\s+(?:authentication|auth|authorization|authz|access\s+control)/i,
11
- /(?:public|open|unrestricted|unprotected|unsecured)\s+(?:access|endpoint|api|tool|resource)/i,
12
- /(?:anonymous|guest|unauthenticated)\s+(?:user|access|request)/i,
13
- /(?:skip|bypass|ignore|disable)\s+(?:authentication|auth|authorization|check|validation)/i,
14
- /(?:weak|insecure|poor|insufficient)\s+(?:authentication|auth|authorization|security)/i,
15
- ];
16
-
17
- function scanText(text) {
18
- if (!text) {
19
- return null;
20
- }
21
- const matches = [];
22
- for (const pattern of INSUFFICIENT_AUTH_PATTERNS) {
23
- const match = text.match(pattern);
24
- if (match) {
25
- matches.push(match[0]);
26
- }
27
- }
28
- return matches.length > 0 ? matches : null;
29
- }
30
-
31
- function buildReason(entity, matches) {
32
- return `Potential insufficient authentication/authorization in ${entity}: ${matches.join(', ')}`;
33
- }
34
-
35
- export function scanMCP07InsufficientAuth(mcpData = {}) {
36
- const results = {
37
- toolFindings: [],
38
- resourceFindings: [],
39
- promptFindings: [],
40
- notablePatterns: [],
41
- recommendations: [RECOMMENDATION],
42
- };
43
-
44
- for (const tool of mcpData.tools || []) {
45
- const matches = scanText(toolToText(tool));
46
- if (matches) {
47
- results.toolFindings.push({
48
- issueType: 'Insufficient Auth',
49
- name: tool?.name || 'tool',
50
- severity: 'high',
51
- reasons: [buildReason(`tool "${tool?.name || 'unknown'}"`, matches)],
52
- tags: ['insufficient-auth', 'authentication', 'authorization'],
53
- mcpCategory: OWASP_ID,
54
- safeUseNotes:
55
- 'Review tool authentication requirements. Ensure proper access controls are in place.',
56
- });
57
- }
58
- }
59
-
60
- for (const resource of mcpData.resources || []) {
61
- const matches = scanText(resourceToText(resource));
62
- if (matches) {
63
- results.resourceFindings.push({
64
- issueType: 'Insufficient Auth',
65
- uri: resource?.uri || resource?.name || 'resource',
66
- severity: 'high',
67
- reasons: [
68
- buildReason(`resource "${resource?.name || resource?.uri || 'unknown'}"`, matches),
69
- ],
70
- tags: ['insufficient-auth', 'authentication', 'authorization'],
71
- mcpCategory: OWASP_ID,
72
- });
73
- }
74
- }
75
-
76
- for (const prompt of mcpData.prompts || []) {
77
- const matches = scanText(promptToText(prompt));
78
- if (matches) {
79
- results.promptFindings.push({
80
- issueType: 'Insufficient Auth',
81
- name: prompt?.name || 'prompt',
82
- severity: 'medium',
83
- reasons: [buildReason(`prompt "${prompt?.name || 'unknown'}"`, matches)],
84
- tags: ['insufficient-auth', 'authentication', 'authorization'],
85
- mcpCategory: OWASP_ID,
86
- });
87
- }
88
- }
89
-
90
- return results;
91
- }
92
-
93
- const adapter = createRuleAdapter(scanMCP07InsufficientAuth, RULE_ID, OWASP_ID, RECOMMENDATION);
94
-
95
- export const analyzeTool = adapter.analyzeTool;
96
- export const analyzePrompt = adapter.analyzePrompt;
97
- export const analyzeResource = adapter.analyzeResource;
98
-
99
- export function analyzePacket(packet) {
100
- const text = packetToText(packet);
101
- const matches = scanText(text);
102
- if (!matches) {
103
- return [];
104
- }
105
- return [
106
- convertPacketFinding(
107
- {
108
- issueType: 'Insufficient Auth',
109
- severity: 'high',
110
- title: 'Insufficient Auth Pattern in Traffic',
111
- description: `Potential authentication weakness in packet: ${matches.join(', ')}`,
112
- evidence: matches[0]?.substring(0, 50) || '',
113
- },
114
- RULE_ID,
115
- OWASP_ID,
116
- RECOMMENDATION,
117
- packet
118
- ),
119
- ];
120
- }
121
-
122
- export const ruleMetadata = {
123
- id: RULE_ID,
124
- name: 'Insufficient Authentication Detection',
125
- owasp_id: OWASP_ID,
126
- severity: 'high',
127
- description: 'Detects potential authentication and authorization weaknesses.',
128
- source: 'static',
129
- type: 'owasp-mcp',
130
- };
@@ -1,129 +0,0 @@
1
- import { convertPacketFinding, createRuleAdapter } from '../utils/adapter.js';
2
- import { packetToText, promptToText, resourceToText, toolToText } from '../utils/text.js';
3
-
4
- const RULE_ID = 'mcp08-lack-audit';
5
- const OWASP_ID = 'MCP08';
6
- const RECOMMENDATION =
7
- 'Implement comprehensive logging, audit trails, and telemetry. Monitor all tool usage and resource access.';
8
-
9
- const LACK_AUDIT_PATTERNS = [
10
- /(?:no|missing|lack|absent|without)\s+(?:logging|log|audit|telemetry|monitoring|tracking)/i,
11
- /(?:disable|turn\s+off|remove)\s+(?:logging|log|audit|telemetry|monitoring)/i,
12
- /(?:silent|quiet|no\s+output)\s+(?:mode|operation|execution)/i,
13
- /(?:unlogged|unmonitored|untracked)\s+(?:action|operation|event|access)/i,
14
- ];
15
-
16
- function scanText(text) {
17
- if (!text) {
18
- return null;
19
- }
20
- const matches = [];
21
- for (const pattern of LACK_AUDIT_PATTERNS) {
22
- const match = text.match(pattern);
23
- if (match) {
24
- matches.push(match[0]);
25
- }
26
- }
27
- return matches.length > 0 ? matches : null;
28
- }
29
-
30
- function buildReason(entity, matches) {
31
- return `Potential lack of audit/telemetry in ${entity}: ${matches.join(', ')}`;
32
- }
33
-
34
- export function scanMCP08LackAudit(mcpData = {}) {
35
- const results = {
36
- toolFindings: [],
37
- resourceFindings: [],
38
- promptFindings: [],
39
- notablePatterns: [],
40
- recommendations: [RECOMMENDATION],
41
- };
42
-
43
- for (const tool of mcpData.tools || []) {
44
- const matches = scanText(toolToText(tool));
45
- if (matches) {
46
- results.toolFindings.push({
47
- issueType: 'Lack Audit',
48
- name: tool?.name || 'tool',
49
- severity: 'medium',
50
- reasons: [buildReason(`tool "${tool?.name || 'unknown'}"`, matches)],
51
- tags: ['lack-audit', 'telemetry', 'logging'],
52
- mcpCategory: OWASP_ID,
53
- safeUseNotes:
54
- 'Ensure tool operations are logged and audited. Implement telemetry for security monitoring.',
55
- });
56
- }
57
- }
58
-
59
- for (const resource of mcpData.resources || []) {
60
- const matches = scanText(resourceToText(resource));
61
- if (matches) {
62
- results.resourceFindings.push({
63
- issueType: 'Lack Audit',
64
- uri: resource?.uri || resource?.name || 'resource',
65
- severity: 'medium',
66
- reasons: [
67
- buildReason(`resource "${resource?.name || resource?.uri || 'unknown'}"`, matches),
68
- ],
69
- tags: ['lack-audit', 'telemetry', 'logging'],
70
- mcpCategory: OWASP_ID,
71
- });
72
- }
73
- }
74
-
75
- for (const prompt of mcpData.prompts || []) {
76
- const matches = scanText(promptToText(prompt));
77
- if (matches) {
78
- results.promptFindings.push({
79
- issueType: 'Lack Audit',
80
- name: prompt?.name || 'prompt',
81
- severity: 'low',
82
- reasons: [buildReason(`prompt "${prompt?.name || 'unknown'}"`, matches)],
83
- tags: ['lack-audit', 'telemetry', 'logging'],
84
- mcpCategory: OWASP_ID,
85
- });
86
- }
87
- }
88
-
89
- return results;
90
- }
91
-
92
- const adapter = createRuleAdapter(scanMCP08LackAudit, RULE_ID, OWASP_ID, RECOMMENDATION);
93
-
94
- export const analyzeTool = adapter.analyzeTool;
95
- export const analyzePrompt = adapter.analyzePrompt;
96
- export const analyzeResource = adapter.analyzeResource;
97
-
98
- export function analyzePacket(packet) {
99
- const text = packetToText(packet);
100
- const matches = scanText(text);
101
- if (!matches) {
102
- return [];
103
- }
104
- return [
105
- convertPacketFinding(
106
- {
107
- issueType: 'Lack Audit',
108
- severity: 'medium',
109
- title: 'Audit Bypass Pattern in Traffic',
110
- description: `Potential audit bypass in packet: ${matches.join(', ')}`,
111
- evidence: matches[0]?.substring(0, 50) || '',
112
- },
113
- RULE_ID,
114
- OWASP_ID,
115
- RECOMMENDATION,
116
- packet
117
- ),
118
- ];
119
- }
120
-
121
- export const ruleMetadata = {
122
- id: RULE_ID,
123
- name: 'Lack of Audit Detection',
124
- owasp_id: OWASP_ID,
125
- severity: 'medium',
126
- description: 'Detects potential lack of audit trails and telemetry.',
127
- source: 'static',
128
- type: 'owasp-mcp',
129
- };