Use with caution. Address findings before production.
Scanned 5/3/2026, 6:48:39 PM·Cached result·Fast Scan·45 rules·How we decide ↗
AIVSS Score
Medium
Severity Breakdown
0
critical
19
high
115
medium
3
low
MCP Server Information
Findings
This package presents significant security concerns with a C grade and 60/100 safety score, driven primarily by 19 high-severity findings including insecure deserialization vulnerabilities and 70 server configuration issues that could expose it to attacks. The 20 ANSI escape injection vulnerabilities and 21 resource exhaustion risks suggest inadequate input validation and resource management, making it unsuitable for production use without substantial remediation. You should request security fixes from the maintainers or consider alternative packages before installation.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 37 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasn’t shipped yet.
Showing 1–30 of 37 findings
37 findings
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 360 | // Parse YAML |
| 361 | let parsed: any; |
| 362 | try { |
| 363 | parsed = yaml.load(data, { |
| 364 | schema: yamlSchema, |
| 365 | json: false, |
| 366 | onWarning: (warning: any) => { |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 720 | // Read file content |
| 721 | const content = await this.fileOperations.readFile(filePath, { source: 'PortfolioIndexManager.createMemoryIndexEntry' }); |
| 722 | |
| 723 | // FIX #1196: Parse pure YAML using yaml.load() |
| 724 | // Memory files are pure YAML without frontmatter markers, so we can't use SecureYamlParser |
| 725 | // (which is designed for Markdown files with YAML frontmatter between --- markers) |
| 726 | // Using FAILSAFE_SCHEMA for security (same as MemoryManager uses) |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 79 | // Use preserved metadata for perfect roundtrip |
| 80 | const preservedYAML = skillData.metadata.get('dollhouse.yaml')!; |
| 81 | // FIX (DMCP-SEC-005): Use CORE_SCHEMA to prevent YAML deserialization attacks |
| 82 | enrichedMetadata = yaml.load(preservedYAML, { schema: yaml.CORE_SCHEMA }) as DollhouseMCPSkillMetadata; |
| 83 | // Apply any custom metadata overrides |
| 84 | if (options?.customMetadata) { |
| 85 | Object.assign(enrichedMetadata, options.customMetadata); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 1484 | } else if (exportPackage.format === 'yaml') { |
| 1485 | // SECURITY: Use JSON_SCHEMA for pure YAML parsing (prevents code execution) |
| 1486 | // JSON_SCHEMA = FAILSAFE + bool/int/float/null (safer than DEFAULT which adds timestamps) |
| 1487 | const parsed = yaml.load(exportPackage.data, { schema: yaml.JSON_SCHEMA }); |
| 1488 | if (typeof parsed !== 'object' || parsed === null) { |
| 1489 | throw new Error('Invalid YAML data: expected object'); |
| 1490 | } |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 228 | } |
| 229 | |
| 230 | // FIX (DMCP-SEC-005): Use CORE_SCHEMA to prevent YAML deserialization attacks |
| 231 | const metadata = yaml.load(yamlMatch[1], { schema: yaml.CORE_SCHEMA }) as DollhouseMCPSkillMetadata; |
| 232 | const bodyContent = yamlMatch[2]; |
| 233 | |
| 234 | return { metadata, bodyContent }; |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 136 | findings.push(...this.evaluateConfigObject(parsed, filePath)); |
| 137 | } else if (extension === '.yml' || extension === '.yaml') { |
| 138 | // Use FAILSAFE_SCHEMA for safe YAML parsing (no arbitrary object instantiation) |
| 139 | const parsed = yaml.load(content, { schema: yaml.FAILSAFE_SCHEMA }) as ConfigObject; |
| 140 | if (parsed && typeof parsed === 'object') { |
| 141 | findings.push(...this.evaluateConfigObject(parsed, filePath)); |
| 142 | } |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 310 | */ |
| 311 | static readPortFromYaml(yamlContent: string): number | undefined { |
| 312 | try { |
| 313 | const parsed = yaml.load(yamlContent, { schema: yaml.FAILSAFE_SCHEMA }) as Record<string, any> | null; |
| 314 | const raw = parsed?.console?.port; |
| 315 | if (raw === undefined || raw === null) return undefined; |
| 316 | const port = Number(raw); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 494 | const content = await this.fileOperations.readFile(filePath, { source: 'SubmitToPortfolioTool.extractElementMetadata' }); |
| 495 | |
| 496 | // SECURITY FIX: Use SecureYamlParser to prevent YAML deserialization attacks |
| 497 | // Previously would have used: yaml.load(yamlContent) which is vulnerable |
| 498 | // Now: Uses SecureYamlParser.parse() which validates and sanitizes |
| 499 | try { |
| 500 | const parsed = SecureYamlParser.parse(content, { |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 731 | return null; |
| 732 | } |
| 733 | |
| 734 | const rawParsed = yaml.load(content, { |
| 735 | schema: yaml.FAILSAFE_SCHEMA |
| 736 | }); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 367 | } |
| 368 | |
| 369 | // FIX (DMCP-SEC-005): Use CORE_SCHEMA to prevent YAML deserialization attacks |
| 370 | const metadata = yaml.load(yamlMatch[1], { schema: yaml.CORE_SCHEMA }) as AnthropicSkillMetadata; |
| 371 | const content = yamlMatch[2].trim(); |
| 372 | |
| 373 | return { metadata, content }; |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 168 | // 5. Parse with safe schema |
| 169 | let data: any; |
| 170 | try { |
| 171 | data = yaml.load(yamlContent, { |
| 172 | schema: this.SAFE_SCHEMA, |
| 173 | json: false, // Don't allow JSON-specific types |
| 174 | onWarning: (warning) => { |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 557 | let loadedData: any; |
| 558 | try { |
| 559 | // Using yaml with FAILSAFE_SCHEMA is secure - prevents code execution |
| 560 | loadedData = yaml.load(content, { |
| 561 | schema: yaml.FAILSAFE_SCHEMA // Safe schema prevents code execution |
| 562 | }); |
| 563 | } catch (yamlError) { |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 83 | try { |
| 84 | // Use safe load with restricted schema |
| 85 | const rawData = yaml.load(yamlContent, { |
| 86 | schema: yaml.CORE_SCHEMA, // No functions, only basic types |
| 87 | onWarning: (warning) => { |
| 88 | logger.warn('YAML parsing warning:', warning); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 225 | } |
| 226 | ): DollhouseMCPSkillMetadata { |
| 227 | // FIX (DMCP-SEC-005): Use CORE_SCHEMA to prevent YAML deserialization attacks |
| 228 | const enrichedMetadata = yaml.load(preservedYAML, { schema: yaml.CORE_SCHEMA }) as DollhouseMCPSkillMetadata; |
| 229 | |
| 230 | // Apply any custom metadata overrides |
| 231 | if (options?.customMetadata) { |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 192 | const content = await this.fileOperations.readFile(this.capabilityIndexPath, { |
| 193 | source: 'CapabilityIndexResource.loadCapabilityIndex' |
| 194 | }); |
| 195 | const parsed = yaml.load(content, { schema: yaml.FAILSAFE_SCHEMA }) as CapabilityIndex; |
| 196 | |
| 197 | // Cache the result |
| 198 | this.cachedIndex = parsed; |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 872 | // Try parsing as YAML |
| 873 | try { |
| 874 | const parsed = yaml.load(trimmed, { |
| 875 | schema: yaml.FAILSAFE_SCHEMA, |
| 876 | json: false |
| 877 | }); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 31 | ### YAML Parsing |
| 32 | |
| 33 | **Always use `SecureYamlParser`** - never use `yaml.load()` directly. |
| 34 | |
| 35 | ```typescript |
| 36 | // For markdown with frontmatter (personas, skills, templates) |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 345 | } |
| 346 | |
| 347 | // Parse with safe schema |
| 348 | const parsed = yaml.load(yamlContent, { |
| 349 | schema: this.SAFE_SCHEMA, // CORE_SCHEMA - safe basic types only |
| 350 | json: false |
| 351 | }); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Unsafe deserialization primitive detected. pickle.load(s), yaml.load (without SafeLoader), marshal.load(s), and shelve.open execute arbitrary code when the input is attacker-controlled.
Evidence
| 286 | yaml: { |
| 287 | parse: (str: string) => { |
| 288 | // Use our secure YAML parsing |
| 289 | const parsed = yaml.load(str, { |
| 290 | schema: this.SAFE_SCHEMA, |
| 291 | json: false |
| 292 | }); |
Remediation
Replace pickle with json/msgpack or a schema-validated format (protobuf, cap'n proto). Use yaml.safe_load instead of yaml.load. Never deserialize data from an untrusted source with these APIs.
Weak authentication primitive detected. MD5/SHA-1 are not password hashes — they are fast, GPU-accelerated, and unsalted by default. Use bcrypt (≥12 rounds), argon2id, or scrypt for passwords.
Evidence
| 120 | }); |
| 121 | } |
| 122 | |
| 123 | const hash = crypto.createHash('md5') |
| 124 | .update(normalized.normalizedContent) |
| 125 | .digest(); |
| 126 | const hashInt = hash.readUInt32BE(0); |
Remediation
Use bcrypt (rounds >= 12), argon2id (preferred), or scrypt for password storage. Never pass a password into hashlib.md5/sha1 or crypto.createHash("md5"|"sha1").
Container base image uses the floating :latest tag. This provides no reproducibility — the image content can change under you, and there is no signature to verify.
Evidence
| 1 | # Minimal test Dockerfile - just echo hello and exit |
| 2 | # Using busybox instead of alpine to avoid rate limit issues |
| 3 | FROM busybox:latest |
| 4 | CMD ["echo", "Hello from minimal Docker test!"] |
Remediation
Pin the base image by digest (e.g. python@sha256:...) or at minimum an exact semver tag (e.g. python:3.12.4-slim-bookworm). Never use :latest in production Dockerfiles.
Dockerfile never sets a non-root `USER` directive, so the CMD runs as root by default. Any RCE or library-level vulnerability exploited inside this container gets full privileges (MCP Top-10 R3). Add `USER <non-root>` before CMD / ENTRYPOINT in the final stage — e.g. `USER 1000`, `USER nobody`, or `USER nonroot` on distroless.
Evidence
| 1 | # CI Simulation Dockerfile |
| 2 | # Purpose: Create constrained container environments matching GitHub Actions runner specs |
| 3 | # for local performance calibration and CI prediction |
| 4 | |
| 5 | # Base image matching GitHub Actions ubuntu-latest Node 20 environment |
| 6 | FROM node:20-slim AS ci-base |
| 7 | |
| 8 | # Install minimal dependencies matching GitHub Actions environment |
| 9 | RUN apt-get update && apt-get install -y --no-install-recommends \ |
| 10 | python3 \ |
| 11 | make \ |
| 12 | g++ \ |
| 13 | ca-certificates \ |
| 14 | && rm -rf /var/lib/apt/lists/* |
| 15 | |
| 16 |
Remediation
Create and switch to a non-root user before the CMD / ENTRYPOINT: RUN adduser --system --uid 1000 app USER 1000 Or reuse the base image's shipped non-root account (e.g. `USER nobody`, `USER nonroot` on distroless). Multi-stage builds only need the USER directive in the final stage.
Dockerfile never sets a non-root `USER` directive, so the CMD runs as root by default. Any RCE or library-level vulnerability exploited inside this container gets full privileges (MCP Top-10 R3). Add `USER <non-root>` before CMD / ENTRYPOINT in the final stage — e.g. `USER 1000`, `USER nobody`, or `USER nonroot` on distroless.
Evidence
| 1 | # Minimal test Dockerfile - just echo hello and exit |
| 2 | # Using busybox instead of alpine to avoid rate limit issues |
| 3 | FROM busybox:latest |
| 4 | CMD ["echo", "Hello from minimal Docker test!"] |
Remediation
Create and switch to a non-root user before the CMD / ENTRYPOINT: RUN adduser --system --uid 1000 app USER 1000 Or reuse the base image's shipped non-root account (e.g. `USER nobody`, `USER nonroot` on distroless). Multi-stage builds only need the USER directive in the final stage.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 172 | // ---------- Step 1: initial status ---------- |
| 173 | section('Step 1: initial status (should be not-enrolled)'); |
| 174 | const initialStatus = await apiCall('GET', '/api/console/totp/status', token); |
| 175 | console.log(JSON.stringify(initialStatus.body, null, 2)); |
| 176 | checkOk('GET /status returned 200', () => assert.strictEqual(initialStatus.status, 200)); |
| 177 | checkOk('status reports enrolled=false before enrollment', () => |
| 178 | assert.strictEqual((initialStatus.body as { enrolled: boolean }).enrolled, |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 281 | * const result = queryService.query(items, userOptions); |
| 282 | * } catch (error) { |
| 283 | * // Options are invalid, show error to user |
| 284 | * console.error('Invalid query options:', error.message); |
| 285 | * } |
| 286 | * ``` |
| 287 | */ |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 146 | const match = response.match(/SELECTED: ([\\w-]+)/); |
| 147 | const selected = match ? match[1] : null; |
| 148 | |
| 149 | console.log(JSON.stringify({ |
| 150 | variation: '${variationId}', |
| 151 | query: '${query.query}', |
| 152 | selected: selected, |
| 153 | expected: '${query.expected}', |
| 154 | correct: selected === '${query.expected}' |
| 155 | })); |
| 156 | ` |
| 157 | ]); |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 254 | // ---------- Step 5: status reflects enrollment ---------- |
| 255 | section('Step 5: status reflects enrollment'); |
| 256 | const enrolledStatus = await apiCall('GET', '/api/console/totp/status', token); |
| 257 | console.log(JSON.stringify(enrolledStatus.body, null, 2)); |
| 258 | checkOk('GET /status returned 200', () => assert.strictEqual(enrolledStatus.status, 200)); |
| 259 | checkOk('status reports enrolled=true after enrollment', () => |
| 260 | assert.strictEqual((enrolledStatus.body as { enrolled: boolean }).enrolled |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 69 | // Length check to prevent DOS |
| 70 | if (input.length > maxLength) { |
| 71 | console.warn(`[SafeRegex] Input too long (${input.length} > ${maxLength}) in ${context}`); |
| 72 | return false; |
| 73 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 285 | // ---------- Step 7: final status ---------- |
| 286 | section('Step 7: status reflects disable'); |
| 287 | const finalStatus = await apiCall('GET', '/api/console/totp/status', token); |
| 288 | console.log(JSON.stringify(finalStatus.body, null, 2)); |
| 289 | checkOk('GET /status returned 200', () => assert.strictEqual(finalStatus.status, 200)); |
| 290 | checkOk('status reports enrolled=false after disable', () => |
| 291 | assert.strictEqual((finalStatus.body as { enrolled: boolean }).enrolled, false), |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 55 | if (currentPhase < phases.length) { |
| 56 | const phase = phases[currentPhase]; |
| 57 | console.error(`📤 Phase ${phase.id}: ${phase.name}`); |
| 58 | console.log(JSON.stringify(phase.request)); |
| 59 | currentPhase++; |
| 60 | } else { |
| 61 | // All done |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 34 | ); |
| 35 | console.log(initialCheck); |
| 36 | |
| 37 | console.log("\n3. Sending MCP tool request to trigger index..."); |
| 38 | |
| 39 | // Create an MCP request to list_elements (simple tool that should trigger index) |
| 40 | const mcpRequest = JSON.stringify({ |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 160 | * }); |
| 161 | * |
| 162 | * if (result.isValid) { |
| 163 | * console.log('Clean input:', result.sanitizedValue); |
| 164 | * } else { |
| 165 | * console.error('Validation failed:', result.errors); |
| 166 | * } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 249 | // Handle directories |
| 250 | if (!fs.statSync(input).isDirectory()) { |
| 251 | console.error(chalk.red(`Input must be a directory or ZIP file: ${input}`)); |
| 252 | process.exit(1); |
| 253 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 98 | * ```typescript |
| 99 | * const result = normalizer.normalize({ query: 'test' }, context); |
| 100 | * if (result.success) { |
| 101 | * console.log(result.params); // Transformed params |
| 102 | * } else { |
| 103 | * console.error(result.error); // Validation error message |
| 104 | * } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1930 | btn.classList.toggle('active', on); |
| 1931 | btn.setAttribute('aria-pressed', on); |
| 1932 | }); |
| 1933 | try { localStorage.setItem('collection-view', view); } catch {} |
| 1934 | } |
| 1935 | |
| 1936 | applyView(activeView); |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1903 | const hljsDark = document.getElementById('hljs-theme-dark'); |
| 1904 | if (hljsLight) hljsLight.disabled = isDark; |
| 1905 | if (hljsDark) hljsDark.disabled = !isDark; |
| 1906 | try { localStorage.setItem('color-scheme', theme); } catch {} |
| 1907 | } |
| 1908 | |
| 1909 | // Restore saved preference; fall back to OS preference |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 1907 | } |
| 1908 | |
| 1909 | // Restore saved preference; fall back to OS preference |
| 1910 | const saved = (() => { try { return localStorage.getItem('color-scheme'); } catch {} })(); |
| 1911 | const preferred = saved || (globalThis.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); |
| 1912 | applyTheme(preferred); |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.