Skip to content

Commit

Permalink
🔒 fix(sso/base.py): remove _oauth_client from class attributes to pre…
Browse files Browse the repository at this point in the history
…vent security issues

✨ feat(sso/base.py): add context manager support to SSOBase class to ensure safe usage
⚠️ feat(sso/base.py): add ReusedOauthClientWarning to warn about potential security issues when reusing SSO object
  • Loading branch information
tomasvotava committed Jul 25, 2023
1 parent 3dc18dc commit 24a16eb
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion fastapi_sso/sso/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import json
import sys
import warnings
from types import TracebackType
from typing import Any, Dict, List, Optional

import httpx
Expand All @@ -28,6 +29,10 @@ class UnsetStateWarning(UserWarning):
"""Warning about unset state parameter"""


class ReusedOauthClientWarning(UserWarning):
"""Warning about reused oauth client instance"""


class SSOLoginError(HTTPException):
"""Raised when any login-related error ocurrs
(such as when user is not verified or if there was an attempt for fake login)
Expand Down Expand Up @@ -55,7 +60,6 @@ class SSOBase:
client_secret: str = NotImplemented
redirect_uri: Optional[str] = NotImplemented
scope: List[str] = NotImplemented
_oauth_client: Optional[WebApplicationClient] = None
additional_headers: Optional[Dict[str, Any]] = None

def __init__(
Expand All @@ -72,6 +76,7 @@ def __init__(
self.client_secret = client_secret
self.redirect_uri = redirect_uri
self.allow_insecure_http = allow_insecure_http
self._oauth_client: Optional[WebApplicationClient] = None
# TODO: Remove use_state argument and attribute
if use_state:
warnings.warn(
Expand Down Expand Up @@ -208,6 +213,16 @@ async def verify_and_process(
code, request, params=params, additional_headers=headers, redirect_uri=redirect_uri
)

def __enter__(self) -> "SSOBase":
self._oauth_client = None
self._refresh_token = None
return self

def __exit__(
self, _exc_type: type[BaseException] | None, _exc_val: BaseException | None, _exc_tb: TracebackType | None
) -> None:
return None

async def process_login(
self,
code: str,
Expand All @@ -225,6 +240,16 @@ async def process_login(
additional_headers {Optional[Dict[str, Any]]} -- Optional additional headers to be added to all requests
"""
# pylint: disable=too-many-locals
if self._oauth_client is not None:
self._oauth_client = None
self._refresh_token = None
warnings.warn(
(
"Reusing the SSO object is not safe and caused a security issue in previous versions."
"To make sure you don't see this warning, please use the SSO object as a context manager."
),
ReusedOauthClientWarning,
)
params = params or {}
additional_headers = additional_headers or {}
additional_headers.update(self.additional_headers or {})
Expand Down

0 comments on commit 24a16eb

Please sign in to comment.