🏡 | ⬅️ Notes | 2023_11_27_OpenID_Connect.md

#zero

Recent HN posting - Easy to use OpenID Connect client and server library written for Go https://news.ycombinator.com/item?id=38496264

I can't recommend enough Zitadel and its OIDC library. Code is very well-writen and informative.

1. IntrospectionResponse

Highly encourage everyone jump into source code and explore how IntrospectionResponse struct work with all related code around zitadel/oidc/blob/main/pkg/oidc/introspec...

// IntrospectionResponse implements RFC 7662, section 2.2 and
// OpenID Connect Core 1.0, section 5.1 (UserInfo).
type IntrospectionResponse struct {
	Active     bool                `json:"active"`
	Scope      SpaceDelimitedArray `json:"scope,omitempty"`
	ClientID   string              `json:"client_id,omitempty"`
	TokenType  string              `json:"token_type,omitempty"`
	Expiration Time                `json:"exp,omitempty"`
	IssuedAt   Time                `json:"iat,omitempty"`
	NotBefore  Time                `json:"nbf,omitempty"`
	Subject    string              `json:"sub,omitempty"`
	Audience   Audience            `json:"aud,omitempty"`
	Issuer     string              `json:"iss,omitempty"`
	JWTID      string              `json:"jti,omitempty"`
	Username   string              `json:"username,omitempty"`
	UserInfoProfile
	UserInfoEmail
	UserInfoPhone

	Address *UserInfoAddress `json:"address,omitempty"`
	Claims  map[string]any   `json:"-"`
}

2. Identity Providers

Start from exploring the difference between identity providers by clicking through nextauthjs/next-auth/tree/main/packages/c...

export default function Instagram(
  config: OAuthUserConfig<Record<string, any>>
): OAuthConfig<Record<string, any>> {
  return {
    id: "instagram",
    name: "Instagram",
    type: "oauth",
    authorization:
      "[https://api.instagram.com/oauth/authorize?scope=user_profile",](https://api.instagram.com/oauth/authorize?scope=user_profile",)
    token: "[https://api.instagram.com/oauth/access_token",](https://api.instagram.com/oauth/access_token",)
    userinfo:
      "[https://graph.instagram.com/me?fields=id,username,account_type,name",](https://graph.instagram.com/me?fields=id,username,account_type,name",)
    client: {
      token_endpoint_auth_method: "client_secret_post",
    },
    async profile(profile) {
      return {
        id: profile.id,
        name: profile.username,
        email: null,
        image: null,
      }
    },
    style: {
      logo: "/instagram.svg",
      bg: "#fff",
      text: "#000",
    },
    options: config,
  }
}

Azure is the most insane ... and it's a lot of fun to compare them all against each other.

3. PKCE (Proof Key for Code Exchange)

Next challenge is to go though PKCE and look how code_challenge, code_verifier works or at least see interfaces.

4. Alternatives

Ory Fosite is a great alternative too https://github.com/ory/fosite

Support PKCE #59835 in x/oauth2 https://github.com/golang/go/issues/59835

5. Youtube Videos

Scott Brady's content is great for undetstanding the topic

SPA Identity and Access Control with OpenID Connect https://www.youtube.com/watch?v=rP3St0GU_Bk  OAuth is Not Authentication https://www.scottbrady91.com/oauth/oauth-is-not-authenticati...

SPA is a landmine ..

OAuth 2.0 and OpenID Connect for Single Page Applications Philippe De Ryck https://www.youtube.com/watch?v=XoBtUn4XczU

The deeper you go into the topic the more you will discover. It's an ultimate "rabbit hole" - web, native, SPA flows, PKCE, JWT, session storage, custome middleware for your favorite flavor of backend framework, etc

6. Unsorted

  1. PKCE "Code" vs "ID Token" vs "Token-ID Token" flow
  2. Grant Type "Autorization Code" vs "Implicit" vs "Device Code" vs "Refresh Token"
  3. https://github.com/gorilla/securecookie

Testing against https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/facebook.ts

  • Google
  • Azure
  • Keyclock
  • Zitadel
  • Auth0

img

