From 26c60e26fa604f61eae3bedd52d15d627d2c1032 Mon Sep 17 00:00:00 2001 From: Alexander Lukanin Date: Wed, 6 Dec 2017 14:13:09 +0500 Subject: [PATCH] Disallow POST application/json (only x-www-form-urlencoded is allowed) --- README.md | 2 ++ pozetron_barcode/barcode/models.py | 2 ++ tests/conftest.py | 7 +++++++ tests/test_barcode.py | 11 +++++++++++ 4 files changed, 22 insertions(+) diff --git a/README.md b/README.md index e734ca5..61fdd07 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Get QR code using [HTTPie](https://httpie.org/): http -v --form POST http://localhost:9001 text=abracadabra --download -o qrcode.png http -v --form POST http://localhost:9001 base64=YWJyYWNhZGFicmE= --download -o qrcode.png +Note that only `application/x-www-form-urlencoded` is allowed. + ## Testing Using tox: diff --git a/pozetron_barcode/barcode/models.py b/pozetron_barcode/barcode/models.py index 7e1ea9d..f179e45 100644 --- a/pozetron_barcode/barcode/models.py +++ b/pozetron_barcode/barcode/models.py @@ -9,6 +9,8 @@ class BarcodeResource: @staticmethod def on_post(req, resp): + if not req.content_type or req.content_type.split(';')[0] != 'application/x-www-form-urlencoded': + raise falcon.HTTPUnsupportedMediaType(description='Use application/x-www-form-urlencoded') # Get data (bytes) from request try: if len(req.params) != 1: diff --git a/tests/conftest.py b/tests/conftest.py index 2c95a26..d5cc04e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,6 +13,13 @@ def simulate_get_png(self, *args, **kw): def simulate_post_png(self, *args, **kw): self._add_file_wrapper(kw) + # If Content-Type is not specified explicitly, set application/x-www-form-urlencoded + try: + headers = kw['headers'] + except KeyError: + headers = kw['headers'] = {} + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/x-www-form-urlencoded' return super().simulate_post(*args, **kw) def _add_file_wrapper(self, kw): diff --git a/tests/test_barcode.py b/tests/test_barcode.py index 13a8417..b45641d 100644 --- a/tests/test_barcode.py +++ b/tests/test_barcode.py @@ -20,6 +20,17 @@ def test_get_barcode(client): assert response.content == b'' +def test_post_barcode_invalid(client): + response = client.simulate_post_png('/', + body='{"text":"abracadabra"}', + headers={'Content-Type': 'application/json'}) + assert response.status_code == 415 + assert response.json == { + 'title': 'Unsupported media type', + 'description': 'Use application/x-www-form-urlencoded' + } + + def test_post_barcode(client, abracadabra_png): # No params response = client.simulate_post_png('/')