Yoav Weiss, Bas Schouten, Barry Pollard, Noam Rosenthal, Cliff Crocker, Joone Hur, Tim Kadlec, Noam Helfman, Ian Clelland, Ben Michel, Guohui Deng, Giacomo Zecchini, Dave Hunt, Philip Tellis, Nic Jansma, Benjamin De Kosnik, Jose Dapena Paz, Michal Mocny, Pat Meenan, Sean Feng, Timo Tijhof
… With Early Hints, definition of first bytes is confusing
… We’ve added firstInterimResponseStart to 103
… We’ve moved responseStart to when the body starts
… But we’ve created an interop issue for browsers that haven’t implemented this
… responseStart and TTFB now mean something different by browser
… Instead, should we introduce new finalResponseHeadersStart when the non-103 headers arrive
… At TPAC, people seemed reasonably positive
… Other than Chrome being different for a few versions, we would get back to having interop compat
… A few comments on Github issue
Bas: We want to be clear about the final response
Barry: We could possibly only have interimResponseStart and finalResponseStart
… Original proposal had that
… New proposal allows that as well, in a different way
… Chrome would do the work to revert our previous change
… Other browsers could do work to work towards current proposal
Yoav: I think you covered it well
… Main question is whether we want to be more explicitly
… Main risk with leaving responseStart as is people will continue to misunderstand it
… TTFB based on responseStart, but based on the final response and won’t necessarily understand the difference between the two
… Noam’s proposal is to have 3 timestamps to cover 2 points in time at most
… Don’t know if it’s necessary
… Main point we need to make a decision on
Barry: Is anyone against reverting?
(no responses)
… OK that’s one decision
… As far as how many timestamps
… firstInterimResponseStart presence can determine “broken chrome” when it was different
Bas: Whether it’s there or not would help you understand what responseStart means
… having firstResponseStart and finalResponseStart seems perfectly reasonable
NoamR: I thought the 3 of them was better for discoverability. To disambiguate the meaning, where responseStart means one of the other. Save people from reading the docs
... It’s unfortunate to make API decisions based on detecting broken implementations
… You could also check that based on whether the responseStart value aligns with the interim or the final
… Dislike TTFB because it’s amorphic, and responseStart is also amorphic
Yoav: 103 is not special
… 101 is also a responseStart
NoamR: Pretty sure it’s not in the spec
… We could implement something intermediate in the future
… “What is the start” is a moving target
… Interim response, final header, something specific that has a name
… 3xx we don’t track except redirectStart
NoamH: Are we sure it’ll stay there and we don’t need a finalFinalResponse?
Barry: Discussion about whether we should have finalBodyResponseStart
… Early-flush but haven’t created document yet, they’ve done head but not body
… e.g. postFinalBodyStart
Bas: That would just be the body start
Philip: We haven’t discussed chunked responses for this right?
… Multiple chunks and each has a start and end
Yoav: Yes we’ll maybe want to expose when body started, chunks, etc
… For chunks we’ll have to figure out a way to expose a lot of them
… Maybe it makes sense to add a header into the mix
… So we have finalHeader... finalResponseHeaderStart
NoamR: I don’t think we need to solve all the problems, just to be reasonably specific enough
… Is this NavigationTiming only?
… At least we don’t support 103 outside of a Nav
Barry: We don’t but firstInterimResponseStart was added to RT so it could be used in NT
Yoav: Nothing is preventing us from using 103s for any HTTP response, it’s just not currently implemented
… I don’t think we should limit this to current implementations
NoamR: Redundant in non-Nav RT
Timo: For whether we have a firstFirst or lastLast, depends on likely interpreted meaning of this for developers
… We kind of have this for firstInterimResponseStart
… Spec has already clarified it for years, but I never realized that
… If there were some other kind of “newer” early hint, will they be surprised if that point in time moves again
… Does firstInterim just mean “Early Hints”
… (do we give it a more specific name)
… Or do we want to have it be a moving target depending on the implementation
… What’s the more likely developer need rather than an interpretation
Yoav: I think we should be more cautious than we have been when we’re shifting semantics around
… e.g. something parallel to early hints, early hints-like, early response, it could fit into the same bucket and it wouldn’t change semantics (unless people need to distinguish between early hints)
… Makes sense to call this interim, but for something to fall in the same bucket it would have to be very early hints-like
Barry: We did a lot of bikeshedding
… e.g. IETF we wanted firstInterim vs firstEarlyHints
… If there’s e.g. 104 in the future it fits into firstInterim, and if you want to measure separately we could add another timestamp
… Mistake here when we changed semantics of responseStart
… We should try to be as backwards-compat as possible
Yoav: After this discussion, I realized that we said earlier that we aren’t going to do firstInterim and just responseStart?
Barry: Any objection to finalResponseHeaderStart?
NoamH: Clarify?
Barry: Last response (e.g. 2xx 4xx 5xx) when the first bytes come into play
… If e.g. multiple 103s you ignore those and just use last
NoamH: First byte of 2xx 4xx 5xx, first bytes of that header
… Instead of “final” can it be “status header”
Bas: They’re called “final” responses right?
NoamR: They’re called “interim” and “final” response in HTTP spec
NoamH: If it’s aligned with decision then sure
Barry: Any objections?
… (none)
Barry: Final question - do we keep firstInterimResponseStart for clarity and it’s the same as responseStart?
Timo: Alias of responseStart
… We’re just moving it over
Barry: (and 3xx is before that as redirectStart and end)
Yoav: Why would it alias to one or the other?
NoamR: First non-zero
Barry: firstInterimResponseStart is 0 if no early hints, not same as responseStart
Timo: If you don’t use Early Hints, final response is not interim. It’s first but not interim.
… We can assume there will always be a final response but not necessarily a interim
Yoav: Way to distinguish between is to see if there’s a difference between FIR and final
… Be able to make the distinction on timestamps
Bas: If they’re equal the answer is no
Barry: What precision is timestamps?
Yoav: If that’s the case it shouldn’t matter
… Fuzzed millisecond at worst
Barry: Coming around to having it, as non-zero means it Early Hints were used
… Would Moz implement?
Bas: Haven’t spoken to network folks, but keeping both is just a bit of plumbing
… Make sure it only gets set if there’s an Early Hints response
… Trying to think if there’s any reason to not specifically want FIRS
… When it was the exact same thing it’s would be bad in my mind
… But if it’s not, no objections either way
Yoav: No one has a strong opinion
Barry: Proposal: Keeping firstInterimResponseStart timestamp as well
(no objections)
… 3 for 3 passes!
Yoav: Only breaking change is semantics for FIRS in Chromium, will have to be done carefully while letting people know their dashboards may change
… Defensively code against it by detecting if finalResponseHeaderStart is present
… And checking timestamp of responseStart vs. firstInterimResponseStart
NoamR: Have to be registered to Barry’s blogs. Requirement. :)
Yoav: We have a decision
Timo: For how we think of things, marketing, is it fair to say we’re introducing the finalResponseHeader – that’s the new feature
… When people see dashboards change and they don’t expect it
Barry: Not sure I agree with that, everyone’s measuring responseStart
… We’re aligning with others
Bas: From spec perspective, Chrome was “non compliant”
Barry: We had changed the spec, but are now changing it back
Timo: If you go to a version of FF and Chrome a few years ago
Yoav: firstInterim was added after EH support. Wasn’t an issue.
Barry: For a time EH wasn’t mentioned in the spec
… responseStart was first bytes back, including early hints
… Now we’re being specific about it going the other way
Yoav: And folks that care are ones who have implemented EH on their servers
Barry: And may be annoyed by the inconsistency
Subresource Reporting
Yoav: May have mentioned at TPAC, but there are a bunch of industry security standards that are arriving around card payments
… Part of those security standards, websites need to keep track of all the scripts they download and execute
… Not a capability the web platform allows for today
… Some of that is feasible through ResourceTiming, look at entries with initiatorType=script as a bucket of URLs
… Will give URLs but not hashes
… For resources with SRI, they could get hashes from attributes but no one tells that is correct unless they validate those hashes passed and didn’t trigger CSP violations
… Doing any of this on the client side means an attacker can also harm collection by obfuscating whatever you’re reporting
… We want better awareness of whatever is running on site
… Reporting API seems a good feature to build on in that respect
… Get reporting directly from browser to the server w/out going through JavaScript that can be intercepted by attacker
… Proposal would be for developers to define a reporting endpoint in HTTP headers
… New feature defined by this for subresource-reporting for script types
… Generates a report with URL and digest, assuming was requested in CORS mode
… Which means it’s readable by website (so no security problems sending hash to server)
… Alternatives could be in ResourceTiming, we could add integrity attribute
… But running security verifications on the client is not ideal
… Without opt-in to hash calculation we’d add some RT entry generation, having to generate entries for the scripts
… The other alternative is for CSP require-SRI directive
… Add hash reporting on top of that, but that may be architecturally different thing from what CSP is doing today
… Would love to discuss these open questions
… One major question is whether we see other use-cases performance related or otherwise for this kind of data?
… Or other questions?
Bas: Can you explain the use-case one more time?
Yoav: Use case is for security and compliance reasons, some sites may need to collect an inventory of all scripts that are running on pages, e.g. payment pages
… If you have all first-parties and third-parties, you’ll need to know why they’re there and have guarantees they’re not tampered with at rest or in delivery
Bas: Is there a way for a site to guarantee that CORS policy is working? Otherwise compromise they won’t see it?
Yoav: You would see URL but not the hashes
… e.g. if you can make sure top-level is all CORS enabled you’d know when something went wrong
Nic: When would these reports get generated? A report for every URL? Do they get batched?
Yoav: Initially concerned about that, but Reporting API batches by default, and sends to the server at some UA-defined time.
… Queue a report for every script loaded, but are likely to be sent some number of second or minutes later
Nic: How can it guarantee that the “end” of the reports
Yoav: What you’re looking for in reports is scripts you’re not expecting
Nic: If it’s an “inventory” though a complete list may need to be generated
Yoav: If something doesn’t run that’s fine, but what we’re looking for is something that isn’t supposed to run
… Are there ways to stitch sessions together in Reporting today
Ian: You get cookies if reporting endpoint is same-origin as document reporting
Yoav: For same-origin reporting you could stitch together sessions
Ian: You could add an index to the report, to stitch together
Yoav: I can see how we can change the proposal for that
Ian: It may be worth batching until at least something like DomContentLoaded, so we’re not batching up a ton of reports, as an optimization
… ReportingObserver, it purposes to allow reaction in real-time
… If that’s important for the site to do, ReportingObserver could
Nic: But an attacking script could modify ReportingObserver could modify it
Yoav: For security things, ReportingObserver would not be helpful here
… But for other use-cases, not a significant cost?
Pat: Along the same lines, if this is for some sort of PCI compliance, do you need some level of guarantees that Reporting API doesn’t provide linked to the payment event
… Do you need “no known rogue scripts seen” or for an individual transaction see all the scripts running
NoamH: With cookies, it may include session information
Pat: But no guarantees in Reporting API, best efforts, classes of situations where you won’t get reports for events
Yoav: I would expect this to get sampled
… Not on a per-session or per-payment basis, but for alerts
Bas: For client-side injected scripts, extensions, how would that interact with reporting API in this case
… Would you get script URLs for those things?
Yoav: I wouldn’t expect to get script URLs
… Similar to what we get in ResourceTiming
… Don’t include extensions
Timo: Purpose is to detect unexpected scripts, define what it means in relation to CSP
… Would they not have CSP enforcement?
Yoav: But it can only give so much guarantees for some scenarios
… If all scripts are versioned, you could have hashes for all, and get CSP reports for things not explicitly allowed
… Hard method to deploy
… Especially for evergreen scripts and multiple third-parties
Timo: From a domain you trust
NoamR: Have we thought about doing this in the ServiceWorker?
Yoav: It is feasible to do in ServiceWorker, I can add as an alternative considered. Adds overhead that is not exciting.
NoamR: Lots of ServiceWorker optimizations coming, that could be a solution
NoamH: Is it secure, it’s a script after all
NoamR: Yes you can CSP worker source
Yoav: Some complications, on first run you will not necessarily get all the resources, etc
… Add as an alternative considered on that front
NoamH: Did you consider inline scripts as part of this? Or it can be blocked with CSP?
Yoav: Inline scripts are different. Easier to get an inventory on as part of the build process.
… Tools and CSP to block them
NoamH: I can share from recent experiments on Report-Only violations that when you have a large number of reports e.g. during load time it can affect metrics, some cases 40ms+ regression
… Would need to think about how to avoid that
Yoav: Would think of that as a browser implementation issue, browser should wait a while with these reports
… Is regression related to network traffic?
NoamH: Still analyzing, pinpointing who to blame. From A/B testing a report-only header
… Whether that’s the cause or not I can’t say for sure
… Has significantly identified regression
Yoav: Good feedback for specific browser implementation
… or, if on many browsers, add issue to Reporting API spec
… Coalescing requests is UA-defined, maybe we should be more specific to avoid overhead
… This will rely on Reporting API so I think it was interesting to share