Skip to content

Commit

Permalink
[#1475] Harden apimock against directory traversal
Browse files Browse the repository at this point in the history
Signed-off-by: Bart van der Schoor <bart@maykinmedia.nl>
  • Loading branch information
Bart van der Schoor committed May 23, 2023
1 parent 8b77891 commit 8e610be
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
22 changes: 17 additions & 5 deletions src/open_inwoner/apimock/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@


class APIMockTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.url = reverse(
def test_basic_response(self):
url = reverse(
"apimock:mock",
kwargs={
"set_name": "openklant-read",
Expand All @@ -16,8 +15,7 @@ def setUpTestData(cls):
},
)

def test_basic_response(self):
response = self.client.get(self.url)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

data = response.json()
Expand All @@ -27,3 +25,17 @@ def test_basic_response(self):
url = data["results"][0]["url"]
self.assertNotIn("https://klanten.nl/", url)
self.assertIn("http://testserver/", url)

def test_doctored_response_endpoint(self):
url = reverse(
"apimock:mock",
kwargs={
"set_name": "openklant-read",
"api_name": "klanten",
# let's try to read package.json
"endpoint": "../../../../../../package",
},
)
response = self.client.get(url)
# status 403 if we get blocked on directory traversal
self.assertEqual(response.status_code, 403)
8 changes: 7 additions & 1 deletion src/open_inwoner/apimock/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
from pathlib import Path

from django.core.exceptions import PermissionDenied
from django.http import Http404, JsonResponse
from django.views import View

Expand All @@ -27,14 +28,19 @@ def get(self, request, *args, **kwargs):

endpoint = endpoint.rstrip("/")

# grab source dir
base_dir = Path(__file__).parent.resolve()
base_dir /= "apis"

api_dir = base_dir / set_name / api_name
if not api_dir.exists():
raise Http404("bad api_dir")

file_path = api_dir / (endpoint + ".json")
file_path = (api_dir / (endpoint + ".json")).resolve()

if base_dir not in file_path.parents:
raise PermissionDenied("bad traversal")

if not file_path.exists():
raise Http404("bad endpoint")

Expand Down

0 comments on commit 8e610be

Please sign in to comment.