Skip to content

Commit

Permalink
Merge pull request #681 from jcjones/404-challanges
Browse files Browse the repository at this point in the history
Fix #404 - Add a Security Consideration for Cryptographic Challenges
  • Loading branch information
jcjones committed Nov 13, 2017
2 parents e09e0c3 + f496efa commit 45541f9
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1545,7 +1545,7 @@ an assertion. Its {{PublicKeyCredentialRequestOptions/challenge}} member must be
<dl dfn-type="dict-member" dfn-for="PublicKeyCredentialRequestOptions">
: <dfn>challenge</dfn>
:: This member represents a challenge that the selected [=authenticator=] signs, along with other data, when producing an
[=authentication assertion=].
[=authentication assertion=]. See the [[#cryptographic-challenges]] security consideration.

: <dfn>timeout</dfn>
:: This optional member specifies a time, in milliseconds, that the caller is willing to wait for the call to complete.
Expand Down Expand Up @@ -1636,6 +1636,7 @@ following Web IDL.
confusion attacks (where an attacker substitutes one legitimate signature for another).

The <dfn>challenge</dfn> member contains the base64url encoding of the challenge provided by the RP.
See the [[#cryptographic-challenges]] security consideration.

The <dfn>origin</dfn> member contains the fully qualified [=origin=] of the requester, as provided to the authenticator by
the client, in the syntax defined by [[RFC6454]].
Expand Down Expand Up @@ -3127,7 +3128,8 @@ The entry key is the [=extension identifier=] and the value is the [=client exte
<pre class="example" highlight="js">
var assertionPromise = navigator.credentials.get({
publicKey: {
challenge: "...",
// The challenge must be produced by the server, see the Security Considerations
challenge: new Uint8Array([4,99,22 /* 29 more random bytes generated by the server */]),
extensions: {
"webauthnExample_foobar": 42
}
Expand Down Expand Up @@ -3193,7 +3195,8 @@ the use of the extension. The [=[RP]=] sets this value in its request for an ass
var assertionPromise =
navigator.credentials.get({
publicKey: {
challenge: "SGFuIFNvbG8gc2hvdCBmaXJzdC4",
// The challenge must be produced by the server, see the Security Considerations
challenge: new Uint8Array([11,103,35 /* 29 more random bytes generated by the server */]),
allowCredentials: [], /* Empty filter */
extensions: { 'webauthnExample_geo': true }
}
Expand Down Expand Up @@ -3766,7 +3769,8 @@ The sample code for generating and registering a new key follows:
if (!PublicKeyCredential) { /* Platform not capable. Handle error. */ }

var publicKey = {
challenge: Uint8Array.from(window.atob("PGifxAoBwCkWkm4b1CiIl5otCphiIh6MijdjbWFjomA="), c=>c.charCodeAt(0)),
// The challenge must be produced by the server, see the Security Considerations
challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),

// Relying Party:
rp: {
Expand Down Expand Up @@ -3896,7 +3900,8 @@ credentials, then the sample code for performing such an authentication might lo
if (!PublicKeyCredential) { /* Platform not capable. Handle error. */ }

var options = {
challenge: new TextEncoder().encode("climb a mountain"),
// The challenge must be produced by the server, see the Security Considerations
challenge: new Uint8Array([4,101,15 /* 29 more random bytes generated by the server */]),
timeout: 60000, // 1 minute
allowCredentials: [{ type: "public-key" }]
};
Expand Down Expand Up @@ -3927,7 +3932,8 @@ extension for transaction authorization.
};

var options = {
challenge: encoder.encode("climb a mountain"),
// The challenge must be produced by the server, see the Security Considerations
challenge: new Uint8Array([8,18,33 /* 29 more random bytes generated by the server */]),
timeout: 60000, // 1 minute
allowCredentials: [acceptableCredential1, acceptableCredential2],
extensions: { 'txAuthSimple':
Expand Down Expand Up @@ -4002,6 +4008,16 @@ handled on the server side and do not need support from the API specified here.
* Sometime later, the server deregisters this credential due to inactivity.


# Security Considerations # {#security-considerations}

## Cryptographic Challenges ## {#cryptographic-challenges}
As a cryptographic protocol, Web Authentication is dependent upon randomized challenges
to avoid replay attacks. Therefore, the [=challenge=] field MUST be randomly generated
by the [=Relying Party=] in an environment they trust, and the challenge in the client's
response must match what was generated. This should be done in a fashion that does not rely
upon a client's behavior; e.g.: the Relying Party should store the challenge temporarily
until the operation is complete. Tolerating a mismatch will compromise the security
of the protocol.


# Acknowledgements # {#acknowledgements}
Expand Down

0 comments on commit 45541f9

Please sign in to comment.