-
-
Notifications
You must be signed in to change notification settings - Fork 103
Remove HMAC caching by token #256
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
Remove HMAC caching by token #256
Conversation
Codecov Report
@@ Coverage Diff @@
## main #256 +/- ##
===================================
- Coverage 85% 85% -1%
===================================
Files 74 74
Lines 2028 2025 -3
Branches 297 296 -1
===================================
- Hits 1734 1730 -4
- Misses 210 212 +2
+ Partials 84 83 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
|
What are you on about? Can you please raise an issue proving a bug in the implementation. There is protocol here and you’re not following it and adding unnecessary work for me chasing down random comments littered though the development history. |
I thought this was just too obvious if you look at this single line of code:
The HMAC is generated based on the information in the |
|
Wouldn't the fix then be as simple as using the full encoded (or even display) URL as the key? Although the overhead of that might well negate the benefit of caching. |
| [InlineData("Over the lazy dog.", "2ea9f37afac5ae93e27d835cc6061ad84b31064ae29f451c9136e88ad5686a1e")] | ||
| public void CanGenerate256BitHMAC(string value, string expected) | ||
| { | ||
| string expected = HMACUtilities.ComputeHMACSHA256(value, HMACSecretKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't understand why you changed these tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because checking Assert.Equal(expected, actual); doesn't make sense if they're both generated exactly the same way...
The only valuable assertion is whether the length is correct (okay and that it doesn't throw exceptions), but if it would generate a static string of the correct length, this test will still succeed!
| // First check for a HMAC token and capture before the command is stripped out. | ||
| byte[] secret = this.options.HMACSecretKey; | ||
| bool checkHMAC = false; | ||
| bool computeHMAC = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the variable name here incorrectly changes the meaning of the bool field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's because the meaning has changed! Instead of always requiring a valid token when a secret is configured, it's dependent on whether the OnComputeHMACAsync returns null or not.
Together with removing the caching, this allows you to bypass the HMAC check based on the request, e.g. whether a user is logged in.
Prerequisites
Description
As mentioned in https://github.com/SixLabors/ImageSharp.Web/pull/250/files#r857755086, caching generated HMACs based on the token completely bypasses the validation, because the cache key doesn't change when the commands are changed and therefore returns the same valid HMAC when the token is used with different commands.
I've thought about creating a better key for the HMAC cache, but that would also require additional processing and you might get similar issues when that cache key doesn't use the same information as
OnComputeHMACAsyncdoes (e.g. the HMAC cache key uses a relative URL, but the HMAC is computed using an absolute URL).The overhead of generating HMACs is also relatively low and attackers could otherwise just change the URL slightly to bypass the cached HMACs anyway. This is why I think completely removing the HMAC cache seems like the most reasonable fix.
You can quickly test this by using the following code and appending
&hmac=with the logged value: