diff --git a/conservancy/tests.py b/conservancy/tests.py index 3016821a..361d5e8a 100644 --- a/conservancy/tests.py +++ b/conservancy/tests.py @@ -55,3 +55,9 @@ def test_path_traversal_404s(rf): request = rf.get('/about/../../../conservancy-website.sqlite3') with pytest.raises(Http404): views.content(request) + + +def test_long_path_404s(rf): + request = rf.get('x' * 1000) + with pytest.raises(Http404): + views.content(request) diff --git a/conservancy/views.py b/conservancy/views.py index cbc1dd46..8505f5b7 100644 --- a/conservancy/views.py +++ b/conservancy/views.py @@ -52,10 +52,14 @@ def content(request, *args, **kwargs): path += 'index.html' full_path = (base_path / path).resolve() safe_from_path_traversal = full_path.is_relative_to(base_path) - if full_path.is_dir(): - # Should have been accessed with a trailing slash. - return HttpResponseRedirect(request.path + '/') - elif not full_path.exists() or not safe_from_path_traversal: + try: + if full_path.is_dir(): + # Should have been accessed with a trailing slash. + return HttpResponseRedirect(request.path + '/') + elif not full_path.exists() or not safe_from_path_traversal: + raise Http404() + except OSError: + # eg. path is too long raise Http404() is_template = mimetypes.guess_type(full_path)[0] == 'text/html' if not is_template: