Skip to content

Commit 1c048c7

Browse files
Nayana-R-GowdaNAYANAR0502crivetimihai
authored
423RedundantConditionalExpression (#653)
* Redundant Conditional Expression in Content Validation Signed-off-by: NAYANAR <[email protected]> * update Signed-off-by: NAYANAR <[email protected]> * Remove FEATURES_DOCS_ENABLED and set DEV_MODE=false Signed-off-by: Mihai Criveti <[email protected]> --------- Signed-off-by: NAYANAR <[email protected]> Signed-off-by: Mihai Criveti <[email protected]> Co-authored-by: NAYANAR <[email protected]> Co-authored-by: Mihai Criveti <[email protected]>
1 parent 83df1b2 commit 1c048c7

File tree

4 files changed

+46
-12
lines changed

4 files changed

+46
-12
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ TOKEN_EXPIRY=10080
100100
# Require all JWT tokens to have expiration claims (true or false)
101101
REQUIRE_TOKEN_EXPIRATION=false
102102

103+
103104
# Used to derive an AES encryption key for secure auth storage
104105
# Must be a non-empty string (e.g. passphrase or random secret)
105106
AUTH_ENCRYPTION_SECRET=my-test-salt

mcpgateway/main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,9 @@ async def create_resource(
14131413
raise HTTPException(status_code=409, detail=str(e))
14141414
except ResourceError as e:
14151415
raise HTTPException(status_code=400, detail=str(e))
1416+
except ValidationError as e:
1417+
# Handle validation errors from Pydantic
1418+
return JSONResponse(content=ErrorFormatter.format_validation_error(e), status_code=422)
14161419

14171420

14181421
@resource_router.get("/{uri:path}")

mcpgateway/schemas.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -999,15 +999,13 @@ def validate_content(cls, v: Optional[Union[str, bytes]]) -> Optional[Union[str,
999999

10001000
if isinstance(v, bytes):
10011001
try:
1002-
v_str = v.decode("utf-8")
1003-
1004-
if re.search(SecurityValidator.DANGEROUS_HTML_PATTERN, v_str if isinstance(v, bytes) else v, re.IGNORECASE):
1005-
raise ValueError("Content contains HTML tags that may cause display issues")
1002+
text = v.decode("utf-8")
10061003
except UnicodeDecodeError:
10071004
raise ValueError("Content must be UTF-8 decodable")
10081005
else:
1009-
if re.search(SecurityValidator.DANGEROUS_HTML_PATTERN, v if isinstance(v, bytes) else v, re.IGNORECASE):
1010-
raise ValueError("Content contains HTML tags that may cause display issues")
1006+
text = v
1007+
if re.search(SecurityValidator.DANGEROUS_HTML_PATTERN, text, re.IGNORECASE):
1008+
raise ValueError("Content contains HTML tags that may cause display issues")
10111009

10121010
return v
10131011

@@ -1094,15 +1092,13 @@ def validate_content(cls, v: Optional[Union[str, bytes]]) -> Optional[Union[str,
10941092

10951093
if isinstance(v, bytes):
10961094
try:
1097-
v_str = v.decode("utf-8")
1098-
1099-
if re.search(SecurityValidator.DANGEROUS_HTML_PATTERN, v_str if isinstance(v, bytes) else v, re.IGNORECASE):
1100-
raise ValueError("Content contains HTML tags that may cause display issues")
1095+
text = v.decode("utf-8")
11011096
except UnicodeDecodeError:
11021097
raise ValueError("Content must be UTF-8 decodable")
11031098
else:
1104-
if re.search(SecurityValidator.DANGEROUS_HTML_PATTERN, v if isinstance(v, bytes) else v, re.IGNORECASE):
1105-
raise ValueError("Content contains HTML tags that may cause display issues")
1099+
text = v
1100+
if re.search(SecurityValidator.DANGEROUS_HTML_PATTERN, text, re.IGNORECASE):
1101+
raise ValueError("Content contains HTML tags that may cause display issues")
11061102

11071103
return v
11081104

tests/unit/mcpgateway/test_schemas.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
AdminToolCreate,
5353
EventMessage,
5454
ListFilters,
55+
ResourceCreate,
5556
ServerCreate,
5657
ServerMetrics,
5758
ServerRead,
@@ -841,3 +842,36 @@ def test_list_filters(self):
841842
# Test default value
842843
default_filters = ListFilters()
843844
assert default_filters.include_inactive is False
845+
846+
847+
DANGEROUS_HTML = "<script>alert('xss')</script>"
848+
SAFE_STRING = "Hello, this is safe."
849+
SAFE_BYTES = b"Some binary safe content"
850+
DANGEROUS_HTML_BYTES = DANGEROUS_HTML.encode("utf-8")
851+
NON_UTF8_BYTES = b"\x80\x81\x82"
852+
853+
854+
# Tests for ResourceCreate
855+
def test_resource_create_with_safe_string():
856+
r = ResourceCreate(uri="some-uri", name="test.txt", content=SAFE_STRING)
857+
assert isinstance(r.content, str)
858+
859+
860+
def test_resource_create_with_dangerous_html_string():
861+
with pytest.raises(ValueError, match="Content contains HTML tags"):
862+
ResourceCreate(uri="some-uri", name="dangerous.html", content=DANGEROUS_HTML)
863+
864+
865+
def test_resource_create_with_safe_bytes():
866+
r = ResourceCreate(uri="some-uri", name="test.bin", content=SAFE_BYTES)
867+
assert isinstance(r.content, bytes)
868+
869+
870+
def test_resource_create_with_dangerous_html_bytes():
871+
with pytest.raises(ValueError, match="Content contains HTML tags"):
872+
ResourceCreate(uri="some-uri", name="dangerous.html", content=DANGEROUS_HTML_BYTES)
873+
874+
875+
def test_resource_create_with_non_utf8_bytes():
876+
with pytest.raises(ValueError, match="Content must be UTF-8 decodable"):
877+
ResourceCreate(uri="some-uri", name="nonutf8.bin", content=NON_UTF8_BYTES)

0 commit comments

Comments
 (0)