From 375951bd49c9c10e7241e313a76235b43285522f Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 30 Mar 2026 02:31:14 +0200 Subject: [PATCH] feat(mcp): Protect from Prompt Injection by removing hidden content Solves #214 as well --- scrapling/core/shell.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/scrapling/core/shell.py b/scrapling/core/shell.py index 80caa99..bed1c84 100644 --- a/scrapling/core/shell.py +++ b/scrapling/core/shell.py @@ -2,7 +2,7 @@ from sys import stderr from copy import deepcopy from functools import wraps -from re import sub as re_sub +from re import sub as re_sub, compile as re_compile from collections import namedtuple from shlex import split as shlex_split from inspect import signature, Parameter @@ -21,6 +21,7 @@ from logging import ( getLevelName, ) +from lxml.etree import XPath from orjson import loads as json_loads, JSONDecodeError from ._shell_signatures import Signatures_map @@ -67,6 +68,19 @@ Request = namedtuple( ], ) +# Precompiled for the prompt injection sanitizer +_HIDDEN_XPATH = XPath( + './/*[contains(@style,"display:none") or contains(@style,"display: none")' + ' or contains(@style,"visibility:hidden") or contains(@style,"visibility: hidden")' + ' or contains(@style,"opacity:0") or contains(@style,"opacity: 0")' + ' or contains(@style,"font-size:0") or contains(@style,"font-size: 0")' + ' or contains(@style,"height:0") or contains(@style,"height: 0")' + ' or contains(@style,"width:0") or contains(@style,"width: 0")]' + " | .//*[@aria-hidden='true']" + " | .//template" +) +_ZWC_PATTERN = re_compile(r"[\u200b\u200c\u200d\ufeff\u2060\u180e]") + # Suppress exit on error to handle parsing errors gracefully class NoExitArgumentParser(ArgumentParser): # pragma: no cover @@ -580,6 +594,23 @@ class Convertor: element.drop_tree() return Selector(root=clean_root, url=page.url) + @classmethod + def _sanitize_for_ai(cls, page: Selector) -> Selector: + """Strip hidden content that could be used for prompt injection. + + Removes CSS-hidden elements, aria-hidden elements,