Skip to content

Commit 509e0de

Browse files
hfissuedat
authored andcommitted
fix: accept ID tokens from all account.apple.com and appleid.apple.com (#2050)
Apple seems to have swapped the issuer without notice from `https://appleid.apple.com` to `https://account.apple.com`
1 parent 1af85b4 commit 509e0de

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

internal/api/provider/apple.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package provider
22

33
import (
44
"context"
5+
"encoding/base64"
56
"encoding/json"
7+
"fmt"
68
"net/url"
79
"strconv"
810
"strings"
@@ -13,7 +15,34 @@ import (
1315
"golang.org/x/oauth2"
1416
)
1517

16-
const IssuerApple = "https://appleid.apple.com"
18+
const DefaultAppleIssuer = "https://account.apple.com"
19+
const OtherAppleIssuer = "https://appleid.apple.com"
20+
21+
func IsAppleIssuer(issuer string) bool {
22+
return issuer == DefaultAppleIssuer || issuer == OtherAppleIssuer
23+
}
24+
25+
func DetectAppleIDTokenIssuer(ctx context.Context, idToken string) (string, error) {
26+
var payload struct {
27+
Issuer string `json:"iss"`
28+
}
29+
30+
parts := strings.Split(idToken, ".")
31+
if len(parts) != 3 {
32+
return "", fmt.Errorf("apple: invalid ID token")
33+
}
34+
35+
payloadBytes, err := base64.RawURLEncoding.DecodeString(parts[1])
36+
if err != nil {
37+
return "", fmt.Errorf("apple: invalid ID token %w", err)
38+
}
39+
40+
if err := json.Unmarshal(payloadBytes, &payload); err != nil {
41+
return "", fmt.Errorf("apple: invalid ID token %w", err)
42+
}
43+
44+
return payload.Issuer, nil
45+
}
1746

1847
// AppleProvider stores the custom config for apple provider
1948
type AppleProvider struct {
@@ -68,7 +97,7 @@ func NewAppleProvider(ctx context.Context, ext conf.OAuthProviderConfiguration)
6897
logrus.Warn("Apple OAuth provider has URL config set which is ignored (check GOTRUE_EXTERNAL_APPLE_URL)")
6998
}
7099

71-
oidcProvider, err := oidc.NewProvider(ctx, IssuerApple)
100+
oidcProvider, err := oidc.NewProvider(ctx, DefaultAppleIssuer)
72101
if err != nil {
73102
return nil, err
74103
}

internal/api/provider/oidc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ func ParseIDToken(ctx context.Context, provider *oidc.Provider, config *oidc.Con
5555
switch token.Issuer {
5656
case IssuerGoogle:
5757
token, data, err = parseGoogleIDToken(token)
58-
case IssuerApple:
59-
token, data, err = parseAppleIDToken(token)
6058
case IssuerLinkedin:
6159
token, data, err = parseLinkedinIDToken(token)
6260
case IssuerKakao:
@@ -66,6 +64,8 @@ func ParseIDToken(ctx context.Context, provider *oidc.Provider, config *oidc.Con
6664
default:
6765
if IsAzureIssuer(token.Issuer) {
6866
token, data, err = parseAzureIDToken(token)
67+
} else if IsAppleIssuer(token.Issuer) {
68+
token, data, err = parseAppleIDToken(token)
6969
} else {
7070
token, data, err = parseGenericIDToken(token)
7171
}

internal/api/token_oidc.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,22 @@ func (p *IdTokenGrantParams) getProvider(ctx context.Context, config *conf.Globa
3434
var acceptableClientIDs []string
3535

3636
switch true {
37-
case p.Provider == "apple" || p.Issuer == provider.IssuerApple:
37+
case p.Provider == "apple" || provider.IsAppleIssuer(p.Issuer):
3838
cfg = &config.External.Apple
3939
providerType = "apple"
40-
issuer = provider.IssuerApple
40+
issuer = p.Issuer
41+
if issuer == "" {
42+
detectedIssuer, err := provider.DetectAppleIDTokenIssuer(ctx, p.IdToken)
43+
if err != nil {
44+
return nil, false, "", nil, apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "Unable to detect issuer in ID token for Apple provider").WithInternalError(err)
45+
}
46+
47+
if provider.IsAppleIssuer(detectedIssuer) {
48+
issuer = detectedIssuer
49+
} else {
50+
return nil, false, "", nil, apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "Detected ID token issuer is not an Apple ID token issuer")
51+
}
52+
}
4153
acceptableClientIDs = append(acceptableClientIDs, config.External.Apple.ClientID...)
4254

4355
if config.External.IosBundleId != "" {

0 commit comments

Comments
 (0)