In the PKCE (Proof Key for Code Exchange) secure flow of OAuth 2.0, the user's login and password are typically not handled directly by the client application. Instead, these credentials are entered during the authorization process, which usually occurs on a webpage hosted by the authorization server (also known as the identity provider). Here's how it typically works in the PKCE flow:

  1. Client Initiates Authorization Request:

    • The client application redirects the user to the authorization server's login page. This redirect includes the code_challenge and other necessary OAuth parameters but does not include any user credentials.
  2. User Enters Credentials:

    • On the authorization server's login page, the user enters their login credentials (username and password). This step is crucial as it ensures that the user's credentials are entered directly on the server's page, not in the client application, enhancing security.
  3. Authorization Server Validates Credentials:

    • The authorization server verifies the user's credentials. If the credentials are correct and the user grants consent for the requested permissions, the server issues an authorization code to the client application.
    • Importantly, this authorization code is sent to the client's redirection endpoint (usually as part of the URL query parameters) and not the credentials themselves.
  4. Token Exchange with code_verifier:

    • The client then uses the received authorization code along with its previously generated code_verifier to request an access token from the token endpoint of the authorization server.
    • At no point during this token request are the user's credentials sent by the client. The code_verifier is used to securely prove that the client making the token request is the same one that initiated the authorization request.
  5. Access Token Issued:

    • If the code_verifier matches the code_challenge (which the authorization server received and stored earlier), the server issues an access token (and possibly an ID token in OpenID Connect flows) to the client.

code_challenge, code_verifier

Key Takeaway

  • In the PKCE-enhanced authorization code flow, the client application never handles the user's login and password directly. The credentials are entered on the authorization server's interface, and the client only handles the authorization code and the code_verifier. This separation of concerns is a fundamental aspect of OAuth's design, contributing significantly to its security.

