|
7 | 7 |
|
8 | 8 | import initSqlJs from 'sql.js'; |
9 | 9 | import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs'; |
10 | | -import { dirname, join, basename } from 'path'; |
| 10 | +import { dirname, join, basename, resolve } from 'path'; |
11 | 11 | import { fileURLToPath } from 'url'; |
12 | 12 | import { execSync } from 'child_process'; |
13 | 13 |
|
@@ -154,7 +154,19 @@ function countFilesAndLines(dir, ext = '.ts') { |
154 | 154 | try { |
155 | 155 | const entries = readdirSync(currentDir, { withFileTypes: true }); |
156 | 156 | for (const entry of entries) { |
| 157 | + // Validate entry name to prevent path traversal |
| 158 | + if (entry.name.includes('..') || entry.name.includes('/') || entry.name.includes('\\')) { |
| 159 | + continue; |
| 160 | + } |
| 161 | + |
157 | 162 | const fullPath = join(currentDir, entry.name); |
| 163 | + // Additional validation: ensure resolved path is within the base directory |
| 164 | + const resolvedPath = resolve(fullPath); |
| 165 | + const resolvedCurrentDir = resolve(currentDir); |
| 166 | + if (!resolvedPath.startsWith(resolvedCurrentDir)) { |
| 167 | + continue; // Path traversal attempt detected |
| 168 | + } |
| 169 | + |
158 | 170 | if (entry.isDirectory() && !entry.name.includes('node_modules')) { |
159 | 171 | walk(fullPath); |
160 | 172 | } else if (entry.isFile() && entry.name.endsWith(ext)) { |
@@ -209,7 +221,20 @@ function calculateModuleProgress(moduleDir) { |
209 | 221 | * Check security file status |
210 | 222 | */ |
211 | 223 | function checkSecurityFile(filename, minLines = 100) { |
| 224 | + // Validate filename to prevent path traversal |
| 225 | + if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) { |
| 226 | + return false; |
| 227 | + } |
| 228 | + |
212 | 229 | const filePath = join(V3_DIR, '@claude-flow/security/src', filename); |
| 230 | + |
| 231 | + // Additional validation: ensure resolved path is within the expected directory |
| 232 | + const resolvedPath = resolve(filePath); |
| 233 | + const expectedDir = resolve(join(V3_DIR, '@claude-flow/security/src')); |
| 234 | + if (!resolvedPath.startsWith(expectedDir)) { |
| 235 | + return false; // Path traversal attempt detected |
| 236 | + } |
| 237 | + |
213 | 238 | if (!existsSync(filePath)) return false; |
214 | 239 |
|
215 | 240 | try { |
|
0 commit comments