@@ -291,6 +291,46 @@ def validate_database(self) -> None:
291
291
if not db_dir .exists ():
292
292
db_dir .mkdir (parents = True )
293
293
294
+ # Validation patterns for safe display (configurable)
295
+ validation_dangerous_html_pattern : str = r"<(script|iframe|object|embed|link|meta|base|form)\b|</*(script|iframe|object|embed|link|meta|base|form)>"
296
+ validation_dangerous_js_pattern : str = r"javascript:|vbscript:|on\w+\s*=|data:.*script"
297
+ validation_allowed_url_schemes : List [str ] = ["http://" , "https://" , "ws://" , "wss://" ]
298
+
299
+ # Character validation patterns
300
+ validation_name_pattern : str = r"^[a-zA-Z0-9_\-\s]+$" # Allow spaces for names
301
+ validation_identifier_pattern : str = r"^[a-zA-Z0-9_\-\.]+$" # No spaces for IDs
302
+ validation_safe_uri_pattern : str = r"^[a-zA-Z0-9_\-.:/?=&%]+$"
303
+ validation_unsafe_uri_pattern : str = r'[<>"\'\\]'
304
+ validation_tool_name_pattern : str = r"^[a-zA-Z][a-zA-Z0-9_-]*$" # MCP tool naming
305
+
306
+ # MCP-compliant size limits (configurable via env)
307
+ validation_max_name_length : int = 255
308
+ validation_max_description_length : int = 4096
309
+ validation_max_template_length : int = 65536 # 64KB
310
+ validation_max_content_length : int = 1048576 # 1MB
311
+ validation_max_json_depth : int = 10
312
+ validation_max_url_length : int = 2048
313
+ validation_max_rpc_param_size : int = 262144 # 256KB
314
+
315
+ # Allowed MIME types
316
+ validation_allowed_mime_types : List [str ] = [
317
+ "text/plain" ,
318
+ "text/html" ,
319
+ "text/css" ,
320
+ "text/javascript" ,
321
+ "application/json" ,
322
+ "application/xml" ,
323
+ "application/pdf" ,
324
+ "image/png" ,
325
+ "image/jpeg" ,
326
+ "image/gif" ,
327
+ "image/svg+xml" ,
328
+ "application/octet-stream" ,
329
+ ]
330
+
331
+ # Rate limiting
332
+ validation_max_requests_per_minute : int = 60
333
+
294
334
295
335
def extract_using_jq (data , jq_filter = "" ):
296
336
"""
0 commit comments