From d97ff57cdaa7625abe4417def64df68f5d68c6ec Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Fri, 20 Jan 2017 09:10:19 -0500 Subject: [PATCH] prohibit API payloads that represent something other than a JSON object The JSON serializer for our API uses ``json.loads``, which permits *any* valid JSON (including bare integers, boolean values, etc). Lots of our code, however, assumes that inbound JSON content will be a dict. see: #4756 --- awx/api/parsers.py | 5 ++++- .../tests/functional/api/test_job_template.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/awx/api/parsers.py b/awx/api/parsers.py index 8c720201a2..826c67189a 100644 --- a/awx/api/parsers.py +++ b/awx/api/parsers.py @@ -26,6 +26,9 @@ class JSONParser(parsers.JSONParser): try: data = stream.read().decode(encoding) - return json.loads(data, object_pairs_hook=OrderedDict) + obj = json.loads(data, object_pairs_hook=OrderedDict) + if not isinstance(obj, dict): + raise ParseError(_('JSON parse error - not a JSON object')) + return obj except ValueError as exc: raise ParseError(_('JSON parse error - %s') % six.text_type(exc)) diff --git a/awx/main/tests/functional/api/test_job_template.py b/awx/main/tests/functional/api/test_job_template.py index ec4286176e..95f0d5d043 100644 --- a/awx/main/tests/functional/api/test_job_template.py +++ b/awx/main/tests/functional/api/test_job_template.py @@ -94,6 +94,23 @@ def test_edit_playbook(patch, job_template_factory, alice): }, alice, expect=403) +@pytest.mark.django_db +@pytest.mark.parametrize('json_body', + ["abc", True, False, "{\"name\": \"test\"}", 100, .5]) +def test_invalid_json_body(patch, job_template_factory, alice, json_body): + objs = job_template_factory('jt', organization='org1') + objs.job_template.admin_role.members.add(alice) + resp = patch( + reverse('api:job_template_detail', args=(objs.job_template.id,)), + json_body, + alice, + expect=400 + ) + assert resp.data['detail'] == ( + u'JSON parse error - not a JSON object' + ) + + @pytest.mark.django_db def test_edit_nonsenstive(patch, job_template_factory, alice): objs = job_template_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred')