/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DOCUMENTATION_PATH_NAMES } from '../constants.js';
/**
* Security configuration for the MCP server
* Following OWASP Input Validation guidelines
*/
export interface SecurityConfig {
input: {
query: {
maxLength: number;
minLength: number;
allowedPattern: RegExp;
};
documentReference: {
maxLength: number;
allowedExtensions: string[];
allowedPattern: RegExp;
preventTraversal: boolean;
};
maxResults: {
min: number;
max: number;
default: number;
};
documentationPath: {
maxItems: number;
allowedValues: string[];
};
};
output: {
maxResponseSize: number;
enableJsonSanitization: boolean;
};
security: {
enableRequestLogging: boolean;
logSecurityEvents: boolean;
strictModeEnabled: boolean;
};
}
export const DEFAULT_SECURITY_CONFIG: SecurityConfig = {
input: {
query: {
maxLength: 1000,
minLength: 1,
// Allow alphanumeric, spaces, and common punctuation - OWASP allowlist approach
allowedPattern: /^[a-zA-Z0-9\s\-_.,!?'"()\[\]{}:;@#$%&*+=<>\/\\]+$/,
},
documentReference: {
maxLength: 255,
allowedExtensions: ['.md'],
// Path-safe characters including spaces - prevent traversal attacks
allowedPattern: /^[a-zA-Z0-9\s\-_.\/]+$/,
preventTraversal: true,
},
maxResults: {
min: 1,
max: 100,
default: 5,
},
documentationPath: {
maxItems: 10,
allowedValues: [...DOCUMENTATION_PATH_NAMES],
},
},
output: {
maxResponseSize: 10 * 1024 * 1024, // 10MB max response
enableJsonSanitization: true,
},
security: {
enableRequestLogging: true,
logSecurityEvents: true,
strictModeEnabled: true,
},
};
/**
* Get security configuration with optional overrides
*/
export function getSecurityConfig(overrides?: Partial<SecurityConfig>): SecurityConfig {
if (!overrides) {
return DEFAULT_SECURITY_CONFIG;
}
return {
...DEFAULT_SECURITY_CONFIG,
...overrides,
input: {
...DEFAULT_SECURITY_CONFIG.input,
...overrides.input,
},
output: {
...DEFAULT_SECURITY_CONFIG.output,
...overrides.output,
},
security: {
...DEFAULT_SECURITY_CONFIG.security,
...overrides.security,
},
};
}