Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does this package support PKCE flow for preventing authorization code interception attacks? #136

Open
anoopemacs opened this issue Nov 19, 2020 · 1 comment

Comments

@anoopemacs
Copy link

anoopemacs commented Nov 19, 2020

PKCE flow diagram from its RFC:-
Screenshot 2020-11-20 at 2 09 23 AM

@vecchp
Copy link

vecchp commented Feb 26, 2024

Few years late... but given I landed on this page when doing my own research I figured I'd answer. I believe you need to modify the backend to support PKCE. This is what I ended up doing to get it to work for me. You need to make sure the code_verifier is sent along in the body (as opposed to the url params) of the post otherwise you defeat the purpose of using it.

from social_core.backends.google import BaseGoogleOAuth2API
from social_core.backends.oauth import BaseOAuth2


class GoogleOAuth2PKCE(BaseGoogleOAuth2API, BaseOAuth2):
    """Google OAuth2 authentication backend"""

    name = "google-oauth2-pkce"
    REDIRECT_STATE = False
    AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/auth"
    ACCESS_TOKEN_URL = "https://accounts.google.com/o/oauth2/token"
    ACCESS_TOKEN_METHOD = "POST"
    REVOKE_TOKEN_URL = "https://accounts.google.com/o/oauth2/revoke"
    REVOKE_TOKEN_METHOD = "GET"
    # The order of the default scope is important
    DEFAULT_SCOPE = ["openid", "email", "profile"]
    EXTRA_DATA = [
        ("refresh_token", "refresh_token", True),
        ("expires_in", "expires"),
        ("token_type", "token_type", True),
    ]

    def auth_complete_params(self, state=None):
        params = super().auth_complete_params(state=state)
        params["code_verifier"] = self.data.get("code_verifier", "")
        return params

I didn't have to modify the OAuth2InputSerializer serializer for the field to pass through but it might be worth a PR to put it in an optional param like the following.'

class OAuth2InputSerializer(serializers.Serializer):
    provider = serializers.CharField(required=False)
    code = serializers.CharField()
    code_verifier = serializers.CharField(required=False)
    redirect_uri = serializers.CharField(required=False)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants