From 9e4eccd26d99af42a7ae3e88bd7a9e4b594e82c5 Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Thu, 18 Jul 2024 03:24:15 -0400 Subject: [PATCH] test: Add tests to tests/test_webservice.py for directory traversal --- tests/test_webservice.py | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/test_webservice.py b/tests/test_webservice.py index d2dfb066..3b8fd031 100644 --- a/tests/test_webservice.py +++ b/tests/test_webservice.py @@ -1,6 +1,9 @@ from pathlib import Path from unittest import mock +import pytest + +from scrapyd.exceptions import DirectoryTraversalError, RunnerError from scrapyd.interfaces import IEggStorage from scrapyd.jobstorage import Job @@ -154,3 +157,60 @@ def test_schedule(self, txrequest, site_with_egg): assert site_with_egg.scheduler.calls == [['quotesbot', 'toscrape-css']] assert content['status'] == 'ok' assert 'jobid' in content + + @pytest.mark.parametrize('endpoint,attach_egg,method', [ + (b'addversion.json', True, 'render_POST'), + (b'listversions.json', False, 'render_GET'), + (b'delproject.json', False, 'render_POST'), + (b'delversion.json', False, 'render_POST'), + ]) + def test_bad_project_names(self, txrequest, site_no_egg, endpoint, attach_egg, method): + txrequest.args = { + b'project': [b'../p'], + b'version': [b'0.1'], + } + + if attach_egg: + egg_path = Path(__file__).absolute().parent / "quotesbot.egg" + with open(egg_path, 'rb') as f: + txrequest.args[b'egg'] = [f.read()] + + with pytest.raises(DirectoryTraversalError) as exc: + getattr(site_no_egg.children[endpoint], method)(txrequest) + + assert str(exc.value) == "../p" + + storage = site_no_egg.app.getComponent(IEggStorage) + version, egg = storage.get('quotesbot') + if egg: + egg.close() + + assert version is None + + @pytest.mark.parametrize('endpoint,attach_egg,method', [ + (b'schedule.json', False, 'render_POST'), + (b'listspiders.json', False, 'render_GET'), + ]) + def test_bad_project_names_runner(self, txrequest, site_no_egg, endpoint, attach_egg, method): + txrequest.args = { + b'project': [b'../p'], + b'spider': [b's'], + } + + if attach_egg: + egg_path = Path(__file__).absolute().parent / "quotesbot.egg" + with open(egg_path, 'rb') as f: + txrequest.args[b'egg'] = [f.read()] + + with pytest.raises(RunnerError) as exc: + getattr(site_no_egg.children[endpoint], method)(txrequest) + + assert str(exc.value).startswith("Traceback (most recent call last):"), str(exc.value) + assert str(exc.value).endswith("scrapyd.exceptions.DirectoryTraversalError: ../p\n"), str(exc.value) + + storage = site_no_egg.app.getComponent(IEggStorage) + version, egg = storage.get('quotesbot') + if egg: + egg.close() + + assert version is None