Browse Source

Update the GenerateLoginCorrelationCookie handler to throw an exception if the request forgery protection was set to null

pull/1517/head
Kévin Chalet 4 years ago
parent
commit
00aa558511
  1. 6
      src/OpenIddict.Abstractions/OpenIddictResources.resx
  2. 22
      src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs
  3. 22
      src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs

6
src/OpenIddict.Abstractions/OpenIddictResources.resx

@ -1325,6 +1325,12 @@ Alternatively, you can disable the token storage feature by calling 'services.Ad
<data name="ID0342" xml:space="preserve"> <data name="ID0342" xml:space="preserve">
<value>Identical issuers cannot be used in multiple client registrations.</value> <value>Identical issuers cannot be used in multiple client registrations.</value>
</data> </data>
<data name="ID0343" xml:space="preserve">
<value>The request forgery protection claim cannot be resolved from the challenge context.</value>
</data>
<data name="ID0344" xml:space="preserve">
<value>The request forgery protection claim cannot be resolved from the sign-out context.</value>
</data>
<data name="ID2000" xml:space="preserve"> <data name="ID2000" xml:space="preserve">
<value>The security token is missing.</value> <value>The security token is missing.</value>
</data> </data>

22
src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs

@ -279,12 +279,13 @@ public static partial class OpenIddictClientAspNetCoreHandlers
.ToString(); .ToString();
// Try to find the cookie matching the request forgery protection stored in the state. // Try to find the cookie matching the request forgery protection stored in the state.
// The correlation cookie serves as a binding mechanism ensuring that a state token
// stolen from an authorization response with the other parameters cannot be validly
// used without sending the matching correlation identifier used as the cookie name.
// //
// If the cookie cannot be found, this may indicate that the authorization response // If the cookie cannot be found, this may indicate that the authorization response
// is unsolicited and potentially malicious. This may also be caused by an unadequate // is unsolicited and potentially malicious or be caused by an invalid or unadequate
// same-site configuration. The correlation cookie also serves as a binding mechanism // same-site configuration.
// ensuring that a state token stolen from an authorization response with the other
// parameters cannot be validly used without sending the matching correlation identifier.
// //
// In any case, the authentication demand MUST be rejected as it's impossible to ensure // In any case, the authentication demand MUST be rejected as it's impossible to ensure
// it's not an injection or session fixation attack without the correlation cookie. // it's not an injection or session fixation attack without the correlation cookie.
@ -525,6 +526,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers
public static OpenIddictClientHandlerDescriptor Descriptor { get; } public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessChallengeContext>() = OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessChallengeContext>()
.AddFilter<RequireHttpRequest>() .AddFilter<RequireHttpRequest>()
.AddFilter<RequireInteractiveGrantType>()
.AddFilter<RequireLoginStateTokenGenerated>() .AddFilter<RequireLoginStateTokenGenerated>()
.UseSingletonHandler<GenerateLoginCorrelationCookie>() .UseSingletonHandler<GenerateLoginCorrelationCookie>()
.SetOrder(AttachChallengeParameters.Descriptor.Order + 1_000) .SetOrder(AttachChallengeParameters.Descriptor.Order + 1_000)
@ -543,12 +545,12 @@ public static partial class OpenIddictClientAspNetCoreHandlers
// will always be rejected if a cookie corresponding to the request forgery protection claim // will always be rejected if a cookie corresponding to the request forgery protection claim
// persisted in the state token cannot be found. This protection is considered essential // persisted in the state token cannot be found. This protection is considered essential
// in OpenIddict and cannot be disabled via the options. Applications that prefer implementing // in OpenIddict and cannot be disabled via the options. Applications that prefer implementing
// a different protection strategy can set the request forgery protection claim to null or // a different protection strategy can remove this handler from the handlers list and add
// remove this handler from the handlers list and add a custom one using a different approach. // a custom one using a different approach (e.g by storing the value in the session state).
if (string.IsNullOrEmpty(context.RequestForgeryProtection)) if (string.IsNullOrEmpty(context.RequestForgeryProtection))
{ {
return default; throw new InvalidOperationException(SR.GetResourceString(SR.ID0343));
} }
Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
@ -711,12 +713,12 @@ public static partial class OpenIddictClientAspNetCoreHandlers
// will always be rejected if a cookie corresponding to the request forgery protection claim // will always be rejected if a cookie corresponding to the request forgery protection claim
// persisted in the state token cannot be found. This protection is considered essential // persisted in the state token cannot be found. This protection is considered essential
// in OpenIddict and cannot be disabled via the options. Applications that prefer implementing // in OpenIddict and cannot be disabled via the options. Applications that prefer implementing
// a different protection strategy can set the request forgery protection claim to null or // a different protection strategy can remove this handler from the handlers list and add
// remove this handler from the handlers list and add a custom one using a different approach. // a custom one using a different approach (e.g by storing the value in the session state).
if (string.IsNullOrEmpty(context.RequestForgeryProtection)) if (string.IsNullOrEmpty(context.RequestForgeryProtection))
{ {
return default; throw new InvalidOperationException(SR.GetResourceString(SR.ID0344));
} }
Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));

