mcp-context-forge icon indicating copy to clipboard operation
mcp-context-forge copied to clipboard

Feature-221 : Gateway-Level Input Validation & Output Sanitization

Open nmveeresh opened this issue 1 week ago โ€ข 0 comments

Gateway-Level Input Validation & Output Sanitization

Closes https://github.com/IBM/mcp-context-forge/issues/221

๐Ÿ”’ Security Enhancement

This PR introduces a comprehensive security layer for input validation and output sanitization within the MCP Gateway, significantly reducing the attack surface for path traversal, command injection, and control-character exploits.


๐ŸŽฏ Key Features

1. Path Traversal Defense

  • Normalizes all paths using secure resolvers.
  • Enforces confinement to declared root directories.
  • Blocks attempts like:
    • ../../../etc/passwd
    • ......\windows\system32

2. Parameter Validation

  • Detects and rejects:
  • Shell metacharacters
  • SQL injection patterns
  • XSS-oriented strings
  • Unsafe URLs (javascript:)
  • Control characters (0x00โ€“0x1F, 0x7Fโ€“0x9F)

3. Output Sanitization

  • Removes unsafe control characters before delivering responses.
  • Validates MIME types and prevents malicious payloads.

4. Configurable Security Modes

  • Fully feature-flagged via:
  • EXPERIMENTAL_VALIDATE_IO
  • Strict vs warn mode
  • Sanitization toggle

5. System-Wide Coverage

  • New validation middleware applied early in request lifecycle.
  • Safe wrapper for subprocess execution.
  • Updated resource service path normalization.
  • Sanitization pipeline for responses.

๐Ÿ› ๏ธ Implementation Details

New Components

  • Request validation middleware
  • Secure path normalization utility
  • Sanitized response generator
  • Safe subprocess command executor

Updated Components

  • Resource service
  • Tool execution pipeline
  • Global configuration manager

๐Ÿ”ง Configuration Added (in .env)

EXPERIMENTAL_VALIDATE_IO=false
VALIDATION_MIDDLEWARE_ENABLED=false
VALIDATION_STRICT=false
SANITIZE_OUTPUT=false
ALLOWED_ROOTS=[]
MAX_PATH_DEPTH=10
MAX_PARAM_LENGTH=10000
DANGEROUS_PATTERNS=[
"[;&|`$(){}\\[\\]<>]",
"\\.\\.[/\\\\]",
"[\\x00-\\x1f\\x7f-\\x9f]"
]

๐ŸŽฏ Security Impact


Prevents:

  • Directory traversal
  • Shell/command injection
  • SQL injection attempts
  • XSS injection into tool metadata
  • Malicious binary/control-character output

Benefits:

  • Stronger baseline security posture
  • Consistent validation across the entire gateway
  • Clean and predictable output guarantees -Foundation for future MCP spec hardening

๐Ÿ›ก๏ธ Quick Security Validation Tests

Essential attack patterns that MUST be blocked by the Gateway.


Export the environment variables

Run this in your terminal:

export EXPERIMENTAL_VALIDATE_IO=false
export VALIDATION_MIDDLEWARE_ENABLED=false
export VALIDATION_STRICT=false
export SANITIZE_OUTPUT=false

If false โ†’ validation disabled, tests will execute normally If true โ†’ validation enabled, tests will block invalid inputs

๐Ÿงช Test Script

#!/bin/bash
# Quick security validation tests - Essential attacks that MUST be blocked

BASE_URL="http://localhost:4444"
TOKEN="Paste your token here"

check_blocked() {
    if echo "$1" | grep -Eq "Parameter .* contains dangerous characters"; then
        echo "โœ”๏ธ  BLOCKED as expected"
    else
        echo "โŒ  ERROR: Should have been BLOCKED"
    fi
}

check_allowed() {
    # Check for "id" in response, which indicates successful tool creation
    if echo "$1" | grep -q "\"id\""; then
        echo "โœ”๏ธ  ALLOWED as expected"
    else
        echo "โŒ  ERROR: Should have been ALLOWED"
    fi
}

echo "๐Ÿ›ก๏ธ  Quick Security Test - Essential Validations"
echo "==============================================="

# Test 1: Path Traversal
echo "๐Ÿ”’ Test 1: Path Traversal Attack"
resp=$(curl -s -X POST "$BASE_URL/resources" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"uri": "../../../etc/passwd", "name": "test_traversal"}')
echo "$resp" | jq .
check_blocked "$resp"
echo ""

# Test 2: Shell Injection
echo "๐Ÿ”’ Test 2: Shell Injection Attack"
resp=$(curl -s -X POST "$BASE_URL/tools" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "test_shell", "command": "ls && cat /etc/passwd"}')
echo "$resp" | jq .
check_blocked "$resp"
echo ""

# Test 3: SQL Injection
echo "๐Ÿ”’ Test 3: SQL Injection Attack"
resp=$(curl -s -X POST "$BASE_URL/tools" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "test_sql", "description": "'"'"'; DROP TABLE users; --"}')
echo "$resp" | jq .
check_blocked "$resp"
echo ""

# Test 4: XSS
echo "๐Ÿ”’ Test 4: XSS Attack"
resp=$(curl -s -X POST "$BASE_URL/tools" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "test_xss", "description": "<script>alert(1)</script>"}')
echo "$resp" | jq .
check_blocked "$resp"
echo ""

# Test 5: Dangerous URL
echo "๐Ÿ”’ Test 5: Dangerous URL"
resp=$(curl -s -X POST "$BASE_URL/tools" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "test_url", "url": "javascript:alert(1)"}')
echo "$resp" | jq .
check_blocked "$resp"
echo ""

# Test 6: Safe Command
echo "โœ… Test 6: Safe Command (should work)"
resp=$(curl -s -X POST "$BASE_URL/tools" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tool": {"name": "acss-tool232", "command": "echo hello world"}}')
echo "$resp" | jq .
check_allowed "$resp"
echo ""

echo "๐Ÿ Quick tests completed!"
echo "Expected: Tests 1-5 should be BLOCKED, Test 6 should PASS"

nmveeresh avatar Dec 02 '25 09:12 nmveeresh