-
Notifications
You must be signed in to change notification settings - Fork 7
The incoming hash of the payload is being trusted and not verified #6
Comments
There doesn't appear to be any tests for generating or verifying that the optional payload validation i.e. specified via Many implementations may not use the optional feature and if they do many would not have audited this library to ensure the optional feature works as intended i.e. implements the security characteristics defined in the spec. |
Thanks for digging into the details here, and for the linked PR which I will take a look at shortly. The readme does mention that "Calculating or verifying payload hashes" is not supported, and the linked spec does say "It is up to the server if and when it validates the payload for any given request, based solely on its security policy and the nature of the data included". However, I do see a reasonable argument that users of the library could expect it to "fail closed" and reject any request with a payload hash, rather than "failing open" and just ignoring the provided hash. |
This is commentary only, in fact the signature is being calculated i.e. the signature is supported and includes the hash contrary to the quoted commentary. The obvious thing here is that the commentary is written by someone who ignores that the hash is included in the signature if provided therefore stating the hash is not supported is untruthful/unauthentic And worse, it implies the signature calculation is not following the specification - effectively when the signature is calculated using client provided values the entire purpose of Hawk Authentication is fundamentally broken, effectively not using Hawk at all and using it like this is identical from a security characteristics perspective. Taking the client provided values and trusting them provides zero assurances and is not following the Hawk Authentication specification at all. |
Just to be clear up-front: absolutely this library should let consumers perform proper payload validation, this is a missing feature and is a potential security footgun for consumers if they assume that payload validation is being performed automatically.
The canonical nodejs implementation checks the signature using the client-provided
Please stop with this hyperbole; being able to replay a captured request with different payload is very different from having no authentication at all. |
Saying hyperbole it not constructive, it is a plain attempt to discredit the reporter and frankly a rude and unethical way to avoid the truth. I read this quote of yours also, and wouldn't you agree that it is inauthentic if the spec algorithm states; Your quote is taken out of context.. Your own quote continues in context to clarify why the hash is calculated first with the client provided values; Obviously your quote was out of context. I acknowledge the first calculation is done using the client provided value, but only because it is faster. The spec continues to state that it should then use the server-side calculated verification. Notice it is independent of payload verification, it is just the basic specification choosing to be fast first and secure last. Next, specific to payload verification (if the optional hash is present) the server may chose to do payload verification - this is the intent of the quote you provided when you actually read the context. Simply using client provided values, phase 1, and ignoring the default phase 2 and 3 seems to be a security charade and this is not actually performing the basic expectation of Hawk spec at all in it's current form. Not hyperbole, just fact. |
Look at mohawk who follow the spec properly |
It's clear that we disagree on the severity of this issue, so I wanted to make another attempt at explaining where I'm coming from here without attempting to language-lawyer anything from the spec. After all, per the spec you linked, the code is the specification. The
The default behaviour of the reference implementation is to accept the client-provided The usage example from the spec document calls All of this leads me to believe that it is intentionally left up to the server whether to validate the provided Should this library provide the ability to validate the But I do not accept that this missing feature is "identical from a security characteristics perspective to not using Hawk at all" given that we behave identically to the reference implementation in its default configuration.
I don't understand what you mean here - what exactly is the server choosing to do or not do under your interpretation? |
I may have to step back from this security fix PR as it is clear that Hawk's security characteristic is and will always be defined and controlled by the client rather that give assurances to the server. If the server only trusts client values and only validates MAC Signature when a client directs it too, then Hawk is a solution to provide the Client assurances not the server. these led me to the above conclusion;
(conveniently ignoring If the MAC is valid
i.e. If the client provided MAC is VALID it still needs to have server-side validation of the MAC "Signature" which is Signature not "payload validation", it is still the MAC. so you promote client-side assurance step, but stop. You skip "If the MAC is valid" and anything after this for unknown reasons... But I have to accept that you believe this and i'll close the PR that implements ONLY what should happen AFTER "If the MAC is valid"..
client-side assurance
client-side assurance I'm guessing you meant "client" not server when you wrote Assuming this PR stays
no problem, it's been fun - contrary to "emotionless" text might seem..
Actually, i've never suggested payload validating is opt-out. I believe it should be opt-in or user journey 2 & 3 are not possible...
The API (linked above) already mandated that the hash is part of the Signature if it is provided (distinct from payload verification). I have no opinions that differ from that in the API document. What are the next steps? I'm left wondering;
|
Chris, assuming you do step away from this PR, are you happy for me to merge and build upon your work-in-progress? As stated, I do believe it's a valuable improvement. (But I wouldn't merge if if you weren't happy for us to do so).
Honestly, I am simply not able to parse what you mean here. Authentication both here and in the JS reference implementation checks the client-provided |
best to clarify this first
Stage 1 optional payload validationAs described you may have optional payload validation if the server wants to do so. This is well known and agreed upon. Assuming we do or do not perform the optional payload validation, stages 2 and 3 are distinct from payload validation. Stage 2, Check the Signature using client provided values
It is OK for the server to use the client provided MAC, if they do not match we early exit. We are agree so far, this is what you have argued and I always agree, in fact it is exactly how hawkauthlib works today.. BUT please continue reading the spec, hawkauthlib has not done the next stage to complete a valid Signature Check Stage 3 complete a valid Signature Checkquickly, Signature is (Included in the above from stage 2)
We reach your question here, i wrote, and you questioned the meaning. So i'll break it down;
that is stage 2 result
In stage 2 it used client provided value, for quick result / early exit
Specifically If the client did not provide a hash, stage 2 and stage 3 are identical and stage 3 is not needed. If the client did provide the hash, we must include the hash the client provided in stage 2 but in stage 3 we must not inherently trust the client value. Stage 3 is about server-side assurance. If the client provided the hash, and the stage 2 validation result was VALID this is not giving assurance. Stage 3 is where this PR adds to Hawk the missing completion to it's Signature check, the part it never had but should have had for server-side assurance. Happy to push on with the PR if we are aiming for server-side assurance of Signature checking If Hawk is to remain client assurance and optional server assurance, please use my PR contribution as you wish 👍 it's been fun |
I am keen to resolve the dispute so the new version can be released, while not actually patching the default behaviour it is at least offering the new secure functionality as a secure-if-configured securely option that implementations out there could leverage going forward. I wondered if I might be wrong, so I wen looking for Hawk implementations to confirm the view one way or the other, preferably a Mozilla example to reference. My hypothesis is the NodeS code that everything stemmed from was just poor coding, or poor interpretations, and the secure characteristics described by the spec (and an expectation of signed requests using a HMAC) was always the intention and goal. Either way it would provide closure 2 years on. Stefan Arentz @st3fan a former Mobile Browser Engineer at Mozilla - Interpreted the Hawk spec in the exact way I did for his Go implementation. Specifically the signature generation and then comparison calculates the hash from the payload. Nowhere in the implementation is the client provided hash simply taken and used in place of the signature generation prior to a proper validation. Stefan never takes the client signature for any signature assembly shortcuts, the signature is always assembling the payload if it is present, and will generate it's own hash for payload validation. An assembled signature that uses a client provided payload and client provided hash intended to validate the payload integrity, then not assemble the hash signature itself to do payload integrity checking (this repo) You have a situation where the client provided values are compared to client provided values - of course they match! What is the point of that? The logic is trash. Kumar McMillan @kumar303 author of mohawk (another python interpretation like this repo) also agrees with Stefan and my own view in his code. The only places I see the errors are the original nodejs that now exists only in the FXA fork, this repo, and mozilla/hawk (originally hapijs/hawk) . If you disagree with Kumar, Stefan's, and my own views, we may be wrong, please educate us. I am sure we can be all open minded, but noone has done more than explain how it work, we are still awaiting to learn why it works that way, the benefit related to the purpose of Authentication. It's accepted your opinions of performance make sense, but this library represents Authentication, not performance guarantees. So please expalin why it operates this way in context to the goals. I hope a review of the work by Stefan, Kumar, and my own PR will be enough input to reach a rational conclusion here. |
Can't say much about this since I'm not from mozilla .. I think this lib is dead. I just did some boilerplate code / in context of the Mozilla Services to make the requirements of the service py3 ready .. but that was a waste of time, because mozilla decided to let the whole project die ... of course without telling the contributors, that's mozilla style .. so don't expect to much feedback .. |
This line of code
hawkauthlib/hawkauthlib/utils.py
Line 154 in 706d498
simply takes the
hash
provided by the client when calculating the server-side verification.what should happen?
The server should read the raw payload + content-type and calculate it's own hash to compare with the client provided value.
Why is this a problem?
A malicious actor in the middle can alter the payload and the server side will not identify the modification occurred because it simply uses the client provided value instead of verify the hash provided against the modified payload.
The text was updated successfully, but these errors were encountered: