Monday: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination#monday
- 09:00 - 10:30
- 11:00 - 12:30
- [30 min] Internationalization
- [30 min] API development, rollout, and launching
- [30 min] dom.executeScript discussion continued
- Oliver Dunk (Google Chrome)
- David Johnson (Apple)
- Simeon Vincent (Mozilla)
- Rob Wu (Mozilla)
- Kiara Rose (Apple)
- Brian Weinstein (Apple)
- Elijah Sawyers (Apple)
- Devlin Cronin (Google Chrome)
- George Henderson (Capital One)
- Carlos Jeurissen (Jeurissen Apps)
- Timothy Hatcher (Apple)
- Mukul Purohit (Microsoft)
- Casey Garland (Capital One)
- Jordan Spivack (Capital One)
- Christos Bacharakis (Eyeo)
- Matt Gibson (Bitwarden)
- [simeon] See wiki for upcoming agenda and topics: https://github.com/w3c/webextensions/wiki/TPAC-2024-Coordination
- [simeon] Wednesday has breakout sessions from other W3C groups; if they seem interesting, please add it to the wiki.
- [simeon] FYI we have a chat channel at https://chat.mozilla.org/#/room/#wecg:mozilla.org
- [simeon] Any suggested changes to the agenda?
- (silent)
- [devlin] I note that some of the 30 minute topics would probably take longer than 30 minutes; Otherwise we would have addressed them before.
- [timothy] This has come recently; in Firefox and Chrome nativeMessaging is stdin/stdout-based. We have recently seen research showing that this design is unsafe against attacks that replace binaries. At Apple we try to safeguard against local malware. Our internal team that develops the iCloud Password extension for Chrome is looking hard at this. Are there areas where we can improve this?
- [rob] FYI some recent reports about nativeMessaging being unsafe against local malware:
- [devlin] Are there cross-platform or platform-specific mechanisms to verify the application, e.g. a hash of an application binary? Also interested in using web tech for this use case. E.g. if it is feasible to use https.
- [timothy] Could be a decent approach. In Safari we use platform APIs for native messaging that are safeguarded by code signatures of the binary.
- [oliver] How to ensure that the binary that is launched is the expected binary; also other way around, how can the binary verify that the launcher is the expected browser.
- [carlos] Do browsers currently do any hash verification of installed extension files?
- [devlin] We verify the integrity of packaged extensions and re-download the original package if needed; cannot defend against patched Chrome.
- [oliver] You can also arbitrarily set the ID of an unpacked extension, which allows you to communicate with the application even with an unpatched browser.
- [simeon] There are increasingly multiple browsers; possibly concerning if usage requires signature by e.g. Google.
- [oliver] Does not have to be just Firefox and Chrome. Native applications could have an allowlist of binaries that can communicate with it customizable by the user.
- [simeon] Signature verification could extend to the certificate bundled with the native app. May help verify a self-signed local certificate or a cert bundled with the application.
- [devlin] I don't know which tools are publicly available for verifying third-party applications via the OS.
- [oliver] E.g. in Chrome the update process breaks the signature of the Chrome binary.
- [oliver] What is available at Safari?
- [timothy] I don't know.
- [devlin] What does 1Password use?
- [oliver] They use signature APIs; if the signature cannot be verified the user is prompted to restart the browser.
- [Matt] Mac supports a way to verify the other end of the pipe.
- [simeon] Mukul, could you look into the signing capabilities on Windows?
- [mukul] I can get clarity on that aspect.
- [rob] Could survey developers to see what capabilities they're using to verify the exchange of native messaging exchange, and see if this is something we can offer as a cross-platform API.
- [simeon] I'm not aware of extensions that do this.
- [devlin] Do extensions encrypt the traffic over the channel?
- [Matt] We do.
- [simeon] Could you show a small document or video showing the flow, so we can get a better picture of what the experience is like?
- [Matt] Sure.
- Created #706
- [devlin] Also question on native messaging API. Whether the current stdin/stdout format is sufficient or whether leveraging web APIs (enabling fetch(), headers, etc) would be preferable.
- [oliver] Establishing a native message connection is unreliable. Checking permissions, file locations, etc. Hard to know if when I call sendNativeMessage() it will work. Once working, data transfer is usually fine.
- [casey] We rely on it on iOS.
- [timothy] 20% of extensions in Safari use it. It is made easy, the native messaging component is bundled with the native apps.
- [simeon] Could well known URLs be used? Android / iOS use some well-known formats.
- [carlos] That is called asset links.
- [simeon] And whether this can be built upon to establish the handshake.
- [jon] The reliability of doing this in the manifests may be shaky.
- [simeon] Was not thinking of the native messaging manifest, but a source of truth e.g. when the extension is installed from the extension store or app from an app store. Has implications about offline behavior.
- [oliver] Rob shared some links before, 1Password for example has proposed some improvement there.
- [devlin] Safari can do lots of magic, is there something that Chrome can do too?
- [devlin] Is there interest in leaning more on web tech for native messaging use cases?
- [rob] Don't expect that it would help here - local applications can always forge any agreed-upon request details. A local server with a HTTP-based API is something that extension developers can already implement.
- [carlos] Can a native application verify an extension came from a given store?
- [devlin] Potentially. We have that information in Chrome. Not sure what it would look like. Hesitant about putting more information in the native messaging manifest. Also worried about tying verification to the distribution channel – don't want to negatively impact 3rd party browsers.
Action Items:
- [oliver] Look into 1Password's research and any possible solutions
- [mukul] Look into verification options on Windows
- [timothy] Look at options for Chrome to verify applications on macOS
- This can be done with the
SecCodeCheckValidity
,SecCodeValidateFileResource
, and SecCodeCopySigningInformation from the Security framework. - https://developer.apple.com/documentation/security/defining-launch-environment-and-library-constraints?language=objc
- This can be done with the
- [simeon] Schedule follow-up discussion for later this week
- (editorial note by Rob: this topic was not discussed further this week)
- Related issues: (#77, #78)
- [timothy] Extensions are often exploited because they use postMessage to listen to any broadcast and realize that the page can also do that. Security researchers often find vulnerabilities in extensions that do this.
- [timothy] Devlin has created proposals based on previous discussions
- [devlin] dom.execute() allows synchronous communication across worlds, dom.createPort() would create a port that enables this script to communicate. These APIs were designed in the earlier San Diego meetup. Rob and Carlos have already provided some feedback on these topics.
- San Diego meeting minutes: 2024-03-20-san-diego-meetup.md
- [devlin] The idea is that in the content script world there is a way to create a port, set up a handler, execute code in the main world that receives the port and can communicate back with the content script.
- [devlin] Would this address the concerns, Timothy?
- [timothy] I think so. Current issue is that postMessage can broadcast and the web page can eavesdrop and intercept. This approach means that only the content script has access to that port.
- [george] Is this independent of externally_connectable?
- [devlin] This is about communication between the content script and a script in the main world in the web page. Sometimes you need to have some state from the main world in your content script. You can do this currently by abusing postMessage.
- [george] Could we allow you to use a chrome-extension:// URL in the postMessage APIs?
- [devlin] A malicious main world could also set this, so it doesn't solve as many problems as the proposals here do.
- [carlos] Is cross-frame communication out of scope here? We might still want to communicate between a content script and a host and an iframe within that host.
- [devlin] I think so.
- [rob] If there is a generic way to send values, one can also send instances of MessagePort/MessageChannel from the web platform to establish communication.
- [devlin] If you want to communicate between a content script and a trusted extension context, can you just use runtime.sendMessage?
- [carlos] You would need to check the message came from the right frame.
- [devlin] This is solvable by looking at the sender.
- [rob] Don't think this alone would solve the issues with postMessage. If you can call methods, the page can intercept it via the prototype chain. Are there more guarantees we should offer?
- [rob] The root cause of the described issues is not just postMessage, but that there are currently no guarantees for some minimal execution behavior in the main world. Should we expose some?
- [devlin] Do you have examples?
- [rob] In Chrome internally, $Array, $Object, etc. (built-ins, e.g. safe_builtins.h in Chromium)
- [devlin] Like safe builtins? I can see the utility. That would be something we could potentially do, I'm not sure what form this would take. We could have a way to pass in types when creating the port.
- [devlin] Could see doing this via a flag and on the receiving end bind to the original prototypes.
- [rob] Firefox has the X-Ray system, I'm not sure if Chrome has something similar.
- [rob] You could pass a DOM element from the content script world to the main world.
- [devlin] We discussed this in San Diego. We decided to hold off since passing DOM elements is weird.
- [rob] DOM elements are a specific instance of the generic issue of the need to be able to pass by reference rather than a copy.
- [devlin] For DOM elements, there's enough ways to find an element.
- [rob] This can be interfered with by the web page. DuckDuckGo has asked for this functionality in the past (issue 284). Anyone here with use cases?
- [george] We have UI we inject into the page. This sounds similar to concerns we have there.
- [oliver] Related concern: if you want to provide or override an API to the main world. Might be nice if you could expose an API in the main world, pass data to the isolated world for execution, and pass the result back to the isolated world.
- [devlin] We wouldn't be able to pass direct references to a value from another world, which would limit the utility of this.
- [oliver] Maybe calling with a copy would be enough?
- [devlin] Would break for anything that works on a reference vs. a value.
- [carlos] I have an extension that does some scripting in the main world before other content is loaded.
- [rob] What limitations do you have?
- [carlos] Since mv3 injected script must conform to main page's CSP and not be inline.
- [rob] Should be addressed by dom.execute()
- [rob] I have an extension which rewrites URLs on google.com. It does this by intercepting the href getter of the HTML element. Needs to run in main world. To prevent extension from breaking Google, extension needs to only hook where appropriate, Oliver's proposal could help. Allow me to act as middleware and decide if we should modify value, return something different etc.
- [devlin] In Chrome, that kind of back and forth between contexts would not go well.
- [rob] Need some guarantees for referencing the unmodified prototypes.
- [devlin] Could this be solved if you inject a script to save all the builtins before any other script runs, and expose them as a frozen object?
- [rob] Yes, user script managers do this. The problem is that there is no guarantee it runs before any other script.
- [devlin] There would be with dom.execute().
- [rob] What guarantees the content script always runs first?
- [devlin] I think that's orthogonal. One way to guarantee: document.write in an iframe.
- [rob] That's Chrome-specific. In Firefox there are also some cases where it is possible for document_start scripts to not run before other code starts executing.
- [devlin] In general we consider those bugs. Document_start should run before anything else. That's the point.
- [rob] Your recommendation is to use document_start to save references.
- [devlin] Yes. In practice, safe builtins are visible to the page.
- [Matt] To support FIDO2 and WebAuthN, we need to override default globals for the relevant methods. Our preference would be to declare that we want to participate in that flow and have the browser facilitate that.
- [timothy] I agree, specifically in passkeys we should offer an API for passkey providers.
- [oliver] From the extension perspective I am supportive. But when discussed before with passkey devs, there was much hesitation. E.g. they preferred OS-level integration over extensions.
- [george] Another use case (Capital One shopping), we inject a node in the DOM & we want to prevent modifications to it or removal of it.
- [timothy] Having a protected way to draw over the page might be good, but using popup or sidebar may be the most trusted solution.
- [george] That may be best for a browser, but it's a suboptimal user experience.
- [devlin] We've talked about declarative badging in the past, where the browser would mediate a piece of extension UI in the page.
- [george] That's also very important for in-page permission requests.
- [Matt] Can also mediate injection of additional, unnecessary content in the page.
- [oliver] Would there be interest in a session for this. Declarative badging. Access to another layer on the page. There was hesitation to this in the past.
- [devlin] Still hesitant. Don't know if anyone is willing to experiment on and drive this effort.
- [rob] What is declarative badging? Something different to declarativeContent + action.ShowAction?
- [devlin] Conceptually similar to declarativeContent in that you can specify selectors, but also URL patterns, assets, etc that enable the browser to display in the page. Without requiring host permissions.
- [timothy] We'd be interested in that. Safari's permission model tries to mostly not require host permissions.
- [devlin] Are there any action items?
- [oliver] Re dom.execute, would like to discuss
world
andworldId
params. - [oliver] Whether we can convince extensions to use the new mechanisms instead of insecure postMessage methods.
- [timothy] Many extensions also use CustomEvent.
- (dom.execute discussion continues later today)
Action items
- [simeon] Schedule time to discuss exposing extension UI in page that doesn't require injecting into the host document.
- (editorial note by Rob: this topic was not discussed further this week)
- [carlos] Listed some at #659 (comment)
Issue 569: Proposal: i18n-system-languages
- [carlos] proposal for i18n.getPreferredSystemLanguages & i18n.getSystemUILanguage
- [simeon] Any open concerns?
- [rob] Could the result of this API be passed to the Intl APIs from the web platform? E.g. Intl.DateTimeFormatter
- [carlos] The values from this API could be passed to these APIs.
- [rob] The doc lists “Sponsoring browser: TBD”. Our proposal process requires at least one sponsor.
- [oliver] Timothy said that Safari would be willing to sponsor it.
- [kiara] Confirms.
- [oliver] Don't seem to be any open concerns left.
- [rob] So next step here is to update the sponsoring browser and then update it .
- [oliver] Addison left feedback on the PR, I'll ping him to see if he believes that the concerns have sufficiently been addressed.
Issue 274: Proposal: i18n.getLanguageDictionary
- [oliver] Devlin left some feedback at #274 (comment)
- [oliver] Chrome preference was proposal C.
- [rob] If we implemented this, we would likely make it asynchronous.
- [oliver] Seems that nobody is excited about an asynchronous version of proposal C.
- [oliver] In that case, the other proposals Chrome is supportive of are proposal B and proposal E.
- [carlos] Having an asynchronous initialization could speed up any extension. e.g a browser.i18n.getLanguageDictionary() which returns a Promise and works without any parameters for a default. This would likely be a change for a future manifest version though.
- [rob] Do we have examples of extensions that need this functionality, e.g. in the form of parsing localization files and doing something specific with this?
- [simeon] I think fregante had an extension which does this.
- [rob] Extensions would need logic to fallback to other locales if they implemented this functionality themselves.
- [carlos] Other browsers fall back to multiple; Firefox is the only one that has one fallback. (see issue 296)
- [rob] (added post meeting in a different meeting, with I18n group) After discussions, Firefox is supportive of also implementing multiple fallbacks: #296 (comment)
- [devlin] Wanted to chat about how we rollout APIs. Typically we restrict an API to certain channels or behind a flag, don't get much feedback unfortunately and then roll out the API more widely. APIs being limited to Canary makes it hard for developers to test with their users.
- [devlin] Do other browser vendors have an appetite for solving this problem?
- [rob] Would be useful, definitely. Thinking about it another way, if a developer wants to use an experimental feature, they will need a way to detect if the feature is exposed and supported. I think this is critical for extensions to adopt new API.
- [patrick] As background, I was a lead dev for modernizr, a feature testing library. The open web solves this problem with origin trials. On the open web, websites can add a meta tag to their page to enable an API. This uses a key which developers can only get once they agree that the API may go away. The API will work across all channels but there is no expectation it will last forever. Chrome recently landed token support in extensions in Stable.
- [devlin] Origin trials are a strong possibility here. Often covers functionality without alternatives.
- [patrick] Origin trials solve the real-world feedback use case, not the developer feedback session.
- [george] Can chrome.experimental be used for this?
- [devlin] There is another session on that this week; Short version is that there is a lot of baggage with chrome.experimental that we don't use.
- [brian] Are there concerns about dataloss, e.g. if an experimental data storage API is removed.
- [patrick] Yes, the origin trial is associated with a specific user. If the trial is revoked or removed then the user may go back to the old case. This is why we have to communicate that the origin trial may go away.
- [oliver] We're discussing origin trials - are there other options we should discuss?
- [devlin] Is there appetite from developers for being able to experiment with APIs with a portion of the population?
- [george] Yes, if you control the size of the population / stability of the population.
- [oliver] Does any developer want anything less than 100%?
- [george] We don't feel strongly here.
- [oliver] Devlin, do you want anything less than 100%?
- [devlin] Would lean towards 100% rollout, the main value of an origin trial is explicit agreement that this is not released.
- [david] Does Chrome require feedback / check-ins from developers?
- [patrick] No.
- [carlos] It would be valuable to be able to tell if an origin trial is active. Could also be API behavior changes that are not obvious from feature detection.
- [simeon] Example of flow for origin trial flow, from a developer point of few. Register, fill in extension URL/ID. Consent to the policies and then you get an origin trial. https://developer.chrome.com/origintrials/#/register_trial/1049901663130746881
- [carlos] A method to query whether a specific origin trial string would be active.
- [matt] The only way that we would use this is we can convince 100% of the users to opt in to functionality.
- [timothy] Devs can always choose to use just the old or the new one.
- [rob] I imagine that if there are new capabilities associated with it, that developers are more willing to go through the effort, whereas just a “different” way to do this would not get much traction.
- [devlin] Any alternative options? I don't have ideas.
- [carlos] Developers could also opt in via the manifest file, without origin trials. As the issue of origin verification does not exist for extensions.
- [simeon] 100% availability may result in the assumption on the developer's part that the feature is fully available.
- [rob] What was the response to whether we need origin trials?
- [devlin] I think Carlos raises a good point that if we are looking at 100% rollout, having something in the manifest that doesn't use the origin trial system may be valuable.
- [rob] Could also not require origin trials, but allow developers to sign up / register extensions so we can contact them about updates to the trial. Those could have breaking releases.
- [patrick] Chrome's origin trials do normally send updates.
- [oliver] Prior art, Cloudflare has “compatibility” flags. All breaking changes are behind compatibility flags. https://developers.cloudflare.com/workers/configuration/compatibility-dates/#setting-compatibility-flags
- [devlin] Do other browsers support origin trials?
- [rob] Firefox has an implementation, but it is not widely used.
- [patrick] One negative that wasn't mentioned is that origin trials require code to reach stable.
- [devlin] Right, if we experimented for 1 month that would put us 3 months behind HEAD.
- [george] We'd be especially interested in testing things that improve existing API. Testing new things would be a larger ask.
Action Items:
- [devlin] File issue and write proposal.
- Carry overs:
- [devlin] Discuss how to pass DOM elements between worlds.
- [oliver] Re dom.createPort, would like to discuss
world
andworldId
params on createPort(). - [oliver] Would also like to discuss ways we can discourage postMessage usage.
- [oliver] Re dom.createPort, would like to discuss
world
andworldId
params on createPort().- [oliver] The proposal tries to force a 1:1 communication, this proposal forces that by requiring the worldId to be specified. I lean towards not having the properties, and throw an error when the port is sent again.
- [timothy] I'm also in favor of not adding it.
- [rob] Same.
- [devlin] I was thinking that forcing it would make it easier from the implementation POV, and communicate the expectations to developers. Not thinking that this would be hugely important. I'm fine with dropping it.
- [rob] For prior art, the web platform has the MessageChannel() constructor consisting of two MessagePort instances. A port can be sent only once, any further attempt raises an error. Would you prefer to have special serialization of the port or use another approach to get the port to the other world?
- [devlin] Treating the value specially is my preference.
- [rob] Makes sense.
- [devlin] Discuss how to pass DOM elements between worlds.
- [devlin] On the Chrome side there would not be support for passing DOM elements as JS references across worlds. Rob's point about the need to pass a handle, and that querySelector can be manipulated by the main world.
- [rob] This is only a problem if you need secrecy. Extensions can currently create an iframe in a closed shadow dom to get a secure reference to the iframe's global to get a reference to unmodified global prototypes.
- [] puppeteer/Playwright use case. Right now it does not play nice with elements in shadow DOM for that reason.
- [oliver] Could you speak to the concerns around special serialization for DOM elements?
- [devlin] Implementation complexity. Want to avoid special serialization that isn't directly related to the API.
- [oliver] From an API perspective it seems quite intuitive. Having to set an id and retrieve it back seems not.
- [timothy] I am in favor of passing a DOM element resolving to the JS wrapper on the DOM element.
- [rob] I don't think that's too different from existing wrapping behavior.
- [devlin] Tricky in chromium because we don't have access to the blink layer in the message handler.
- [rob] If implementation complexity is a concern, we could limit support for it to the top-level elements in the args array (to dom.execute) only. Setting a DOM element as a value in an object in the args array would throw (due to structuredClone not supporting DOM elements).
- [devlin] Could something where we have top level handling: if it's a port do X, if it's an element do Y, if it's an object structured clone.
- [oliver] Would we accept different behaviors across browsers?
- [devlin] Not ideal. If there is a hard technical limitation in Chrome I would not block it in other browsers.
- [rob] And extensions can feature-detect it by detecting thrown errors from being unable to structurally clone a value.