The OAuth 2.1 Authorization Framework [https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-09#name-redirect-uri-parameter-in-t](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-09#name-redirect-uri-parameter-in-t)

https://openwallet.foundation/governing-board/ https://www.youtube.com/watch?v=PcGaompHYbk https://www.youtube.com/@Identiverse/videos

img

OpenID Connect is an interoperable authentication protocol based on the OAuth 2.0 framework of specifications (IETF RFC 6749 and 6750).

img

Passwordless login with passkeys https://developers.google.com/identity/passkeys

The OAuth 2.1 Authorization Framework [https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-09#name-redirect-uri-parameter-in-t](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-09#name-redirect-uri-parameter-in-t)

D. Hardt HellĹŤ A. Parecki Okta T. Lodderstedt yes.com

  • Introduction to Single Sign-On

    • OAuth and OpenID Connect Flows

    • Code Flow / Implicit Flow / Hybrid Flow

  • Generic Attacks on SSO Procedures

    • XSS, Clickjacking, CSRF, Open/Covert Redirects

    • OAuth- and OpenID Connect-specific Attacks

    • ID Token: Details and Attacks

  • Single-Phase Attacks

    • ID Spoofing Attacks

    • Signature Bypasses

  • Cross-Phase Attacks

    • Issuer Confusion

    • Malicious Endpoint Angriffe

    • IdP Confusion / Mix-Up

  • Security Best Practices

    • PKCE

    • Native Apps

    • Single-Page-Applications (SPAs)

  • Secure Token Bindings

    • Mutual TLS

    • DPoP

img

Registration:

  • User is prompted to choose an available FIDO authenticator that matches the online service’s acceptance policy.

  • User unlocks the FIDO authenticator using a fingerprint reader, a button on a second–factor device, securely–entered PIN or other method.

  • User’s device creates a new public/private key pair unique for the local device, online service and user’s account.

  • Public key is sent to the online service and associated with the user’s account. The private key and any information about the local authentication method (such as biometric measurements or templates) never leave the local device.

img

img

Very Good: FIDO2 (software) and FIDO2 (physical) factors are based on the FIDO2 specifications [3]. These consist of the two specifications Web Authentication (WebAuthn)[4] and Client-to-Authenticator Protocol (CTAP)[5]. When creating these protocols, security was an important main point, which is also evident in practice.

Good: TOTP (software) and TOTP (physical) both have reasonably good phishing security due to the usually very short validity of the generated codes. However, a major disadvantage is that both the user and the service are in possession of the same shared secret. In case of a compromise of the shared secrets at the service provider, the attacker can use the shared secret himself in a TOTP app to generate valid codes and access the victim’s account.

[1] https://fidoalliance.org/fido2/ [2] https://fidoalliance.org/content/case-study/ [3] https://web.dev/yahoo-japan-identity-case-study/ [4] https://fidoalliance.org/yahoo-japans-password-free-authentication-reduced-inquiries-by-25-sped-up-sign-in-time-by-2-6x/ [5] https://fidoalliance.org/national-health-service-uses-fido-authentication-for-enhanced-login/ [6] https://krebsonsecurity.com/2018/07/google-security-keys-neutralized-employee-phishing/ [7] https://fidoalliance.org/apple-google-and-microsoft-commit-to-expanded-support-for-fido-standard-to-accelerate-availability-of-passwordless-sign-ins/

When implementing OpenID Connect (OIDC) for Single Page Applications (SPAs), there are several security considerations to be aware of, especially related to redirects. Here's what you should know:

Key Considerations

  1. Redirect URIs:

    • Whitelist Redirect URIs: Only whitelist specific redirect URIs in your OIDC provider configuration to prevent unauthorized redirects.
    • Avoid Open Redirects: Ensure that your application does not have open redirect vulnerabilities, where an attacker could insert a malicious URL to redirect users after authentication.
  2. Token Handling:

    • Avoid Storing Tokens in Local Storage: Access tokens or ID tokens should not be stored in local storage due to the risk of XSS (Cross-Site Scripting) attacks. Use HTTP-only, secure cookies or session storage instead.
    • Token Leakage: Be cautious of token leakage via referrer headers when navigating away from your SPA.
  3. Cross-Site Request Forgery (CSRF) Protection:

    • Implement CSRF tokens in OAuth flows to ensure that the redirect back to your application after authentication is legitimate.
  4. XSS (Cross-Site Scripting) Attacks:

    • Ensure your SPA is secure against XSS, as this can lead to token theft. Always encode output, use Content Security Policy (CSP), and avoid inline scripts.
  5. Client-Side Security:

    • Implement strong input validation and output encoding to mitigate injection attacks.
    • Keep third-party libraries up to date to avoid vulnerabilities.

How You Can Be Hacked

  1. Redirect URI Exploitation:

    • If an attacker can manipulate the redirect URI, they can redirect users to a malicious site after authentication.
  2. Token Theft via XSS:

    • If an attacker can inject malicious scripts into your SPA, they could steal tokens stored in local storage or session storage.
  3. CSRF Attacks:

    • Without proper CSRF protection, an attacker could trick a user into initiating an authentication request that benefits the attacker.
  4. Clickjacking:

    • If your SPA is vulnerable to clickjacking, an attacker could trick users into executing unintended actions.
  5. Phishing Attacks:

    • Users could be tricked into providing credentials or tokens to a fake authentication page.

Best Practices

  • Use secure, HTTP-only cookies for session management.
  • Implement Content Security Policy (CSP) to reduce the risk of XSS.
  • Validate and sanitize all user inputs to prevent injection attacks.
  • Regularly update and audit third-party libraries and dependencies.
  • Educate users about phishing and the importance of verifying URLs.

By being aware of these risks and implementing best practices, you can significantly reduce the chances of being hacked in an OIDC implementation for SPAs. It's crucial to stay updated with the latest security practices and to regularly review and update your application's security measures.

  1. OpenID Connect Core: This is the foundational specification, and it hasn't been updated to a "2.0" or "2.1" version. It remains a robust and widely implemented protocol for user authentication.

  2. OAuth 2.1: This proposed update to OAuth 2.0 aims to make things simpler and more secure by incorporating several extensions and best practices that have become widely adopted. Changes include enforcing the use of PKCE (Proof Key for Code Exchange) in all OAuth flows, using only secure authorization codes in OAuth authorization code flow, and removing implicit and password grant types, among others.

OpenID Connect Providers and OAuth 2.1

As for identity providers implementing OAuth 2.1 or its best practices (which would directly affect how OpenID Connect operates), many leading providers continuously update their services to align with the latest security standards and best practices. Some of these providers include:

  • Auth0
  • Okta
  • Google Identity Platform
  • Microsoft Identity Platform (Azure AD)
  • Amazon Cognito

These providers often integrate the latest recommendations and practices from the OAuth working group and the OpenID Foundation to ensure security and compliance. However, since OAuth 2.1 is still a draft as of my last update, explicit support for "OAuth 2.1" might not be widely marketed or specifically noted. Instead, providers tend to continuously incorporate individual improvements and recommendations from the OAuth community into their existing OAuth 2.0 and OpenID Connect implementations.

Always check with the specific identity provider for the most current information on their support and implementation of OAuth and OpenID Connect standards.

Ilya Elias S
Ilya Elias S @reactima
React/TS/Node/Python/Golang Coder
🇯🇵 Japan Permanent Resident
Used to live in 🇺🇦🇺🇸🇸🇬🇭🇰🇬🇪🇳🇱
Interested to discuss the above or looking for a partner to work on Data Mining, Recruitment, B2B Lead Generation and/or Outbound SaaS related projects?
Feel free to ping me to exchange ideas or request a consultation!