aboutsummaryrefslogtreecommitdiff
path: root/src/test/modules/oauth_validator/t/oauth_server.py
diff options
context:
space:
mode:
authorJacob Champion <jchampion@postgresql.org>2025-05-23 13:05:33 -0700
committerJacob Champion <jchampion@postgresql.org>2025-05-23 13:05:33 -0700
commitcbc8fd0c9aec01f451af5e4eeb0eb2c5d5e47eb2 (patch)
tree643d5d4f0f6c129b81b0647f4531251cd95e66a7 /src/test/modules/oauth_validator/t/oauth_server.py
parent1ca583f6c0f9c178dd2721886c723791ced65520 (diff)
downloadpostgresql-cbc8fd0c9aec01f451af5e4eeb0eb2c5d5e47eb2.tar.gz
postgresql-cbc8fd0c9aec01f451af5e4eeb0eb2c5d5e47eb2.zip
oauth: Limit JSON parsing depth in the client
Check the ctx->nested level as we go, to prevent a server from running the client out of stack space. The limit we choose when communicating with authorization servers can't be overly strict, since those servers will continue to add extensions in their JSON documents which we need to correctly ignore. For the SASL communication, we can be more conservative, since there are no defined extensions (and the peer is probably more Postgres code). Reviewed-by: Aleksander Alekseev <aleksander@timescale.com> Discussion: https://postgr.es/m/CAOYmi%2Bm71aRUEi0oQE9ciBnBS8xVtMn3CifaPu2kmJzUfhOZgA%40mail.gmail.com
Diffstat (limited to 'src/test/modules/oauth_validator/t/oauth_server.py')
-rwxr-xr-xsrc/test/modules/oauth_validator/t/oauth_server.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/test/modules/oauth_validator/t/oauth_server.py b/src/test/modules/oauth_validator/t/oauth_server.py
index 20b3a9506cb..0f8836aadf3 100755
--- a/src/test/modules/oauth_validator/t/oauth_server.py
+++ b/src/test/modules/oauth_validator/t/oauth_server.py
@@ -7,6 +7,7 @@
#
import base64
+import functools
import http.server
import json
import os
@@ -213,14 +214,32 @@ class OAuthHandler(http.server.BaseHTTPRequestHandler):
@property
def _response_padding(self):
"""
- If the huge_response test parameter is set to True, returns a dict
- containing a gigantic string value, which can then be folded into a JSON
- response.
+ Returns a dict with any additional entries that should be folded into a
+ JSON response, as determined by test parameters provided by the client:
+
+ - huge_response: if set to True, the dict will contain a gigantic string
+ value
+
+ - nested_array: if set to nonzero, the dict will contain a deeply nested
+ array so that the top-level object has the given depth
+
+ - nested_object: if set to nonzero, the dict will contain a deeply
+ nested JSON object so that the top-level object has the given depth
"""
- if not self._get_param("huge_response", False):
- return dict()
+ ret = dict()
+
+ if self._get_param("huge_response", False):
+ ret["_pad_"] = "x" * 1024 * 1024
+
+ depth = self._get_param("nested_array", 0)
+ if depth:
+ ret["_arr_"] = functools.reduce(lambda x, _: [x], range(depth))
+
+ depth = self._get_param("nested_object", 0)
+ if depth:
+ ret["_obj_"] = functools.reduce(lambda x, _: {"": x}, range(depth))
- return {"_pad_": "x" * 1024 * 1024}
+ return ret
@property
def _access_token(self):