mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-14 03:54:21 +00:00
fix(oidc): return bad request for base64 errors (#7730)
* fix(oidc): return bad request for base64 errors
We've recently noticed an increased amount of 500: internal server error status returns on zitadel cloud.
The source of these errors appear to be erroneous input in fields that are supposed to be bas64 formatted.
```
time=2024-04-08T14:05:47.600Z level=ERROR msg="request error" oidc_error.parent="ID=OIDC-AhX2u Message=Errors.Internal Parent=(illegal base64 data at input byte 8)" oidc_error.description=Errors.Internal oidc_error.type=server_error status_code=500
```
Within the possible code paths of the token endpoint there are a couple of uses of base64.Encoding.DecodeString of which a returned error was not properly wrapped, but returned as-is.
This causes the oidc error handler to return a 500 with the `OIDC-AhX2u` ID.
We were not able to pinpoint the exact errors that are happening to any one call of `DecodeString`.
This fix wraps all errors from `DecodeString` so that proper 400: bad request is returned with information about the error. Each wrapper now has an unique error ID, so that logs will contain the source of the error as well.
This bug was reported internally by the ops team.
* catch op.ErrInvalidRefreshToken
(cherry picked from commit c8e0b30e17
)
This commit is contained in:
parent
63c7364159
commit
7a34697267
@ -19,7 +19,7 @@ func SessionTokenVerifier(algorithm crypto.EncryptionAlgorithm) func(ctx context
|
||||
return func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) {
|
||||
decodedToken, err := base64.RawURLEncoding.DecodeString(sessionToken)
|
||||
if err != nil {
|
||||
return err
|
||||
return zerrors.ThrowInvalidArgument(err, "COMMAND-hi6Ph", "Errors.Session.Token.Invalid")
|
||||
}
|
||||
_, spanPasswordComparison := tracing.NewNamedSpan(ctx, "crypto.CompareHash")
|
||||
token, err := algorithm.DecryptString(decodedToken, algorithm.EncryptionKeyID())
|
||||
|
@ -157,7 +157,7 @@ func (o *OPStorage) AuthRequestByCode(ctx context.Context, code string) (_ op.Au
|
||||
|
||||
plainCode, err := o.decryptGrant(code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, zerrors.ThrowInvalidArgument(err, "OIDC-ahLi2", "Errors.User.Code.Invalid")
|
||||
}
|
||||
if strings.HasPrefix(plainCode, command.IDPrefixV2) {
|
||||
authReq, err := o.command.ExchangeAuthCode(ctx, plainCode)
|
||||
@ -311,7 +311,7 @@ func (o *OPStorage) TokenRequestByRefreshToken(ctx context.Context, refreshToken
|
||||
|
||||
plainToken, err := o.decryptGrant(refreshToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, op.ErrInvalidRefreshToken
|
||||
}
|
||||
if strings.HasPrefix(plainToken, command.IDPrefixV2) {
|
||||
oidcSession, err := o.command.OIDCSessionByRefreshToken(ctx, plainToken)
|
||||
|
@ -19,7 +19,9 @@ func oidcError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if errors.Is(err, op.ErrInvalidRefreshToken) {
|
||||
err = zerrors.ThrowInvalidArgument(err, "OIDCS-ef2Gi", "Errors.User.RefreshToken.Invalid")
|
||||
}
|
||||
var (
|
||||
sError op.StatusError
|
||||
oError *oidc.Error
|
||||
|
@ -207,7 +207,7 @@ func (c *Commands) getResourceOwnerOfSessionUser(ctx context.Context, userID, in
|
||||
func (c *Commands) decryptRefreshToken(refreshToken string) (refreshTokenID string, err error) {
|
||||
decoded, err := base64.RawURLEncoding.DecodeString(refreshToken)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", zerrors.ThrowInvalidArgument(err, "OIDCS-Cux9a", "Errors.User.RefreshToken.Invalid")
|
||||
}
|
||||
decrypted, err := c.keyAlgorithm.DecryptString(decoded, c.keyAlgorithm.EncryptionKeyID())
|
||||
if err != nil {
|
||||
|
@ -23,7 +23,7 @@ func RefreshToken(userID, tokenID, token string, algorithm crypto.EncryptionAlgo
|
||||
func FromRefreshToken(refreshToken string, algorithm crypto.EncryptionAlgorithm) (userID, tokenID, token string, err error) {
|
||||
decoded, err := base64.RawURLEncoding.DecodeString(refreshToken)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return "", "", "", zerrors.ThrowInvalidArgument(err, "DOMAIN-BGDhn", "Errors.User.RefreshToken.Invalid")
|
||||
}
|
||||
decrypted, err := algorithm.Decrypt(decoded, algorithm.EncryptionKeyID())
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user