Hawk Authentication bug - Firefox Accounts payload bypassing integrity validation

Hawk Authentication bug - Firefox Accounts payload bypassing integrity validation

HawkAuth protocol is widely adopted by Firefox Accounts and appears in Postman in a very short list of supported API authentication methods which indicates HawkAuth is vastly more popular than you might first expect.

Snyk Vulnerability Database | Snyk
Critical severity (9.3) Authentication Bypass in hawk

HawkAuth protocol history‌‌

The origins of HawkAuth appears to be with Eren Hammer then shortly sponsored by hapijs before being completely acquired by Mozilla in "maintenance mode" and renamed to just "hawk", which we will learn here that removing the "auth" from the name serendipitously accurate, as you only get Authentication optionally by design.

Jump to the timeline if you're here for the vulnerability disclosure events.

Show me the PoC

PoC for GHSA-mrcf-5cch-47mc mozilla/hawk
PoC for GHSA-mrcf-5cch-47mc mozilla/hawk. GitHub Gist: instantly share code, notes, and snippets.

You'll notice the PoC is entirely showing work on the endpoints (client + server) and not demonstrating MitM (Manipulator in-the-middle). For the Bug Bounty there were Burp sessions provided for on-the-wire modification to the Mozilla payment services endpoints.

The Gist demonstrates the same MitM approach programmatically, code documented where the key problems are, and simple enough to show the defects without needing tooling.

How is the HawkAuth protocol implemented?

‌‌The protocol is an adaptation of IETF draft where the Hawk API is describe in this document.

There are many client and server side implementations that are disparate in their interpretations of the API.

Where is HawkAuth implemented? ‌

There are several libraries that are available for projects to consume and implement Hawk Authentication:

And a growing number of contributions to the Kubernetes ecosystem are using Hawk, it's becoming so numerous there's almost no value listing them all here.

What exactly is HTTP Holder-Of-Key Authentication?‌‌

Simply put; If you have an API (server) that you want to ensure the requester (client) is whom they claim to be and the request you received (payload) is not modified from what was sent (integrity), then you can pre-share a secret with the client to 'sign' the request which proves they have the secret without them exposing it or giving it back to you and you can only get this proof if the server verifies the request using the secret and payload too.

So when you choose HawkAuth you expect that messages that are signed by the shared secret (symmetrical signatures) that both ends know, and can prove without either end disclosing the secret to the other. This is done by each end reconstructing the signature (sign the request) and comparing the signature they signed to the signature the client signed and sent to them claiming they used the expected secret. If the signatures generated at both ends match, the message being signed was not modified and we have proof the sender has the same secret.

We know the sender is who they claim to be because the request they signed has proven integrity properties ensured by the symmetric key we expected them to use when proving authenticity.

The literal definition of Authentication

Hawk does not do the server verification by default, it uses only client provided signatures, comparing the client signature matches the client signature! Therefore Hawk may never actually do any Authentication at all unless you very explicitly and far too onerously tell it too do the verification on purpose.

This is Hawk, by default, does nothing of value at all that TLS doesn't already provide

It had one job, and it only does that job if it's forced to. Otherwise it does basically nothing useful

Are there any fixes?

Apparently not, officially it's intended to be this way.‌‌ Unofficially there is a new branch for a major release version 3.0.0 that has not been made official, but the changes, documentation, change log, unit test - EVERYTHING is done and ready for 2 years! It "is patched" but that is not acknowledged by Mozilla and Hawk is internally deprecated, the whole HawkAuth should be properly (ethically) retired, but it's not widely known which a problem we will cover further on..

EDIT: Stefan Arentz (@st3fan on GitHub) a former Mobile Browser Engineer at Mozilla, has a Go implementation that does not have the flaw. Also the Rust usage within Mozilla. Both of these assemble the signature correctly from what I saw, not using client provided payload hash as-is, it will compute it's own hash using the payload at time of verification for the expected signature for the HMAC comparison).

It is important to note that I produced a patch, which Fixed it on May 4, 2022 in pkg:npm/hawk@9.0.1 (poor release notes), see the commit adeb7e7e2a854edad0f29fef952221cbc809a238 (click that link to see them) found in the release: https://github.com/mozilla/hawk/releases/tag/v9.0.1

Randoms (not part of Mozilla) Re-introduced the vulnerability Apr 3, 2024 in pkg:npm/hawk@9.0.2 (latest) https://github.com/mozilla/hawk/releases/tag/v9.0.2 and describe it as the final version.

Supply chain risk

It appears this library has been hijacked by actors not affiliated with Mozilla and are acting against the official recorded interests of Mozilla risk assessments and leadership decisions.

On the Mozilla repository for many years, they included the following statement;

This library is in "maintenance mode" – no features will be added, and only security-related bugfixes will be applied.

