diff --git a/meshai/config.py b/meshai/config.py index e732efc..1e933b3 100644 --- a/meshai/config.py +++ b/meshai/config.py @@ -64,6 +64,7 @@ class SafetyConfig: emergency_keywords: list[str] = field( default_factory=lambda: ["emergency", "help", "sos"] ) # Always respond to these + prompt_injection_guard: bool = True # Basic prompt injection detection @dataclass diff --git a/meshai/router.py b/meshai/router.py index 8e33193..ce6239f 100644 --- a/meshai/router.py +++ b/meshai/router.py @@ -33,6 +33,17 @@ class RouteResult: query: Optional[str] = None # For LLM, the cleaned query +# Patterns that suggest prompt injection attempts +_INJECTION_PATTERNS = [ + re.compile(r"ignore\s+(all\s+)?previous", re.IGNORECASE), + re.compile(r"ignore\s+your\s+instructions", re.IGNORECASE), + re.compile(r"disregard\s+(all\s+)?previous", re.IGNORECASE), + re.compile(r"you\s+are\s+now\b", re.IGNORECASE), + re.compile(r"new\s+instructions?\s*:", re.IGNORECASE), + re.compile(r"system\s*prompt\s*:", re.IGNORECASE), +] + + class MessageRouter: """Routes incoming messages to appropriate handlers.""" @@ -186,12 +197,28 @@ class MessageRouter: logger.debug(f"Persisted summary for {user_id}") def _clean_query(self, text: str) -> str: - """Remove @mention from query text.""" + """Remove @mention and check for prompt injection.""" # Remove @botname mention cleaned = self._mention_pattern.sub("", text) # Clean up extra whitespace cleaned = " ".join(cleaned.split()) - return cleaned.strip() + cleaned = cleaned.strip() + + # Check for prompt injection if guard is enabled + if self.config.safety.prompt_injection_guard: + for pattern in _INJECTION_PATTERNS: + if pattern.search(cleaned): + logger.warning( + f"Possible prompt injection detected: {cleaned[:80]}..." + ) + # Truncate to just the part before the injection pattern + match = pattern.search(cleaned) + cleaned = cleaned[:match.start()].strip() + if not cleaned: + cleaned = "Hello" + break + + return cleaned def _make_command_context(self, message: MeshMessage) -> CommandContext: """Create command context from message.""" diff --git a/meshai/web_status.py b/meshai/web_status.py index 7824431..63e09a3 100644 --- a/meshai/web_status.py +++ b/meshai/web_status.py @@ -1,6 +1,7 @@ """Simple web status page for MeshAI.""" import asyncio +import html as html_module import json import logging import threading @@ -159,6 +160,31 @@ class StatusRequestHandler(BaseHTTPRequestHandler): include_activity=self.config.show_recent_activity if self.config else False ) + esc = html_module.escape + + # Build optional stat rows + rows = "" + if self.config and self.config.show_uptime: + rows += ( + '