Skip to content

Transient failure to refresh a key ring produces a 500 response #33116

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

Closed
mdomashchenko opened this issue May 28, 2021 · 4 comments
Closed

Transient failure to refresh a key ring produces a 500 response #33116

mdomashchenko opened this issue May 28, 2021 · 4 comments
Labels
area-dataprotection Includes: DataProtection investigate

Comments

@mdomashchenko
Copy link

Here's how it happens:

  1. A request comes in, with a cookie. Cookie handler needs to decrypt the cookie, this ultimately results in a call to KeyRingBasedDataProtector.UnprotectCore()
  2. UnprotectCore calls KeyRingProvider.GetCurrentKeyRingCore to get keys. The latter determines that it needs to refresh the key ring from the repository.
  3. The repository experiences some transient failure and throws an exception. At this time the KeyRingProvider does have the key ring available, so it extends its lifetime for 2 minutes and reports that from here
    _logger.ErrorOccurredWhileRefreshingKeyRing(ex);
  4. Now, instead of just returning the old key ring with freshly extended lifetime, KeyRingProvider re-throws the exception. Rationale for that is described here
    // The immediate caller should fail so that they can report the error up the chain. This makes it more likely
    // that an administrator can see the error and react to it as appropriate. The caller can retry the operation
    // and will probably have success as long as they fall within the temporary extension mentioned above.
  5. The problem is, KeyRingBasedDataProtector.UnprotectCore does not retry. If it did, it would get the key ring, because it's lifetime was just extended. But it just doesn't make that second call to GetCurrentKeyRing
    var currentKeyRing = _keyRingProvider.GetCurrentKeyRing();
  6. So, the cookie is not decrypted, authentication handler fails and the error leaks to the caller as a 500 response, which is completely preventable.

Here's a stack trace for your reference

at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.GetAllKeys()
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.ICacheableKeyRingProvider.GetCacheableKeyRing(DateTimeOffset now)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.GetCurrentKeyRingCore(DateTime utcNow, Boolean forceRefresh)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)

@mkArtakMSFT mkArtakMSFT added area-dataprotection Includes: DataProtection investigate labels May 28, 2021
@mkArtakMSFT mkArtakMSFT added this to the Next sprint planning milestone Jun 3, 2021
@ghost
Copy link

ghost commented Jun 3, 2021

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@HaoK
Copy link
Member

HaoK commented Sep 8, 2021

Tracked as part of #33116

@HaoK HaoK removed their assignment Sep 8, 2021
@ghost
Copy link

ghost commented Nov 16, 2022

Thanks for contacting us.
We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@amcasey
Copy link
Member

amcasey commented Jan 24, 2024

This is definitely worth fixing and we're planning to prioritize it in 9.0, but I don't think this particular issue adds new details to the general understanding of the key creation/synchronization race. Tracked in #36157 and elsewhere.

@amcasey amcasey closed this as completed Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dataprotection Includes: DataProtection investigate
Projects
None yet
Development

No branches or pull requests

5 participants