mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 05:23:08 +00:00
security: fix CRITICAL timing attack and command injection vulnerabilities (Issue #265)
This commit addresses 2 critical security vulnerabilities identified in the security audit. ## CRITICAL-02: Timing Attack Vulnerability (CVSS 8.5) **Problem:** Non-constant-time string comparison in authentication allowed timing attacks to discover tokens character-by-character through statistical timing analysis (estimated 24-48 hours to compromise). **Fix:** Implemented crypto.timingSafeEqual for all token comparisons **Changes:** - Added AuthManager.timingSafeCompare() constant-time comparison utility - Fixed src/utils/auth.ts:27 - validateToken method - Fixed src/http-server-single-session.ts:1087 - Single-session HTTP auth - Fixed src/http-server.ts:315 - Fixed HTTP server auth - Added 11 unit tests with timing variance analysis (<10% variance proven) ## CRITICAL-01: Command Injection Vulnerability (CVSS 8.8) **Problem:** User-controlled nodeType parameter injected into shell commands via execSync, allowing remote code execution, data exfiltration, and network scanning. **Fix:** Eliminated all shell execution, replaced with Node.js fs APIs **Changes:** - Replaced execSync() with fs.readdir() in enhanced-documentation-fetcher.ts - Added multi-layer input sanitization: /[^a-zA-Z0-9._-]/g - Added directory traversal protection (blocks .., /, relative paths) - Added path.basename() for additional safety - Added final path verification (ensures result within expected directory) - Added 9 integration tests covering all attack vectors ## Test Results All Tests Passing: - Unit tests: 11/11 ✅ (timing-safe comparison) - Integration tests: 9/9 ✅ (command injection prevention) - Timing variance: <10% ✅ (proves constant-time) - All existing tests: ✅ (no regressions) ## Breaking Changes None - All changes are backward compatible. ## References - Security Audit: Issue #265 - Implementation Plan: docs/local/security-implementation-plan-issue-265.md - Audit Analysis: docs/local/security-audit-analysis-issue-265.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
|
||||
import { N8NDocumentationMCPServer } from './mcp/server';
|
||||
import { ConsoleManager } from './utils/console-manager';
|
||||
import { logger } from './utils/logger';
|
||||
import { AuthManager } from './utils/auth';
|
||||
import { readFileSync } from 'fs';
|
||||
import dotenv from 'dotenv';
|
||||
import { getStartupBaseUrl, formatEndpointUrls, detectBaseUrl } from './utils/url-detector';
|
||||
@@ -1080,15 +1081,19 @@ export class SingleSessionHTTPServer {
|
||||
|
||||
// Extract token and trim whitespace
|
||||
const token = authHeader.slice(7).trim();
|
||||
|
||||
// Check if token matches
|
||||
if (token !== this.authToken) {
|
||||
logger.warn('Authentication failed: Invalid token', {
|
||||
|
||||
// SECURITY: Use timing-safe comparison to prevent timing attacks
|
||||
// See: https://github.com/czlonkowski/n8n-mcp/issues/265 (CRITICAL-02)
|
||||
const isValidToken = this.authToken &&
|
||||
AuthManager.timingSafeCompare(token, this.authToken);
|
||||
|
||||
if (!isValidToken) {
|
||||
logger.warn('Authentication failed: Invalid token', {
|
||||
ip: req.ip,
|
||||
userAgent: req.get('user-agent'),
|
||||
reason: 'invalid_token'
|
||||
});
|
||||
res.status(401).json({
|
||||
res.status(401).json({
|
||||
jsonrpc: '2.0',
|
||||
error: {
|
||||
code: -32001,
|
||||
|
||||
Reference in New Issue
Block a user