This held true while Mozilla had control, shown by the dormancy leading up until my patch being merged.

You will note 2 deviations by the new maintainers who do not respond to the mention of Mozilla decisions or process, they only act in an independent way, by adding 3 new FEATURES and removed a SECURITY FIX.

Mozilla made it clear this was not getting features, and yet 3 features were added.

Mozilla made it clear that security-related bug fixed will be applied, and yet they are removed without any rationale or acknowledgement to the Mozilla processes that added it in the first place.

The legitimate security fixes were also removed silently in the patch notes.

The repository is now archived and locked out from users to raise issues or push pull requests - the latest NPM release is vulnerable.

This repository appears to me as being hijacked by actors who operate independently form Mozilla and their interests - suspect and assumed harmful. Use your own judgment.

Security domain knowledge, for an authentication library?

I'll be open minded and willing to acknowledge input from others with more domain knowledge than I have.

I hate myself for throwing shade, but this is egregious, where ignoring it would be complicit.

This library is failing to meet the one expectation of the users that trusted an Authentication library.

That said.. here it is.

Comparing a cryptographic hash, a HMAC no less with the word "Authentication" literally right there, where the hash token was extracted from a HTTP Header called "Authorization" and the protocol called HawkAuth has a primary design goal to perform cryptographic verification of signatures - for the use to do secure Authentication operations.

No..

This is not security-sensitive

Makes you feel really warm and fuzzy when you see developers, not influenced by anything you have done because at the time they had no idea about your existence, when they have no domain knowledge at all about the code they are producing for the goals they set. The assumptions they make are the opposite to reality.

If there is no fundamental dare I say basics (AAA) security domain knowledge expressed in the code, the tests, the issues raised, or the discussions - we have a clear systemic problem before I arrived on the scene - in hindsight there's no wonder they used dogma and ignorance to guide the irrational responses.

This is like surgeon walking into a hospital and looks around, all they see is abattoir activities everywhere. Shocked the surgeon walks outside and checks - yes, it said hospital.. Confused, the surgeon asks the butchers what they are doing to these patients, they reply "I taught to amputate, that what I am doing." The surgeon says "The child needed glue for that gash! You monster!" The surgeon talks about this experience with some other surgeons and nurses, and everyone already knew about the abattoir and turn a blind eye to it. They're too far gone and they just try to prevent people going there for 'help'.

Hyperbolic? Maybe. That is how this repository appears to anyone who understands "Verify the hash to gain authentication" or the entry level security professional who did ANY cert and can describe AAA theory or the "I" in CIA triad.

Our adoption and usage of HawkAuth

Before Trivial Security (now de-registered organisation) had a web dashboard - It was a collection of services with an Elasticsearch database that a small group of penetration testers and security engineers used for professional engagements, naively those services intercommunicated relying on HawkAuth, which was migrated to mohawk, then during the SaaS migration we identified the systematic issues and abandoned HawkAuth entirely.

How does this effect Firefox Accounts?‌‌

FXA is where Authentication is handled for Firefox Accounts, the following list are the public endpoints that are easily observable by just running Firefox and observing where the Authentication is included:

Sample of FXA endpoints - thousands (or millions) more exist beyond FXA

  • /account/create
  • /account/login
  • /account/keys
  • /account/devices
  • /account/device
  • /account/device/destroy
  • /account/device/commands
  • /account/devices/invoke_command
  • /account/devices/notify
  • /account/status
  • /account/reset
  • /account/destroy
  • /recovery_email/status
  • /recovery_email/resend_code
  • /recovery_email/verify_code
  • /recovery_email/secondary/verify_code
  • /recovery_email/secondary/resend_code
  • /session/verify_code
  • /session/resend_code
  • /certificate/sign
  • /password/change/start
  • /password/change/finish
  • /password/forgot/send_code
  • /password/forgot/resend_code
  • /password/forgot/verify_code
  • /password/forgot/status
  • /account/lock
  • /account/unlock/resend_code
  • /account/unlock/verify_code
  • /account/attached_client/destroy
  • /session/destroy
  • /session/reauth
  • /session/duplicate
  • /account/sessions
  • /account/attached_clients
  • /session/status
  • /securityEvents
  • /account/profile
  • /account
  • /sms
  • /sms/status{country}
  • /recovery_emails
  • /recovery_email
  • /recovery_email/destroy
  • /recovery_email/set_primary
  • /account/login/send_unblock_code
  • /signinCodes/consume
  • /signinCodes
  • /totp/create
  • /totp/destroy
  • /totp/exists
  • /session/verify/totp
  • /recoveryCodes
  • /session/verify/recoveryCode
  • /recoveryKey
  • /recoveryKey/{recoveryKeyId}
  • /recoveryKey/exists
  • /introspect
  • /oauth/authorization
  • /oauth/token
  • /oauth/destroy
  • /account/scoped-key-data
  • /oauth/subscriptions/clients
  • /oauth/subscriptions/plans
  • /oauth/subscriptions/active
  • /oauth/subscriptions/updatePayment
  • /oauth/subscriptions/customer
  • /oauth/subscriptions/active/{subscriptionId}
  • /oauth/subscriptions/reactivate

There is also the FXA server side that has 'patched' the risk (not what I would call the response), which is more accurately described as them changing from HawkAuth defaults (blind trust) to the payload verification (it's one job) that will do the HTTP Holder-Of-Key Authentication (which is the one and only expected function of Hawk in the first place, right?).

Finally, that FXA Payments Server specifically was at risk and Mozilla themselves said it is "a significant vulnerability".

I refuse to publish the proof-of-concept, any specifics about how an attack can work, or be specific about the flaw. I only discuss there was a vulnerability, Hawk is now completely removed from FxA but it is still widely utilised, even growing in popularity among repositories in the Kubernetes ecosystem.


Timeline

  • Agreement in an ADR 0022 that FxA has deprecated HawkAuth
    May 29, 2020, 3:04 AM GMT+10
  • Introduced (approx) Oct 23, 2020 in v7.0.0 (or earlier, inherited from fork of hueniverse/hawk) https://github.com/mozilla/hawk/tree/v7.0.0
    Effected NPM Versions:  <=9.0.0 >=9.0.2 see https://www.npmjs.com/package/hawk/v/0.0.1
  • Issue #6 mozilla-services/hawkauthlib
    Jul 8, 2021, 4:16 PM GMT+10
    The incoming hash of the payload is being trusted and not verified
    (the library never included a server-side signature construction to compare to the presented signature, it used only the client signature for verification, which verifies itself against itself - not actually a verification at all)
  • Bugzilla 1719614
    2021-07-08 01:19 PDT
    Reported the incorrect hash validation in hawk library for Mozilla backend services and API where the hawkauthlib is utilised.
  • Issue #38 mozilla/PyHawk
    Jul 10, 2021, 3:34 PM GMT+10
    Security Vulnerability in Payload Verification
  • Pull Request #7 mozilla-services/hawkauthlib
    Jul 10, 2021, 12:02 PM GMT+10
    Fixes validation, new and existing unit tests passing, still not merged
  • Bugzilla 1719964 created
    July 10, 2021 01:52 PDT
    PoC for a MitM attack against Firefox Accounts
  • Bugzilla 1719614 Mozilla confirm the code for the both Python and new Rust sync server is not validating payload either
    July 11, 2021 17:44 PDT
  • Issue #284 mozilla/hawk
    Jul 14, 2021, 1:12 PM GMT+10
    The incoming hash of the payload is being trusted and not verified
  • CVE Request 1106124 directly to Mitre
    July 14, 2021
  • Mitre cannot issue a CVE for a vulnerability that includes an open source library which has the name of a CNA (Mozilla)
    July 15, 2021
  • Issue #9850 mozilla/fxa
    Jul 15, 2021, 2:48 AM GMT+10
    Mozilla private JIRA task to add payload veification on sensitive routes, as discussed in my bounty submission 1719614
  • Bugzilla 1719964 follow up
    August 04, 2021 20:24 PDT
  • Bugzilla 1719964 Mozilla responded with no update
    August 08, 2021 11:56 PDT
  • Pull Request #10199 mozilla/fxa
    Aug 21, 2021, 5:24 AM GMT+10 merged Aug 21, 2021, 6:43 AM GMT+10
    Adding payload validation to signature verification, an option available in the vendored (fork) of hapijs/hawk (no longer public)
  • Bugzilla 1719964 follow up
    December 20, 2021 04:28 PST
  • Bugzilla 1719964 Mozilla resolved the ticket as fixed
    December 20, 2021 14:20 PST
  • Bugzilla 1719964 follow up
    January 08, 2022 17:56 PST
  • Bugzilla 1719964 Mozilla reply with no update
    January 09, 2022 23:55 PST
  • Mozilla confuse 1719964 (Firefox Accounts / FxA vuln with PoC) within the bug numbered 1719614 which is only related by the name 'HawkAuth' but completely separate bug where we were last looking at the Python sync server and I listed almost a hundred endpoints that needed to be validated if payload modifications are considered harmful, which would therefore permit me to demonstrate harm for them, or they could accept my bug submission on it's merits that there is clear misconfiguration with potential for harm.
    Feb 7, 2022 09:18 PST
  • I respond to point out they are confusing the 2 tickets, and clarify how 1719614 is a systematic weakness in the spec and implementation whereas 1719964 was a specific issue (remediated already).
    Feb 7, 2022 19:17 PST
  • Hall of fame status added to Bugzilla 1719964
    March 14, 2022 08:41 PDT
    No bounty payment for the bug was also noted
  • I updated Bugzilla 1719964 with details for a CVE to be issued for FXA
    March 14, 2022 08:41 PDT
  • Pull Request #12932 mozilla/fxa
    May 19, 2022, 3:53 AM GMT+10
    All mention of HawkAuth removed
  • I proposed in 1719614 that Mozilla acknowledge the systematic weakness of Hawk, their deprecation efforts, to signal publicly Mozilla have no intention of fixing the specification of HawkAuth or the libraries they maintain. Essentially an advisory to all Hawk users so that they may know they're at risk when implementing HawkAuth with it's insecure default by design.
    May 4, 2023 17:00 PDT
  • Followed up Bugzilla 1719964
    May 4, 2023 16:56 PDT
    Offered to waive bounty payment if it was a blocker for the Hall of Fame entry
  • Bugzilla 1719964 updated to reject the request for CVE on the grounds the severity is disputed, and the patch (PR#7 on mozilla-services/hawkauthlib) still hasn't been merged
    May 31, 2023 00:22 PDT
    (Not sure how a PR for another issue is related to the already patched FxA of this issue, or how severity decisions prevent the existence of a CVE, they're again confusing an issue for FXA with the other issue tracking bug in the open source HawkAuth library itself)
  • Hall of Fame confirmed for Bugzilla 1719964
    May 31, 2023 02:02 PDT
  • mozilla/hawkauthlib now officially abandoned
    Jun 1, 2023, 9:16 PM GMT+10
    The PR I raised to fix the flaw was archived along with the repo, the API spec repo mozilla/hawk was already in maintenance mode not accepting new features (the patch), so the large number of dependencies will not get a CVE or GHSA in their dependabot to advise them of the risk using this abandoned and vulnerable by default Authentication library..
  • Disclosed to Snyk 21 Feb 2024
  • SNYK-JS-HAWK-6969142 published 22 May 2024

Attribution via a CVE, or recognition like this from Snyk is 100% all the value I sought. It's a shame the ethical outcomes could not be reached.

While the CVE process and bureaucracy makes it adversarial to raise awareness and produce a standardised way for legitimate (broken by design), widely adopted, and deprecated by the creator - kinds of vulnerabilities, you know, what CVE has as it's one purpose for existence.. Blocked by Mozilla who inappropriately block CVE creation for no apparent reason, and ignored by Mitre who we would have expected to step in but it's more like they made a 'too hard basket' when they got CNA's involved to avoid the work.

CVE is broken

I can't show screenshots from Mozilla as they are behind a login, but feel free to get an account and request access to see the issues quoted above - allowing Mozilla o control access to information as they see fit.

Snyk is a CNA and can't number an authentication bypass, exploitable, and used by millions of other packages (exponentially larger user base from there)

How about a GitHub Security Advisory issue the CVE so that Dependabot will alert users?

Forks not allowed, even though this fork is maintained and the original is not maintained. Something GitHub give exemption to many famous forks, but this maintained fork is somehow not in the club?
Try another CNA, open source on GitHub is not actually something this CNA will disclose vulnerabilities for (willful ignorance)
The comment was not made by the Mozilla team, it was a random GitHub user in the open source software scope - Mozilla at this point published the repository is not being maintained by them. GitHub can't read.

GitHub's double standards

This repository is a maintained fork, complete with a security patch for the GHSA, The original is abandoned, suspected to have been hijacked from Mozilla, and display with no uncertain terms it will not be maintained, period. No isses or pull requests can even be created, no discussions or comments - nothing - it is read-only.

The only way vulnerability disclosure, and maintenance, can even occur - is with a fork!

But the GitHub rules are, quote;

unpatched repository must request the CVE for their repository instead
we only support package maintainers requesting CVEs from the official package repository
Mozilla is the registered CVE Numbering Authority with scope over hawk.

So "No forks" when the original is read-only. addressing the first two.

GitHub want Mozilla to act as CNA even though Mozilla clearly said it's not in their scope, it is open source and not a Mozilla product that they act as CNA to issue a CVE. GitHub could see that randoms were last maintaining the original repository and are not affiliated to Mozilla, if they thought the Mozilla Bugzilla screenshot was doctored or whatever.

And for double standards, I could name thousands of forks that according to GitHub should not get a CVE, but do. Here are a just a few;

So reading their words is a complete cop-out (Aussie slang for being willfully ignorant with faux-rationale easily debunked but acts like a "go away leave me alone" in a weak attempt that hopes you will find them too difficult to deal with and they win by being left alone like they wanted all along).

Subscribe to Christopher D. Langton

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe