Bug 206403

Summary: Safari does not present CertificateInfo for service-worker served documents
Product: WebKit Reporter: youenn fablet <youennf>
Component: Service WorkersAssignee: Alex Christensen <achristensen>
Status: RESOLVED FIXED    
Severity: Normal CC: achristensen, ap, beidson, berto, cgarcia, darin, ews-watchlist, ggaren, gustavo, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=196182
https://bugs.webkit.org/show_bug.cgi?id=216038
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Description youenn fablet 2020-01-17 00:35:16 PST
Safari does not present CertificateInfo for service-worker served documents
Comment 1 Radar WebKit Bug Importer 2020-01-17 00:36:24 PST
<rdar://problem/58674661>
Comment 2 youenn fablet 2020-01-20 00:50:07 PST
This happens in a few cases:
- service worker intercepts the document fetch, call fetch() itself and sends back the response
- service worker intercepts the document fetch and returns a DOMCache response/synthesized response.
Comment 3 youenn fablet 2020-07-20 11:06:35 PDT
<rdar://problem/65410875>
Comment 4 Alex Christensen 2020-07-20 22:31:21 PDT
Created attachment 404796 [details]
Patch
Comment 5 Geoffrey Garen 2020-07-21 10:19:23 PDT
EWS says the new API tests are failing.
Comment 6 youenn fablet 2020-07-21 10:40:48 PDT
Comment on attachment 404796 [details]
Patch

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

> Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:2163
> +    "    event.respondWith(new Response(new Blob(['<script>alert(\"hello from service worker\")</script>'], {type: 'text/html'})));"

We should probably exercise three code paths here.
The first one with synthetic responses as above.

The second one is when using DOMCache by putting in DOMCache an existing resource and the feeding it into respondWith.
You can find an example in https://mdn.github.io/sw-test/sw.js

The third one by doing something like: event.respondWith(fetch(event.request.url)).
Hopefully this one should work.
Comment 7 Alex Christensen 2020-07-21 13:07:44 PDT
Created attachment 404857 [details]
Patch
Comment 8 Alex Christensen 2020-07-21 13:50:51 PDT
Created attachment 404859 [details]
Patch
Comment 9 Alex Christensen 2020-07-21 17:31:32 PDT
Created attachment 404889 [details]
Patch
Comment 10 Brady Eidson 2020-07-21 17:40:27 PDT
We don't check in failing tests though
Comment 11 EWS 2020-07-21 18:11:20 PDT
Committed r264687: <https://trac.webkit.org/changeset/264687>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 404889 [details].
Comment 12 Alex Christensen 2020-07-21 18:19:22 PDT
Reopening to attach actual fix.  That was just a test showing current behavior.
Comment 13 Alex Christensen 2020-07-21 21:10:53 PDT
Created attachment 404898 [details]
Patch
Comment 14 Darin Adler 2020-07-21 21:37:14 PDT
Comment on attachment 404898 [details]
Patch

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

> Source/WebCore/platform/network/cf/CertificateInfoCFNet.cpp:53
> +    CertificateInfo copy;
> +#if HAVE(SEC_TRUST_SERIALIZATION)
> +    copy.m_trust = m_trust;
> +#endif
> +    copy.m_certificateChain = m_certificateChain;
> +    return copy;

Since there is nothing to isolate, can just write this:

    return *this;

Could even put it inline in the header if you like.
Comment 15 youenn fablet 2020-07-21 23:39:06 PDT
Comment on attachment 404898 [details]
Patch

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

> Source/WebCore/workers/WorkerScriptLoader.cpp:130
> +    options.certificateInfoPolicy = certificateInfoPolicy;

Another way to pass this information down to network process is to piggy back on the destination option, which should be Destination::ServiceWorker, not Destination::Worker.
For ServiceWorker destination, NetworkResourceLoader could decide to pass the certificateInfo (or WebLoaderStrategy could set needsCertificateInfo to true).

We could think of removing certificateInfoPolicy/needsCertificateInfo in the future.

> Source/WebCore/workers/service/ServiceWorkerGlobalScope.h:71
> +    const CertificateInfo& certificateInfo() { return m_contextData.certificateInfo; }

const

> Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp:106
> +    resourceResponse.setCertificateInfo(WTFMove(certificateInfo));

We should probably only do that if the response has no certificate info. And restrict that to navigation loads only.
We do not want to pretend to use the service worker certificate info for third party resources.

> Source/WebCore/workers/service/server/RegistrationDatabase.cpp:408
> +        // FIXME: Consider serializing the certificate info to disk so WKWebView.serverTrust will be non-null when offline.

Could you also add a FIXME for the following case:
- service worker is installed and has a certificate info
- service worker is soft updated, script does not change but certificate info does (say the old certificate was soon to be obsolete).
We should in that case update the service worker registration info and potentially the service worker certificate info.
A quick fix would be to consider that a change in certificate info is like a change in the script. We would then trigger install/activate and update the on disk registration.
See SWServerJobQueue::scriptFetchFinished.
Comment 16 Alex Christensen 2020-07-22 09:35:47 PDT
Thanks for the reviews.  I found that we do need to persist the data to fix the radar, so I incremented schemaVersion and added it.
I added a FIXME for the certificate change in soft update, and used destination to mean certificate info policy.
Comment 17 youenn fablet 2020-07-22 09:39:54 PDT
(In reply to Alex Christensen from comment #16)
> Thanks for the reviews.  I found that we do need to persist the data to fix
> the radar, so I incremented schemaVersion and added it.
> I added a FIXME for the certificate change in soft update, and used
> destination to mean certificate info policy.

Great!
Is there an way to easily compare CertificateInfo equality?
If so, we should probably try to update CertificateInfo as if the script was modified as a follow-up patch.
Comment 18 Alex Christensen 2020-07-22 09:44:53 PDT
Created attachment 404930 [details]
Patch
Comment 19 Alex Christensen 2020-07-22 10:16:39 PDT
(In reply to youenn fablet from comment #17)
> Is there an way to easily compare CertificateInfo equality?
There is a function called certificatesMatch.  We should probably refactor that into something like CertificateInfo::operator==.
Comment 20 Alex Christensen 2020-07-22 11:37:39 PDT
Created attachment 404942 [details]
Patch
Comment 21 Alex Christensen 2020-07-22 12:59:43 PDT
Created attachment 404953 [details]
Patch
Comment 22 Alex Christensen 2020-07-22 13:19:45 PDT
https://trac.webkit.org/changeset/264724/webkit