Limit health endpoint to /health$ (#19405)
This commit is contained in:
1
changelog.d/19405.misc
Normal file
1
changelog.d/19405.misc
Normal file
@@ -0,0 +1 @@
|
||||
Disallow requests to the health endpoint from containing trailing path characters.
|
||||
@@ -22,6 +22,8 @@
|
||||
from twisted.web.resource import Resource
|
||||
from twisted.web.server import Request
|
||||
|
||||
from synapse.api.errors import Codes
|
||||
|
||||
|
||||
class HealthResource(Resource):
|
||||
"""A resource that does nothing except return a 200 with a body of `OK`,
|
||||
@@ -34,5 +36,15 @@ class HealthResource(Resource):
|
||||
isLeaf = 1
|
||||
|
||||
def render_GET(self, request: Request) -> bytes:
|
||||
# Prevent path traversal by ensuring the request path is exactly /health.
|
||||
if request.path != b"/health":
|
||||
request.setResponseCode(404)
|
||||
body = (
|
||||
'{"errcode":"'
|
||||
+ Codes.UNRECOGNIZED
|
||||
+ '","error":"Unrecognized request"}'
|
||||
)
|
||||
return body.encode("utf-8")
|
||||
|
||||
request.setHeader(b"Content-Type", b"text/plain")
|
||||
return b"OK"
|
||||
|
||||
@@ -33,3 +33,16 @@ class HealthCheckTests(unittest.HomeserverTestCase):
|
||||
|
||||
self.assertEqual(channel.code, 200)
|
||||
self.assertEqual(channel.result["body"], b"OK")
|
||||
|
||||
def test_health_path_traversal(self) -> None:
|
||||
"""
|
||||
Test that the health endpoint does not allow extra path segments,
|
||||
which could be used to access other resources.
|
||||
|
||||
Regression test for: https://github.com/element-hq/synapse/issues/19395
|
||||
"""
|
||||
channel = self.make_request("GET", "/health/extra/path", shorthand=False)
|
||||
|
||||
self.assertEqual(channel.code, 404)
|
||||
self.assertEqual(channel.json_body["errcode"], "M_UNRECOGNIZED")
|
||||
self.assertIn("error", channel.json_body)
|
||||
|
||||
Reference in New Issue
Block a user