mcp-code-context 3.4.0 → 3.5.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/CHANGELOG.md +3 -3
- package/CHANGELOG_v3.2.0.md +196 -196
- package/CHANGELOG_v3.3.0.md +266 -266
- package/SECURITY.md +177 -177
- package/dist/src/core/engine.d.ts +1 -1
- package/dist/src/core/engine.js +11 -1
- package/dist/src/core/engine.js.map +1 -1
- package/dist/src/core/validator.d.ts +1 -1
- package/dist/src/core/validator.js +3 -5
- package/dist/src/core/validator.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +43 -11
- package/dist/src/index.js.map +1 -1
- package/dist/src/operations/compress.d.ts +1 -1
- package/dist/src/operations/compress.js +1 -1
- package/dist/src/operations/confirmationStore.d.ts +10 -1
- package/dist/src/operations/confirmationStore.js +2 -1
- package/dist/src/operations/confirmationStore.js.map +1 -1
- package/dist/src/operations/read.d.ts +2 -2
- package/dist/src/operations/read.js +38 -42
- package/dist/src/operations/read.js.map +1 -1
- package/dist/src/operations/write.d.ts +9 -2
- package/dist/src/operations/write.js +21 -15
- package/dist/src/operations/write.js.map +1 -1
- package/dist/src/parsers/base.d.ts +1 -1
- package/dist/src/parsers/base.js +1 -1
- package/dist/src/parsers/dartTreeSitter.d.ts +1 -1
- package/dist/src/parsers/dartTreeSitter.js +1 -1
- package/dist/src/parsers/php.d.ts +1 -1
- package/dist/src/parsers/php.js +1 -1
- package/dist/src/parsers/python.d.ts +1 -1
- package/dist/src/parsers/python.js +1 -1
- package/dist/src/parsers/registry.d.ts +1 -1
- package/dist/src/parsers/registry.js +1 -1
- package/dist/src/parsers/typescript.d.ts +1 -1
- package/dist/src/parsers/typescript.js +1 -1
- package/dist/src/utils/auditLogger.d.ts +1 -1
- package/dist/src/utils/auditLogger.js +1 -1
- package/dist/src/utils/backupManager.d.ts +1 -1
- package/dist/src/utils/backupManager.js +1 -1
- package/dist/src/utils/constants.d.ts +1 -1
- package/dist/src/utils/constants.js +1 -1
- package/dist/src/utils/diff.d.ts +1 -1
- package/dist/src/utils/diff.js +1 -1
- package/dist/src/utils/fileLock.d.ts +1 -1
- package/dist/src/utils/fileLock.js +1 -1
- package/dist/src/utils/rateLimiter.d.ts +1 -1
- package/dist/src/utils/rateLimiter.js +1 -1
- package/dist/src/utils/safeRegex.d.ts +55 -4
- package/dist/src/utils/safeRegex.js +186 -61
- package/dist/src/utils/safeRegex.js.map +1 -1
- package/dist/src/utils/streaming.d.ts +1 -1
- package/dist/src/utils/streaming.js +1 -1
- package/dist/src/utils/telemetry.d.ts +1 -1
- package/dist/src/utils/telemetry.js +1 -1
- package/llms.txt +5 -5
- package/package.json +1 -1
- package/scripts/replace-version.js +59 -0
package/SECURITY.md
CHANGED
|
@@ -1,177 +1,177 @@
|
|
|
1
|
-
# Security Policy - mcp-code-context v3.
|
|
2
|
-
|
|
3
|
-
## 🔒 Security Improvements in v3.
|
|
4
|
-
|
|
5
|
-
This release addresses **all critical security vulnerabilities** from comprehensive adversarial audit, implements full middleware pipeline, and hardens all 13 tool handlers.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Fixed Vulnerabilities
|
|
10
|
-
|
|
11
|
-
### 1. Path Traversal (HIGH)
|
|
12
|
-
**CVSS Score**: 8.1 (High)
|
|
13
|
-
**Status**: ✅ FIXED in v3.2.0, **hardened in v3.
|
|
14
|
-
|
|
15
|
-
**Description**: Path traversal check occurred BEFORE path normalization, allowing bypass with absolute paths.
|
|
16
|
-
|
|
17
|
-
**Fix**: Check boundary AFTER `path.resolve()` normalization. In v3.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
### 2. Regex Injection in renameSymbol (HIGH)
|
|
22
|
-
**CVSS Score**: 7.5 (High)
|
|
23
|
-
**Status**: ✅ FIXED in v3.2.0
|
|
24
|
-
|
|
25
|
-
**Description**: User-provided symbol names used directly in regex without sanitization.
|
|
26
|
-
|
|
27
|
-
**Fix**: Sanitize all regex metacharacters via `sanitizeRegexPattern()` before use.
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
### 3. Code Corruption via Invalid Syntax (CRITICAL)
|
|
32
|
-
**CVSS Score**: 9.1 (Critical)
|
|
33
|
-
**Status**: ✅ FIXED in v3.2.0
|
|
34
|
-
|
|
35
|
-
**Description**: Write operations did not validate syntax of generated code.
|
|
36
|
-
|
|
37
|
-
**Fix**: Mandatory AST syntax validation before all writes.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
### 4. ReDoS in searchPattern and readLines (MEDIUM)
|
|
42
|
-
**CVSS Score**: 5.3 (Medium)
|
|
43
|
-
**Status**: ✅ FIXED in v3.
|
|
44
|
-
|
|
45
|
-
**Description**: User-provided regex patterns could cause catastrophic backtracking.
|
|
46
|
-
|
|
47
|
-
**Fix**: All regex operations now use `safeRegexTest()` with pattern validation and timeout enforcement (1s limit).
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
### 5. Unbounded Memory in compress (MEDIUM)
|
|
52
|
-
**CVSS Score**: 5.9 (Medium)
|
|
53
|
-
**Status**: ✅ FIXED in v3.2.0
|
|
54
|
-
|
|
55
|
-
**Fix**: `MAX_TOTAL_SIZE_BYTES` (50MB) + `MAX_FILES_REPO_MAP` (500) limits.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
### 6. extractSymbol API Mismatch (CRITICAL)
|
|
60
|
-
**CVSS Score**: 9.0 (Critical)
|
|
61
|
-
**Status**: ✅ FIXED in v3.
|
|
62
|
-
|
|
63
|
-
**Description**: `read.ts` passed `content` as `symbolName` and real `symbolName` as `className`. Symbol extraction was 100% broken.
|
|
64
|
-
|
|
65
|
-
**Fix**: Corrected argument order to match `BaseParser.extractSymbol(tree, symbolName, className?)`.
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
### 7. Handlers Without Path Validation (HIGH)
|
|
70
|
-
**CVSS Score**: 8.5 (High)
|
|
71
|
-
**Status**: ✅ FIXED in v3.
|
|
72
|
-
|
|
73
|
-
**Description**: `readLines`, `searchPattern`, `analyzeImpact`, `getSemanticRepoMap` had no path boundary check.
|
|
74
|
-
|
|
75
|
-
**Fix**: All 13 handlers now require `projectRoot` and validate all paths via `SecurityValidator`.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
### 8. renameSymbol Arbitrary Write (HIGH)
|
|
80
|
-
**CVSS Score**: 8.0 (High)
|
|
81
|
-
**Status**: ✅ FIXED in v3.
|
|
82
|
-
|
|
83
|
-
**Description**: `renameSymbol` wrote dependent files without SecurityValidator check, using non-atomic writes.
|
|
84
|
-
|
|
85
|
-
**Fix**: Each dependent file path validated via SecurityValidator + atomic write (write-to-tmp + rename).
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
### 9. LCS Diff OOM (MEDIUM)
|
|
90
|
-
**CVSS Score**: 5.0 (Medium)
|
|
91
|
-
**Status**: ✅ FIXED in v3.
|
|
92
|
-
|
|
93
|
-
**Description**: LCS diff algorithm is O(n²) memory — 10K-line files cause OOM.
|
|
94
|
-
|
|
95
|
-
**Fix**: `MAX_DIFF_LINES = 5000` guard — falls back to O(n) `generateSimpleDiff` for large files.
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
## Security Features
|
|
100
|
-
|
|
101
|
-
### Defense in Depth
|
|
102
|
-
|
|
103
|
-
1. **Input Validation**
|
|
104
|
-
- Path boundary enforcement on ALL handlers (v3.
|
|
105
|
-
- File size limits (10MB per file, 50MB total)
|
|
106
|
-
- Regex sanitization + timeout (1s limit)
|
|
107
|
-
|
|
108
|
-
2. **Two-Phase Write Workflow** (v3.
|
|
109
|
-
- Phase 1: Dry-run returns diff + confirmation token
|
|
110
|
-
- Phase 2: Apply with token (5-minute expiry)
|
|
111
|
-
- Max 50 pending operations
|
|
112
|
-
|
|
113
|
-
3. **Middleware Pipeline** (v3.
|
|
114
|
-
- Rate limiting (token bucket per operation)
|
|
115
|
-
- File locking (prevents concurrent writes)
|
|
116
|
-
- Audit logging (persistent `.mcp-audit-logs/`)
|
|
117
|
-
- Telemetry (operation metrics, percentiles)
|
|
118
|
-
|
|
119
|
-
4. **Syntax Validation**
|
|
120
|
-
- AST parsing of generated code post-write
|
|
121
|
-
- Rejection of invalid syntax before any file modification
|
|
122
|
-
|
|
123
|
-
5. **Atomic Writes**
|
|
124
|
-
- Write to `.tmp` file, then rename
|
|
125
|
-
- Prevents corruption on crash/timeout
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## Reporting Vulnerabilities
|
|
130
|
-
|
|
131
|
-
1. **DO NOT** open public GitHub issues for security vulnerabilities
|
|
132
|
-
2. Include: Description, Steps to reproduce, Impact, Suggested fix
|
|
133
|
-
3. Response: Critical 24h, High 72h, Medium 1 week
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Security Testing
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
npm run build:tests
|
|
141
|
-
node dist-tests/tests/test-security.js
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**Coverage**:
|
|
145
|
-
- ✅ Path traversal (all handlers)
|
|
146
|
-
- ✅ Regex injection (sanitization + timeout)
|
|
147
|
-
- ✅ File size validation
|
|
148
|
-
- ✅ ReDoS detection
|
|
149
|
-
- ✅ Two-phase write confirmation
|
|
150
|
-
- ✅ Rate limiting
|
|
151
|
-
- ✅ File locking
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Completed Security Roadmap
|
|
156
|
-
|
|
157
|
-
### v3.2.0 ✅
|
|
158
|
-
- [x] Path traversal fix (normalize before check)
|
|
159
|
-
- [x] Regex sanitization
|
|
160
|
-
- [x] Syntax validation
|
|
161
|
-
- [x] Bounded memory in compress
|
|
162
|
-
|
|
163
|
-
### v3.
|
|
164
|
-
- [x] Regex timeout enforcement (safeRegexTest)
|
|
165
|
-
- [x] Rate limiting (token bucket)
|
|
166
|
-
- [x] File locking (concurrent write prevention)
|
|
167
|
-
- [x] Audit logging (persistent, rotated)
|
|
168
|
-
- [x] Telemetry (operation metrics)
|
|
169
|
-
- [x] Two-phase write workflow
|
|
170
|
-
- [x] All handlers validated with projectRoot
|
|
171
|
-
- [x] extractSymbol bug fix
|
|
172
|
-
- [x] Diff OOM guard
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
**Last Updated**: 2026-04-24
|
|
177
|
-
**Version**: 3.
|
|
1
|
+
# Security Policy - mcp-code-context v3.5.0
|
|
2
|
+
|
|
3
|
+
## 🔒 Security Improvements in v3.5.0
|
|
4
|
+
|
|
5
|
+
This release addresses **all critical security vulnerabilities** from comprehensive adversarial audit, implements full middleware pipeline, and hardens all 13 tool handlers.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Fixed Vulnerabilities
|
|
10
|
+
|
|
11
|
+
### 1. Path Traversal (HIGH)
|
|
12
|
+
**CVSS Score**: 8.1 (High)
|
|
13
|
+
**Status**: ✅ FIXED in v3.2.0, **hardened in v3.5.0**
|
|
14
|
+
|
|
15
|
+
**Description**: Path traversal check occurred BEFORE path normalization, allowing bypass with absolute paths.
|
|
16
|
+
|
|
17
|
+
**Fix**: Check boundary AFTER `path.resolve()` normalization. In v3.5.0, **all 13 handlers** now require `projectRoot` and validate via `SecurityValidator`.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### 2. Regex Injection in renameSymbol (HIGH)
|
|
22
|
+
**CVSS Score**: 7.5 (High)
|
|
23
|
+
**Status**: ✅ FIXED in v3.2.0
|
|
24
|
+
|
|
25
|
+
**Description**: User-provided symbol names used directly in regex without sanitization.
|
|
26
|
+
|
|
27
|
+
**Fix**: Sanitize all regex metacharacters via `sanitizeRegexPattern()` before use.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### 3. Code Corruption via Invalid Syntax (CRITICAL)
|
|
32
|
+
**CVSS Score**: 9.1 (Critical)
|
|
33
|
+
**Status**: ✅ FIXED in v3.2.0
|
|
34
|
+
|
|
35
|
+
**Description**: Write operations did not validate syntax of generated code.
|
|
36
|
+
|
|
37
|
+
**Fix**: Mandatory AST syntax validation before all writes.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### 4. ReDoS in searchPattern and readLines (MEDIUM)
|
|
42
|
+
**CVSS Score**: 5.3 (Medium)
|
|
43
|
+
**Status**: ✅ FIXED in v3.5.0
|
|
44
|
+
|
|
45
|
+
**Description**: User-provided regex patterns could cause catastrophic backtracking.
|
|
46
|
+
|
|
47
|
+
**Fix**: All regex operations now use `safeRegexTest()` with pattern validation and timeout enforcement (1s limit).
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### 5. Unbounded Memory in compress (MEDIUM)
|
|
52
|
+
**CVSS Score**: 5.9 (Medium)
|
|
53
|
+
**Status**: ✅ FIXED in v3.2.0
|
|
54
|
+
|
|
55
|
+
**Fix**: `MAX_TOTAL_SIZE_BYTES` (50MB) + `MAX_FILES_REPO_MAP` (500) limits.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
### 6. extractSymbol API Mismatch (CRITICAL)
|
|
60
|
+
**CVSS Score**: 9.0 (Critical)
|
|
61
|
+
**Status**: ✅ FIXED in v3.5.0
|
|
62
|
+
|
|
63
|
+
**Description**: `read.ts` passed `content` as `symbolName` and real `symbolName` as `className`. Symbol extraction was 100% broken.
|
|
64
|
+
|
|
65
|
+
**Fix**: Corrected argument order to match `BaseParser.extractSymbol(tree, symbolName, className?)`.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### 7. Handlers Without Path Validation (HIGH)
|
|
70
|
+
**CVSS Score**: 8.5 (High)
|
|
71
|
+
**Status**: ✅ FIXED in v3.5.0
|
|
72
|
+
|
|
73
|
+
**Description**: `readLines`, `searchPattern`, `analyzeImpact`, `getSemanticRepoMap` had no path boundary check.
|
|
74
|
+
|
|
75
|
+
**Fix**: All 13 handlers now require `projectRoot` and validate all paths via `SecurityValidator`.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### 8. renameSymbol Arbitrary Write (HIGH)
|
|
80
|
+
**CVSS Score**: 8.0 (High)
|
|
81
|
+
**Status**: ✅ FIXED in v3.5.0
|
|
82
|
+
|
|
83
|
+
**Description**: `renameSymbol` wrote dependent files without SecurityValidator check, using non-atomic writes.
|
|
84
|
+
|
|
85
|
+
**Fix**: Each dependent file path validated via SecurityValidator + atomic write (write-to-tmp + rename).
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### 9. LCS Diff OOM (MEDIUM)
|
|
90
|
+
**CVSS Score**: 5.0 (Medium)
|
|
91
|
+
**Status**: ✅ FIXED in v3.5.0
|
|
92
|
+
|
|
93
|
+
**Description**: LCS diff algorithm is O(n²) memory — 10K-line files cause OOM.
|
|
94
|
+
|
|
95
|
+
**Fix**: `MAX_DIFF_LINES = 5000` guard — falls back to O(n) `generateSimpleDiff` for large files.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Security Features
|
|
100
|
+
|
|
101
|
+
### Defense in Depth
|
|
102
|
+
|
|
103
|
+
1. **Input Validation**
|
|
104
|
+
- Path boundary enforcement on ALL handlers (v3.5.0)
|
|
105
|
+
- File size limits (10MB per file, 50MB total)
|
|
106
|
+
- Regex sanitization + timeout (1s limit)
|
|
107
|
+
|
|
108
|
+
2. **Two-Phase Write Workflow** (v3.5.0)
|
|
109
|
+
- Phase 1: Dry-run returns diff + confirmation token
|
|
110
|
+
- Phase 2: Apply with token (5-minute expiry)
|
|
111
|
+
- Max 50 pending operations
|
|
112
|
+
|
|
113
|
+
3. **Middleware Pipeline** (v3.5.0)
|
|
114
|
+
- Rate limiting (token bucket per operation)
|
|
115
|
+
- File locking (prevents concurrent writes)
|
|
116
|
+
- Audit logging (persistent `.mcp-audit-logs/`)
|
|
117
|
+
- Telemetry (operation metrics, percentiles)
|
|
118
|
+
|
|
119
|
+
4. **Syntax Validation**
|
|
120
|
+
- AST parsing of generated code post-write
|
|
121
|
+
- Rejection of invalid syntax before any file modification
|
|
122
|
+
|
|
123
|
+
5. **Atomic Writes**
|
|
124
|
+
- Write to `.tmp` file, then rename
|
|
125
|
+
- Prevents corruption on crash/timeout
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Reporting Vulnerabilities
|
|
130
|
+
|
|
131
|
+
1. **DO NOT** open public GitHub issues for security vulnerabilities
|
|
132
|
+
2. Include: Description, Steps to reproduce, Impact, Suggested fix
|
|
133
|
+
3. Response: Critical 24h, High 72h, Medium 1 week
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Security Testing
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm run build:tests
|
|
141
|
+
node dist-tests/tests/test-security.js
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Coverage**:
|
|
145
|
+
- ✅ Path traversal (all handlers)
|
|
146
|
+
- ✅ Regex injection (sanitization + timeout)
|
|
147
|
+
- ✅ File size validation
|
|
148
|
+
- ✅ ReDoS detection
|
|
149
|
+
- ✅ Two-phase write confirmation
|
|
150
|
+
- ✅ Rate limiting
|
|
151
|
+
- ✅ File locking
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Completed Security Roadmap
|
|
156
|
+
|
|
157
|
+
### v3.2.0 ✅
|
|
158
|
+
- [x] Path traversal fix (normalize before check)
|
|
159
|
+
- [x] Regex sanitization
|
|
160
|
+
- [x] Syntax validation
|
|
161
|
+
- [x] Bounded memory in compress
|
|
162
|
+
|
|
163
|
+
### v3.5.0 ✅
|
|
164
|
+
- [x] Regex timeout enforcement (safeRegexTest)
|
|
165
|
+
- [x] Rate limiting (token bucket)
|
|
166
|
+
- [x] File locking (concurrent write prevention)
|
|
167
|
+
- [x] Audit logging (persistent, rotated)
|
|
168
|
+
- [x] Telemetry (operation metrics)
|
|
169
|
+
- [x] Two-phase write workflow
|
|
170
|
+
- [x] All handlers validated with projectRoot
|
|
171
|
+
- [x] extractSymbol bug fix
|
|
172
|
+
- [x] Diff OOM guard
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
**Last Updated**: 2026-04-24
|
|
177
|
+
**Version**: 3.5.0
|
package/dist/src/core/engine.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Core Engine - v3.
|
|
2
|
+
* Core Engine - v3.5.0
|
|
3
3
|
* ASYNC I/O: Migrated to fs.promises
|
|
4
4
|
*/
|
|
5
5
|
import { Parser, Language } from "web-tree-sitter";
|
|
@@ -7,6 +7,7 @@ import * as path from "node:path";
|
|
|
7
7
|
import * as fs from "node:fs/promises";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { dirname } from "path";
|
|
10
|
+
import { createRequire } from "node:module";
|
|
10
11
|
export class CodeContextEngine {
|
|
11
12
|
config;
|
|
12
13
|
initialized = false;
|
|
@@ -39,6 +40,15 @@ export class CodeContextEngine {
|
|
|
39
40
|
// 3. Fallback to process.cwd()
|
|
40
41
|
path.join(process.cwd(), "node_modules", "tree-sitter-wasms", "out", wasmFile),
|
|
41
42
|
];
|
|
43
|
+
// 4. Robust Node.js module resolution (handles npx hoisting and global installs)
|
|
44
|
+
try {
|
|
45
|
+
const require = createRequire(import.meta.url);
|
|
46
|
+
const pkgPath = require.resolve("tree-sitter-wasms/package.json");
|
|
47
|
+
possiblePaths.unshift(path.join(path.dirname(pkgPath), "out", wasmFile));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Ignore resolution errors, fallback to manual paths
|
|
51
|
+
}
|
|
42
52
|
let wasmPath = null;
|
|
43
53
|
for (const p of possiblePaths) {
|
|
44
54
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/core/engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/core/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Security Validator - v3.
|
|
2
|
+
* Security Validator - v3.5.0
|
|
3
3
|
* CRITICAL FIX: Path traversal check AFTER normalization
|
|
4
4
|
*/
|
|
5
5
|
import * as path from "node:path";
|
|
@@ -16,10 +16,8 @@ export class SecurityValidator {
|
|
|
16
16
|
if (!resolved.startsWith(this.projectRoot)) {
|
|
17
17
|
return { valid: false, error: "Path outside project boundary" };
|
|
18
18
|
}
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
return { valid: false, error: "Invalid path: contains dangerous patterns" };
|
|
22
|
-
}
|
|
19
|
+
// NOTE: Path traversal already caught by startsWith check above.
|
|
20
|
+
// Removed dead code that duplicated the boundary check (unreachable condition).
|
|
23
21
|
// Existence check
|
|
24
22
|
try {
|
|
25
23
|
await fs.access(resolved);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/core/validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQvC,MAAM,OAAO,iBAAiB;IACpB,WAAW,CAAS;IAE5B,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QACrC,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAExC,+CAA+C;QAC/C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC;QAClE,CAAC;QAED,
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/core/validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQvC,MAAM,OAAO,iBAAiB;IACpB,WAAW,CAAS;IAE5B,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QACrC,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAExC,+CAA+C;QAC/C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC;QAClE,CAAC;QAED,iEAAiE;QACjE,gFAAgF;QAEhF,kBAAkB;QAClB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;QACxD,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,UAAkB,EAAE,GAAG,IAAI,GAAG,IAAI;QACzE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9F,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,KAAK,EAAE,EAAE,CAAC;QACxE,CAAC;IACH,CAAC;CACF"}
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* mcp-code-context v3.
|
|
3
|
+
* mcp-code-context v3.5.0 - Tree-sitter WASM Edition
|
|
4
4
|
*
|
|
5
5
|
* Production-ready with:
|
|
6
6
|
* - Tree-sitter WASM for 100% AST accuracy (TypeScript, Python, PHP, Dart)
|
|
@@ -28,7 +28,7 @@ import { streamFile } from "./utils/streaming.js";
|
|
|
28
28
|
import { BackupManager } from "./utils/backupManager.js";
|
|
29
29
|
import * as fs from "node:fs/promises";
|
|
30
30
|
const SERVER_NAME = "mcp-code-context";
|
|
31
|
-
const SERVER_VERSION = "3.
|
|
31
|
+
const SERVER_VERSION = "3.5.0";
|
|
32
32
|
// Global instances
|
|
33
33
|
let engine;
|
|
34
34
|
let registry;
|
|
@@ -252,8 +252,10 @@ async function handleGetSemanticRepoMap(args) {
|
|
|
252
252
|
registry,
|
|
253
253
|
format: format
|
|
254
254
|
});
|
|
255
|
+
if (!result.success)
|
|
256
|
+
throw new Error(result.error);
|
|
255
257
|
return {
|
|
256
|
-
content: [{ type: "text", text: result }],
|
|
258
|
+
content: [{ type: "text", text: result.content }],
|
|
257
259
|
};
|
|
258
260
|
}
|
|
259
261
|
async function handleReadFileSurgical(args) {
|
|
@@ -373,12 +375,21 @@ async function handleTwoPhaseWrite(args, operationName, executeWrite) {
|
|
|
373
375
|
const pendingOp = globalConfirmationStore.consumePending(token);
|
|
374
376
|
if (!pendingOp)
|
|
375
377
|
throw new Error(`Invalid or expired confirmation token: ${token}`);
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
if (pendingOp.pendingWrites && pendingOp.pendingWrites.length > 0) {
|
|
379
|
+
// Multi-file rename: backup and write ALL files atomically
|
|
380
|
+
for (const pw of pendingOp.pendingWrites) {
|
|
381
|
+
await BackupManager.createBackup(pw.filePath, String(args.projectRoot));
|
|
382
|
+
await writeFile(pw.filePath, pw.newContent);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
// Single-file operation
|
|
387
|
+
await BackupManager.createBackup(pendingOp.filePath, String(args.projectRoot));
|
|
388
|
+
await writeFile(pendingOp.filePath, pendingOp.newContent);
|
|
389
|
+
}
|
|
390
|
+
const fileCount = pendingOp.pendingWrites?.length || 1;
|
|
380
391
|
return {
|
|
381
|
-
content: [{ type: "text", text: `Success. Changes applied to ${
|
|
392
|
+
content: [{ type: "text", text: `Success. Changes applied to ${fileCount} file(s).\n\nDiff:\n${pendingOp.diff}` }],
|
|
382
393
|
};
|
|
383
394
|
}
|
|
384
395
|
// Phase 1: Dry-run
|
|
@@ -391,6 +402,7 @@ async function handleTwoPhaseWrite(args, operationName, executeWrite) {
|
|
|
391
402
|
symbolName: args.symbolName ? String(args.symbolName) : undefined,
|
|
392
403
|
newContent: result.newContent,
|
|
393
404
|
diff: result.diff,
|
|
405
|
+
pendingWrites: result.pendingWrites,
|
|
394
406
|
});
|
|
395
407
|
return {
|
|
396
408
|
content: [{
|
|
@@ -503,6 +515,20 @@ async function handleGetServerStats() {
|
|
|
503
515
|
// -----------------------------------------------------------------------------
|
|
504
516
|
// PIPELINE & MAIN EXECUTION
|
|
505
517
|
// -----------------------------------------------------------------------------
|
|
518
|
+
/**
|
|
519
|
+
* Redact sensitive fields from args before audit logging.
|
|
520
|
+
* Prevents newContent/code from being persisted in plain text.
|
|
521
|
+
*/
|
|
522
|
+
function redactSensitiveFields(args) {
|
|
523
|
+
const SENSITIVE_KEYS = ["newContent", "code", "content"];
|
|
524
|
+
const safe = { ...args };
|
|
525
|
+
for (const key of SENSITIVE_KEYS) {
|
|
526
|
+
if (key in safe && typeof safe[key] === "string") {
|
|
527
|
+
safe[key] = `[REDACTED: ${safe[key].length} chars]`;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return safe;
|
|
531
|
+
}
|
|
506
532
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
507
533
|
const { name, arguments: args } = request.params;
|
|
508
534
|
const startTime = Date.now();
|
|
@@ -511,13 +537,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
511
537
|
try {
|
|
512
538
|
// 1. Rate Limiting Middleware
|
|
513
539
|
const cost = OPERATION_COSTS[name] ?? 1;
|
|
514
|
-
|
|
540
|
+
// Use global bucket — MCP stdio has 1 client per connection
|
|
541
|
+
const rateCheck = await rateLimiter.checkLimit("global", cost);
|
|
515
542
|
if (!rateCheck.allowed) {
|
|
516
543
|
throw new Error(`Rate limit exceeded for tool: ${name}. Retry after ${rateCheck.retryAfter}ms`);
|
|
517
544
|
}
|
|
518
545
|
// 2. File Locking Middleware (for writes only)
|
|
519
546
|
if (WRITE_OPS.has(name) && args && args.filePath) {
|
|
520
|
-
await globalLockManager.acquireLock(String(args.filePath), "mcp-client", name);
|
|
547
|
+
const lockResult = await globalLockManager.acquireLock(String(args.filePath), "mcp-client", name);
|
|
548
|
+
if (!lockResult.acquired) {
|
|
549
|
+
throw new Error(`File is locked: ${lockResult.error}`);
|
|
550
|
+
}
|
|
521
551
|
}
|
|
522
552
|
// 3. Execution
|
|
523
553
|
let result;
|
|
@@ -582,10 +612,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
582
612
|
}
|
|
583
613
|
// 5. Telemetry & Audit Logging Middleware
|
|
584
614
|
globalTelemetry.recordOperation({ toolName: name, duration, success });
|
|
615
|
+
// Redact sensitive fields (newContent, code) from audit log
|
|
616
|
+
const safeDetails = args ? redactSensitiveFields(args) : {};
|
|
585
617
|
globalAuditLogger.log({
|
|
586
618
|
level: success ? "info" : "error",
|
|
587
619
|
operation: name,
|
|
588
|
-
details:
|
|
620
|
+
details: safeDetails,
|
|
589
621
|
result: success ? "success" : "failure"
|
|
590
622
|
});
|
|
591
623
|
}
|