22
src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs

@ -280,12 +280,13 @@ public static partial class OpenIddictClientOwinHandlers
.ToString(); .ToString();
// Try to find the cookie matching the request forgery protection stored in the state. // Try to find the cookie matching the request forgery protection stored in the state.
// The correlation cookie serves as a binding mechanism ensuring that a state token
// stolen from an authorization response with the other parameters cannot be validly
// used without sending the matching correlation identifier used as the cookie name.
// //
// If the cookie cannot be found, this may indicate that the authorization response // If the cookie cannot be found, this may indicate that the authorization response
// is unsolicited and potentially malicious. This may also be caused by an unadequate // is unsolicited and potentially malicious or be caused by an invalid or unadequate
// same-site configuration. The correlation cookie also serves as a binding mechanism // same-site configuration.
// ensuring that a state token stolen from an authorization response with the other
// parameters cannot be validly used without sending the matching correlation identifier.
// //
// In any case, the authentication demand MUST be rejected as it's impossible to ensure // In any case, the authentication demand MUST be rejected as it's impossible to ensure
// it's not an injection or session fixation attack without the correlation cookie. // it's not an injection or session fixation attack without the correlation cookie.
@ -555,6 +556,7 @@ public static partial class OpenIddictClientOwinHandlers
public static OpenIddictClientHandlerDescriptor Descriptor { get; } public static OpenIddictClientHandlerDescriptor Descriptor { get; }
= OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessChallengeContext>() = OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessChallengeContext>()
.AddFilter<RequireOwinRequest>() .AddFilter<RequireOwinRequest>()
.AddFilter<RequireInteractiveGrantType>()
.AddFilter<RequireLoginStateTokenGenerated>() .AddFilter<RequireLoginStateTokenGenerated>()
.UseSingletonHandler<GenerateLoginCorrelationCookie>() .UseSingletonHandler<GenerateLoginCorrelationCookie>()
.SetOrder(AttachChallengeParameters.Descriptor.Order + 1_000) .SetOrder(AttachChallengeParameters.Descriptor.Order + 1_000)
@ -573,12 +575,12 @@ public static partial class OpenIddictClientOwinHandlers
// will always be rejected if a cookie corresponding to the request forgery protection claim // will always be rejected if a cookie corresponding to the request forgery protection claim
// persisted in the state token cannot be found. This protection is considered essential // persisted in the state token cannot be found. This protection is considered essential
// in OpenIddict and cannot be disabled via the options. Applications that prefer implementing // in OpenIddict and cannot be disabled via the options. Applications that prefer implementing
// a different protection strategy can set the request forgery protection claim to null or // a different protection strategy can remove this handler from the handlers list and add
// remove this handler from the handlers list and add a custom one using a different approach. // a custom one using a different approach (e.g by storing the value in the session state).
if (string.IsNullOrEmpty(context.RequestForgeryProtection)) if (string.IsNullOrEmpty(context.RequestForgeryProtection))
{ {
return default; throw new InvalidOperationException(SR.GetResourceString(SR.ID0343));
} }
Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));
@ -768,12 +770,12 @@ public static partial class OpenIddictClientOwinHandlers
// will always be rejected if a cookie corresponding to the request forgery protection claim // will always be rejected if a cookie corresponding to the request forgery protection claim
// persisted in the state token cannot be found. This protection is considered essential // persisted in the state token cannot be found. This protection is considered essential
// in OpenIddict and cannot be disabled via the options. Applications that prefer implementing // in OpenIddict and cannot be disabled via the options. Applications that prefer implementing
// a different protection strategy can set the request forgery protection claim to null or // a different protection strategy can remove this handler from the handlers list and add
// remove this handler from the handlers list and add a custom one using a different approach. // a custom one using a different approach (e.g by storing the value in the session state).
if (string.IsNullOrEmpty(context.RequestForgeryProtection)) if (string.IsNullOrEmpty(context.RequestForgeryProtection))
{ {
return default; throw new InvalidOperationException(SR.GetResourceString(SR.ID0344));
} }
Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); Debug.Assert(context.StateTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006));

Loading…
Cancel
Save