Skip to content

Commit ff8967e

Browse files
authored
Validate prompt arguments for XSS (#571)
Signed-off-by: Madhav Kandukuri <[email protected]>
1 parent 018a278 commit ff8967e

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

mcpgateway/main.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
GatewayUpdate,
8080
JsonPathModifier,
8181
PromptCreate,
82+
PromptExecuteArgs,
8283
PromptRead,
8384
PromptUpdate,
8485
ResourceCreate,
@@ -1632,7 +1633,13 @@ async def get_prompt(
16321633
Rendered prompt or metadata.
16331634
"""
16341635
logger.debug(f"User: {user} requested prompt: {name} with args={args}")
1635-
return await prompt_service.get_prompt(db, name, args)
1636+
try:
1637+
PromptExecuteArgs(args=args)
1638+
return await prompt_service.get_prompt(db, name, args)
1639+
except Exception as ex:
1640+
logger.error(f"Error retrieving prompt {name}: {ex}")
1641+
if isinstance(ex, ValueError):
1642+
return JSONResponse(content={"message": "Prompt execution arguments contains HTML tags that may cause security issues"}, status_code=422)
16361643

16371644

16381645
@prompt_router.get("/{name}")

mcpgateway/schemas.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,34 @@ def validate_arguments(cls, v: Dict[str, Any]) -> Dict[str, Any]:
14331433
return v
14341434

14351435

1436+
class PromptExecuteArgs(BaseModel):
1437+
"""
1438+
Schema for args executing a prompt
1439+
1440+
Attributes:
1441+
args (Dict[str, str]): Arguments for prompt execution.
1442+
"""
1443+
1444+
model_config = ConfigDict(str_strip_whitespace=True)
1445+
1446+
args: Dict[str, str] = Field(default_factory=dict, description="Arguments for prompt execution")
1447+
1448+
@field_validator("args")
1449+
@classmethod
1450+
def validate_args(cls, v: dict) -> dict:
1451+
"""Ensure prompt arguments pass XSS validation
1452+
1453+
Args:
1454+
v (dict): Value to validate
1455+
1456+
Returns:
1457+
dict: Value if validated as safe
1458+
"""
1459+
for val in v.values():
1460+
SecurityValidator.validate_no_xss(val, "Prompt execution arguments")
1461+
return v
1462+
1463+
14361464
class PromptUpdate(BaseModelWithConfigDict):
14371465
"""Schema for updating an existing prompt.
14381466

mcpgateway/validators.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,24 @@ def validate_url(cls, value: str, field_name: str = "URL") -> str:
420420

421421
return value
422422

423+
@classmethod
424+
def validate_no_xss(cls, value: str, field_name: str) -> None:
425+
"""
426+
Validate that a string does not contain XSS patterns.
427+
428+
Args:
429+
value (str): Value to validate.
430+
field_name (str): Name of the field being validated.
431+
432+
Raises:
433+
ValueError: If the value contains XSS patterns.
434+
"""
435+
if not value:
436+
return # Empty values are considered safe
437+
# Check for dangerous HTML tags
438+
if re.search(cls.DANGEROUS_HTML_PATTERN, value, re.IGNORECASE):
439+
raise ValueError(f"{field_name} contains HTML tags that may cause security issues")
440+
423441
@classmethod
424442
def validate_json_depth(
425443
cls,

0 commit comments

Comments
 (0)