From f7170cd6dfd2a4b6b5cbeb1b3a1c6d9e413bf77c Mon Sep 17 00:00:00 2001 From: KaifAhmad1 Date: Tue, 31 Mar 2026 15:20:07 +0530 Subject: [PATCH] fix(security): resolve CodeQL alerts #4, #5, #9, #10 - fix(redos) #10: replace capturing group with non-capturing group in naming_conventions.py to eliminate exponential backtracking (py/redos) - fix(html-filter) #4: update script/iframe end-tag regex to match tags with trailing attributes e.g. (py/bad-tag-filter) - fix(regex-range) #9: replace overly broad [$-_] character range with explicit safe-char list in email_ingestor.py URL pattern (py/overly-large-range) - fix(info-exposure) #5: replace str(exc) with a generic error message and log the full stack trace server-side in export_import.py (py/stack-trace-exposure) Closes #4, Closes #5, Closes #9, Closes #10 Co-Authored-By: Claude Sonnet 4.6 --- semantica/explorer/routes/export_import.py | 7 +++++-- semantica/ingest/email_ingestor.py | 2 +- semantica/normalize/text_cleaner.py | 4 ++-- semantica/ontology/naming_conventions.py | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/semantica/explorer/routes/export_import.py b/semantica/explorer/routes/export_import.py index 587afa56..8c7c2e56 100644 --- a/semantica/explorer/routes/export_import.py +++ b/semantica/explorer/routes/export_import.py @@ -5,7 +5,7 @@ Export & import routes. import asyncio import io import json -import json +import logging import os import tempfile from typing import Optional @@ -13,6 +13,8 @@ from typing import Optional from fastapi import APIRouter, Depends, File, UploadFile from fastapi.responses import Response +logger = logging.getLogger(__name__) + from ..dependencies import get_session, get_ws_manager from ..schemas import ExportRequest from ..session import GraphSession @@ -229,7 +231,8 @@ async def import_file( "detail": f"File type not supported yet: {filename}", } except Exception as exc: - result = {"status": "error", "detail": str(exc)} + logger.exception("Import failed") + result = {"status": "error", "detail": "An internal error occurred during import"} await ws.broadcast("import_completed", result) return result diff --git a/semantica/ingest/email_ingestor.py b/semantica/ingest/email_ingestor.py index b626abfd..0f16d9df 100644 --- a/semantica/ingest/email_ingestor.py +++ b/semantica/ingest/email_ingestor.py @@ -392,7 +392,7 @@ class EmailParser: # Extract URLs from text using regex import re - url_pattern = r"http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" + url_pattern = r"https?://(?:[a-zA-Z0-9]|[$\-_.&+!*(),]|(?:%[0-9a-fA-F]{2}))+" text_links = re.findall(url_pattern, email_content) links.extend(text_links) diff --git a/semantica/normalize/text_cleaner.py b/semantica/normalize/text_cleaner.py index f97ceb45..a6b5f93c 100644 --- a/semantica/normalize/text_cleaner.py +++ b/semantica/normalize/text_cleaner.py @@ -302,10 +302,10 @@ class TextCleaner: # Remove potential script tags text = re.sub( - r"]*>.*?", "", text, flags=re.IGNORECASE | re.DOTALL + r"]*>.*?]*)?>", "", text, flags=re.IGNORECASE | re.DOTALL ) text = re.sub( - r"]*>.*?", "", text, flags=re.IGNORECASE | re.DOTALL + r"]*>.*?]*)?>", "", text, flags=re.IGNORECASE | re.DOTALL ) # Remove javascript: URLs diff --git a/semantica/ontology/naming_conventions.py b/semantica/ontology/naming_conventions.py index f3ebd01a..2d4e0e39 100644 --- a/semantica/ontology/naming_conventions.py +++ b/semantica/ontology/naming_conventions.py @@ -350,7 +350,7 @@ class NamingConventions: def _is_noun_phrase(self, name: str) -> bool: """Check if name is a noun phrase (basic heuristic).""" # Basic heuristic: PascalCase words are typically nouns - return bool(re.match(r"^[A-Z][a-zA-Z0-9]*([A-Z][a-zA-Z0-9]*)*$", name)) + return bool(re.match(r"^[A-Z][a-zA-Z0-9]*(?:[A-Z][a-zA-Z0-9]*)*$", name)) def _is_verb_phrase(self, name: str) -> bool: """Check if name is a verb phrase (basic heuristic)."""