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

[Question] Security Concerns with Email Invitation Policy #655

Open
andnorxor opened this issue Jan 4, 2025 · 4 comments
Open

[Question] Security Concerns with Email Invitation Policy #655

andnorxor opened this issue Jan 4, 2025 · 4 comments

Comments

@andnorxor
Copy link

andnorxor commented Jan 4, 2025

I'm no security researcher, but the policy provided for email invitation
https://github.com/azure-ad-b2c/samples/blob/master/policies/invite-via-email/policy/GenerateInviteToken.xml

... relies on the following for security:

  • Knowledge of the client ID: The attacker needs to know the client ID of an application in Azure AD B2C (which is a UUID v4).
  • Knowledge of the policy's /authorize endpoint (optional): This can be determined if the sample is copied as-is without modification.
  • Nonce validation (optional): While this offers additional protection, it's only effective if properly validated at the redeem invite endpoint.

Although the design appears to seem secure enough in the best-case scenario (e.g., with a different policy name and proper nonce validation), for the worst case scenario relying primarily on the UUID of an application for security feels insufficient. UUIDs are not intended to serve as secure secrets, and this design may leave the invitation process vulnerable to exploitation if the UUID is exposed (by just asking for it) or guessed.

If my conclusions are correct, I would at least suggest enhancing the README to include

  • Clear guidance on how to implement stronger security measures (e.g., use of additional secrets or more robust validation mechanisms, firewall rules, validation of the redirect_uri).
  • Explicit recommendations for modifying policy names and enforcing nonce validation to minimize the risk of abuse.
@jasjeetsuri
Copy link
Contributor

jasjeetsuri commented Jan 5, 2025

The policy generates a link with a signed JWT appended to it, id_token_hint query parameter.

Only you have the private key to generate this JWT.

The trust is then left to the users email provider being uncompromised.

A user can’t just generate the link using a client id. They need to compromise your private key to create a JWT that is appended to the link too.

If you think the link itself maybe hi jacked, then you could ask the user to perform some action in the redemption journey to prove they are who they say they are. For example, have them create a pin in the generate journey and have them type that pin at redemption.

@andnorxor
Copy link
Author

andnorxor commented Jan 6, 2025

@jasjeetsuri Just to clarify: I'm not referring to the security of the JWT itself I'm referring to the endpoint exposed by the Azure B2C custom policy B2C_1A_INV_genlink which in the provided example is exposed to the public without any authentication.

This is the endpoint I'm referring to. It accepts some query parameters and generates a token without any authentication.

string url = string.Format("https://{0}/{1}/B2C_1A_INV_genlink/oauth2/v2.0/authorize?client_id={2}&nonce={3}" 
                    + "&redirect_uri={4}&scope=openid&response_type=id_token&disable_cache=true&login_hint={5}&displayName={6}"
                     , hostName, tenantName, clientId, nonce, redirectUri, email, displayName );

https://github.com/azure-ad-b2c/samples/blob/d6d5e2118174dc8e5bdc0ab1b0b125c3d6dfe060/policies/invite-via-email/source-code/run.csx#L40C9-L42C97

In contrast the example in https://github.com/azure-ad-b2c/samples/blob/master/policies/invite/README.md accepts a signed JWT as input, which is way better.

@jasjeetsuri
Copy link
Contributor

jasjeetsuri commented Jan 6, 2025

Got it. The actual reason for this sample is for admins who want to use a link to verify an email instead of an email OTP that the user must type out. Hence the lack of auth on the generate journey, it is serving its purpose of self service sign up.

The samples are atomic, so you can combine any of them as you create something that best suits your needs.

@andnorxor
Copy link
Author

andnorxor commented Jan 6, 2025

Thank you for the clarification. It seems this is a different use case then. My confusion stemmed from concerns about the potential lack of security mechanisms. And I've just discovered the other example now.

Perhaps this could be highlighted in the README, though that's just a suggestion. From my side, this issue can be considered resolved and closed.

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