fix(FastAPI): prevent CSRF forging login requests

Signed-off-by: Steven Guikal <void@fluix.one>
This commit is contained in:
Steven Guikal 2021-11-01 17:18:09 -04:00
parent e4a5b7fae9
commit 020409ef46
3 changed files with 49 additions and 1 deletions

View file

@ -18,6 +18,9 @@ from aurweb.testing import setup_test_db
# Some test global constants.
TEST_USERNAME = "test"
TEST_EMAIL = "test@example.org"
TEST_REFERER = {
"referer": aurweb.config.get("options", "aur_location") + "/login",
}
# Global mutables.
user = client = None
@ -39,6 +42,10 @@ def setup():
client = TestClient(app)
# Necessary for forged login CSRF protection on the login route. Set here
# instead of only on the necessary requests for convenience.
client.headers.update(TEST_REFERER)
def test_login_logout():
post_data = {
@ -92,6 +99,10 @@ def test_secure_login(mock):
# Create a local TestClient here since we mocked configuration.
client = TestClient(app)
# Necessary for forged login CSRF protection on the login route. Set here
# instead of only on the necessary requests for convenience.
client.headers.update(TEST_REFERER)
# Data used for our upcoming http post request.
post_data = {
"user": user.Username,
@ -246,3 +257,26 @@ def test_login_incorrect_password():
assert post_data["user"] in content
assert post_data["passwd"] not in content
assert "checked" not in content
def test_login_bad_referer():
post_data = {
"user": "test",
"passwd": "testPassword",
"next": "/",
}
# Create new TestClient without a Referer header.
client = TestClient(app)
with client as request:
response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies
BAD_REFERER = {
"referer": aurweb.config.get("options", "aur_location") + ".mal.local",
}
with client as request:
response = request.post("/login", data=post_data, headers=BAD_REFERER)
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
assert "AURSID" not in response.cookies