From 10eff4332034e98861ebd7650755df9a67b6086a Mon Sep 17 00:00:00 2001 From: Pauline Ribeyre <4224001+paulineribeyre@users.noreply.github.com> Date: Tue, 11 Feb 2025 10:11:56 -0600 Subject: [PATCH] reject bearer tokens --- gen3workflow/routes/s3.py | 12 ++++++++++-- tests/test_s3_endpoint.py | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/gen3workflow/routes/s3.py b/gen3workflow/routes/s3.py index e60df01..0754cb8 100644 --- a/gen3workflow/routes/s3.py +++ b/gen3workflow/routes/s3.py @@ -8,7 +8,11 @@ import hmac from starlette.datastructures import Headers from starlette.responses import Response -from starlette.status import HTTP_400_BAD_REQUEST, HTTP_403_FORBIDDEN +from starlette.status import ( + HTTP_400_BAD_REQUEST, + HTTP_401_UNAUTHORIZED, + HTTP_403_FORBIDDEN, +) from gen3workflow import aws_utils, logger from gen3workflow.auth import Auth @@ -33,6 +37,10 @@ def get_access_token(headers: Headers) -> str: auth_header = headers.get("authorization") if not auth_header: return "" + if auth_header.lower().startswith("bearer"): + err_msg = f"Bearer tokens in the authorization header are not supported by this endpoint. Please use the AWS SDK/CLI instead" + logger.error(err_msg) + raise HTTPException(HTTP_401_UNAUTHORIZED, err_msg) try: return auth_header.split("Credential=")[1].split("/")[0] except Exception as e: @@ -65,7 +73,7 @@ def get_signature_key(key: str, date: str, region_name: str, service_name: str) ) async def s3_endpoint(path: str, request: Request): """ - Receive incoming S3 requests, re-sign them (AWS Signature Version 4 algorithm) with the + Receive incoming signed S3 requests, re-sign them (AWS Signature Version 4 algorithm) with the appropriate credentials to access the current user's AWS S3 bucket, and forward them to AWS S3. """ diff --git a/tests/test_s3_endpoint.py b/tests/test_s3_endpoint.py index 88500d5..3a52880 100644 --- a/tests/test_s3_endpoint.py +++ b/tests/test_s3_endpoint.py @@ -69,3 +69,19 @@ def test_s3_endpoint_wrong_bucket(s3_client, access_token_patcher, bucket_name): """ with pytest.raises(ClientError, match="Forbidden"): s3_client.list_objects(Bucket=bucket_name) + + +@pytest.mark.asyncio +async def test_s3_endpoint_with_bearer_token(client): + """ + Hitting the `/s3` endpoint with a bearer token instead of using the AWS SDK/CLI should result + in a 401 error. + """ + res = await client.get( + f"/s3/gen3wf-{config['HOSTNAME']}-{TEST_USER_ID}", + headers={"Authorization": "bearer 123"}, + ) + assert res.status_code == 401, res.text + assert res.json() == { + "detail": "Bearer tokens in the authorization header are not supported by this endpoint. Please use the AWS SDK/CLI instead" + }