From c494f585c3e305d9371b066ca76090375f32c26a Mon Sep 17 00:00:00 2001 From: Deimos Date: Mon, 8 Jul 2019 17:42:03 -0600 Subject: [PATCH] Use webtest to ensure no external login redirects Now that the login page will redirect to a specified path after logging in, I want to make sure that it can't be used to redirect to a different site. --- tildes/tests/conftest.py | 28 ++++++++++++++-------------- tildes/tests/webtests/test_login.py | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 tildes/tests/webtests/test_login.py diff --git a/tildes/tests/conftest.py b/tildes/tests/conftest.py index 8d84537..50cfd0e 100644 --- a/tildes/tests/conftest.py +++ b/tildes/tests/conftest.py @@ -24,6 +24,18 @@ from tildes.models.user import User pytest_plugins = ["tests.fixtures"] +# Extra environment setup for webtest TestApps: +# - wsgi.url_scheme: needed for secure cookies from the session library +# - tm.active: setting to True effectively disables pyramid_tm, which fixes an issue +# with webtest fixtures failing to rollback data after the tests are complete +# - REMOTE_ADDR: must be defined for logging to work +WEBTEST_EXTRA_ENVIRON = { + "wsgi.url_scheme": "https", + "tm.active": True, + "REMOTE_ADDR": "0.0.0.0", +} + + class NestedSessionWrapper(Session): """Wrapper that starts a new nested transaction on commit/rollback.""" @@ -198,19 +210,7 @@ def base_app(overall_redis_session, sdb): @fixture(scope="session") def webtest(base_app): """Create a webtest TestApp and log in as the SessionUser account in it.""" - # create the TestApp - note that specifying wsgi.url_scheme is necessary so that the - # secure cookies from the session library will work - app = TestApp( - base_app, - # This "tm.active" is a temporary fix around this fixture failing to rollback - # data after the tests are complete (it effectively deactivates pyramid_tm). - extra_environ={ - "wsgi.url_scheme": "https", - "tm.active": True, - "REMOTE_ADDR": "0.0.0.0", - }, - cookiejar=CookieJar(), - ) + app = TestApp(base_app, extra_environ=WEBTEST_EXTRA_ENVIRON, cookiejar=CookieJar()) # fetch the login page, fill in the form, and submit it (sets the cookie) login_page = app.get("/login") @@ -224,4 +224,4 @@ def webtest(base_app): @fixture(scope="session") def webtest_loggedout(base_app): """Create a logged-out webtest TestApp (no cookies retained).""" - yield TestApp(base_app) + yield TestApp(base_app, extra_environ=WEBTEST_EXTRA_ENVIRON) diff --git a/tildes/tests/webtests/test_login.py b/tildes/tests/webtests/test_login.py new file mode 100644 index 0000000..a85782c --- /dev/null +++ b/tildes/tests/webtests/test_login.py @@ -0,0 +1,15 @@ +# Copyright (c) 2019 Tildes contributors +# SPDX-License-Identifier: AGPL-3.0-or-later + + +def test_login_no_external_redirect(webtest_loggedout): + """Ensure that the login page won't redirect to an external site.""" + login_page = webtest_loggedout.get( + "/login", params={"from_url": "http://example.com"} + ) + login_page.form["username"] = "SessionUser" + login_page.form["password"] = "session user password" + response = login_page.form.submit() + + assert response.status_int == 302 + assert "example.com" not in response.headers["Location"]