Bug 183530

Summary: [WebAuthn] Roll back newly created credentials if an error occurs
Product: WebKit Reporter: Jiewen Tan <jiewen_tan>
Component: WebCore Misc.Assignee: Jiewen Tan <jiewen_tan>
Status: RESOLVED FIXED    
Severity: Normal CC: alex.gaynor, bfulgham, jiewen_tan, jonathan, jschoi, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 181943    
Attachments:
Description Flags
Patch
none
Patch
none
Patch bfulgham: review+

Description Jiewen Tan 2018-03-09 15:12:13 PST
Current error handling model for WebAuthN is just returning an exception.

A more graceful model should also cleanup any messed states as well.
Comment 1 Radar WebKit Bug Importer 2018-08-15 17:07:54 PDT
<rdar://problem/43357305>
Comment 2 Jiewen Tan 2018-09-13 01:23:24 PDT
Also, we need to carefully pick sentences to describe error such that we can protect user privacy: https://www.w3.org/TR/webauthn/#sctn-privacy-considerations.

For example, we might want to make NotAllowedError indistinguishable between each other.
Comment 3 Jiewen Tan 2020-05-07 01:35:59 PDT
Created attachment 398712 [details]
Patch
Comment 4 Brent Fulgham 2020-05-07 16:13:03 PDT
Comment on attachment 398712 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=398712&action=review

I think this looks good, but I think you made a typo "NSDate instead of NSData".

> Source/WebKit/ChangeLog:3
> +        [WebAuthn] Roll back the newly created credential if an error happens afterwards

Maybe "Roll back newly created credentials if an error occurs"?

> Source/WebKit/ChangeLog:9
> +        Otherwise, the newly created credential will be a dangling credential.

Maybe "We should clean up any newly created credentials if an error occurs before the relying party registers the identity. Otherwise we are left with a dangling credential."

> Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h:78
> +    RetainPtr<NSDate> m_newlyCreatedCredentialId;

This should be an NSData, I think (not an NSDate).

Maybe we should call this "m_provisionalCredentialId"?

Also: Should this be nulled at some point when the credential moves from 'provisional' to 'committed' (or 'complete') ?

> Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:340
> +        m_newlyCreatedCredentialId = toNSData(credentialId);

m_provisionalCredentialId

> Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:605
> +            LOG_ERROR(makeString("Couldn't delete older credential: "_s, status).utf8().data());

I think this should say something like:

"Couldn't delete provisional credential while handling error: "
Comment 5 Jiewen Tan 2020-05-07 17:51:48 PDT
Comment on attachment 398712 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=398712&action=review

Thanks Brent for reviewing this patch.

>> Source/WebKit/ChangeLog:3
>> +        [WebAuthn] Roll back the newly created credential if an error happens afterwards
> 
> Maybe "Roll back newly created credentials if an error occurs"?

Fixed.

>> Source/WebKit/ChangeLog:9
>> +        Otherwise, the newly created credential will be a dangling credential.
> 
> Maybe "We should clean up any newly created credentials if an error occurs before the relying party registers the identity. Otherwise we are left with a dangling credential."

Fixed.

>> Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.h:78
>> +    RetainPtr<NSDate> m_newlyCreatedCredentialId;
> 
> This should be an NSData, I think (not an NSDate).
> 
> Maybe we should call this "m_provisionalCredentialId"?
> 
> Also: Should this be nulled at some point when the credential moves from 'provisional' to 'committed' (or 'complete') ?

Oops, it is indeed a type. But strangely, it compiles and works. There is no needs to commit it. Once the credential is returned to the RP, the LocalAuthenticator object will be cleared.

>> Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:340
>> +        m_newlyCreatedCredentialId = toNSData(credentialId);
> 
> m_provisionalCredentialId

Fixed.

>> Source/WebKit/UIProcess/WebAuthentication/Cocoa/LocalAuthenticator.mm:605
>> +            LOG_ERROR(makeString("Couldn't delete older credential: "_s, status).utf8().data());
> 
> I think this should say something like:
> 
> "Couldn't delete provisional credential while handling error: "

Fixed.
Comment 6 Jiewen Tan 2020-05-07 18:09:26 PDT
Created attachment 398821 [details]
Patch
Comment 7 Jiewen Tan 2020-05-07 18:13:29 PDT
Created attachment 398823 [details]
Patch
Comment 8 Brent Fulgham 2020-05-07 19:04:28 PDT
Comment on attachment 398823 [details]
Patch

r=me
Comment 9 Jiewen Tan 2020-05-07 19:28:05 PDT
(In reply to Brent Fulgham from comment #8)
> Comment on attachment 398823 [details]
> Patch
> 
> r=me

Thanks for r+ the patch.
Comment 10 Jiewen Tan 2020-05-07 19:33:21 PDT
Committed r261366: <https://trac.webkit.org/changeset/261366>