UNPKG

sofya.transcription

Version:

a JavaScript library that provides a robust and flexible solution for real-time audio transcription. It is designed to transcribe audio streams and can be easily integrated into web applications.

157 lines 6.26 kB
"use strict"; /** * Security validation utilities for WebSocket connections. * Provides protection against injection attacks and ensures URL safety. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.WebSocketSecurityValidator = void 0; /** * Malicious patterns to detect in query parameter values */ var MALICIOUS_PATTERNS = [ /[\x00\n\r\t]/, // Control characters /<script/i, // XSS attempts /javascript:/i, // JS protocol /on\w+\s*=/i, // Event handlers (onClick, etc) /[';"]\.*?(DROP|DELETE|INSERT|UPDATE|UNION|SELECT)/i // SQL injection ]; /** * Sensitive keys that should trigger security warnings */ var SENSITIVE_KEYS = [ 'token', 'password', 'secret', 'api_key', 'apikey', 'auth', 'credential', 'pass', 'key', 'bearer' ]; /** * Internal parameters that always take precedence */ var INTERNAL_PARAMS = [ 'transcription_language', 'translation_language' ]; /** * Validation limits */ var LIMITS = { keyPattern: /^[a-zA-Z0-9_-]+$/, maxValueLength: 1000, maxUrlLength: 2000 }; /** * WebSocket security validator class */ var WebSocketSecurityValidator = /** @class */ (function () { function WebSocketSecurityValidator() { this.rules = { keyPattern: LIMITS.keyPattern, maxValueLength: LIMITS.maxValueLength, maxUrlLength: LIMITS.maxUrlLength, internalParams: INTERNAL_PARAMS, sensitiveKeys: SENSITIVE_KEYS }; } /** * Validates a query parameter key * @param key - The key to validate * @throws Error if key format is invalid */ WebSocketSecurityValidator.prototype.validateQueryParamKey = function (key) { if (!this.rules.keyPattern.test(key)) { throw new Error("Invalid queryParam key: \"".concat(key, "\". Keys must match ").concat(this.rules.keyPattern.toString())); } }; /** * Validates a query parameter value * @param key - The parameter key (for error messages) * @param value - The value to validate * @throws Error if value is too long or contains malicious patterns */ WebSocketSecurityValidator.prototype.validateQueryParamValue = function (key, value) { // Check length if (value.length > this.rules.maxValueLength) { throw new Error("queryParam value for key \"".concat(key, "\" exceeds ").concat(this.rules.maxValueLength, " characters")); } // Check for malicious patterns for (var _i = 0, MALICIOUS_PATTERNS_1 = MALICIOUS_PATTERNS; _i < MALICIOUS_PATTERNS_1.length; _i++) { var pattern = MALICIOUS_PATTERNS_1[_i]; if (pattern.test(value)) { throw new Error("Malicious pattern detected in queryParam value for key \"".concat(key, "\"")); } } }; /** * Warns if sensitive keys are detected in query parameters * @param keys - Array of parameter keys to check */ WebSocketSecurityValidator.prototype.warnSensitiveKeys = function (keys) { var _this = this; var foundSensitiveKeys = keys.filter(function (key) { return _this.rules.sensitiveKeys.some(function (sensitive) { return key.toLowerCase().includes(sensitive); }); }); if (foundSensitiveKeys.length > 0) { console.warn('⚠️ Security Warning: Potentially sensitive data detected in queryParams. ' + 'Query parameters are visible in logs. Consider using protocols instead.'); } }; /** * Checks if the final WebSocket URL exceeds maximum length * @param url - The URL to check * @throws Error if URL is too long */ WebSocketSecurityValidator.prototype.checkUrlLength = function (url) { if (url.length > this.rules.maxUrlLength) { throw new Error("WebSocket URL exceeds ".concat(this.rules.maxUrlLength, " characters (current: ").concat(url.length, "). ") + 'Reduce queryParams or use protocols.'); } }; /** * Detects collision between custom params and internal params * @param customParams - Custom query parameters * @returns Object with validated params (internal params removed) and collision warnings */ WebSocketSecurityValidator.prototype.detectCollisions = function (customParams) { var validatedParams = {}; var collisions = []; for (var _i = 0, _a = Object.entries(customParams); _i < _a.length; _i++) { var _b = _a[_i], key = _b[0], value = _b[1]; if (this.rules.internalParams.includes(key)) { collisions.push(key); } else { validatedParams[key] = value; } } // Warn about collisions if (collisions.length > 0) { collisions.forEach(function (key) { var suggestion = key === 'transcription_language' ? 'config.language' : 'config.translation_lang'; console.warn("Custom queryParams ".concat(key, " ignored - use ").concat(suggestion, " instead.")); }); } return { validatedParams: validatedParams, collisions: collisions }; }; /** * Validates all query parameters * @param queryParams - Query parameters to validate * @returns Validated parameters (with internal params removed) * @throws Error if any validation fails */ WebSocketSecurityValidator.prototype.validateQueryParams = function (queryParams) { // Warn about sensitive keys this.warnSensitiveKeys(Object.keys(queryParams)); // Detect and handle collisions var validatedParams = this.detectCollisions(queryParams).validatedParams; // Validate each key-value pair for (var _i = 0, _a = Object.entries(validatedParams); _i < _a.length; _i++) { var _b = _a[_i], key = _b[0], value = _b[1]; this.validateQueryParamKey(key); this.validateQueryParamValue(key, value); } return validatedParams; }; return WebSocketSecurityValidator; }()); exports.WebSocketSecurityValidator = WebSocketSecurityValidator; //# sourceMappingURL=websocketSecurity.js.map