Manifest V3 remotely hosted code and CDN template files

377 views
Skip to first unread message

Stephen Kao

unread,
Jan 8, 2024, 2:34:07 PM1/8/24
to Chromium Extensions
Hey, everyone!  

I wanted to clarify something about the remotely hosted code policy for my particular use case.  I'm working on an extension that fetches and renders templates from a CDN (think a simplified version of Handlebars), and the content script for my extension would take the template and render it.  It's important to keep the templates remote because they may be modified and shared among a group of trusted users.  

So essentially the flow would be:
  • Launch extension
  • Background fetches template data from CDN and messages it to content
  • Content renders the templates into the host page

Some common violations include:

  1. Including a <script> tag that points to a resource that is not within the extension's package

  2. Using JavaScript's eval() method or other mechanisms to execute a string fetched from a remote source

  3. Building an interpreter to run complex commands fetched from a remote source, even if those commands are fetched as data

For my use case, does the rendering of the template count as an interpreter running complex commands?  If so, is there any way to support this functionality without resorting to iframes?  (I'd like to continue to interact with the host page so I'd like to avoid using iframes.)

Thank you in advance!

Patrick Kettner

unread,
Jan 8, 2024, 7:00:24 PM1/8/24
to Stephen Kao, Chromium Extensions
Hey Stephen,
Without seeing the project itself, it is hard to say for sure. But if it is something like handlebars or mustache or anything more complex than a data structure (like just a plain JSON response), then it would likely be in violation.

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/0685e1ea-6305-4190-9a5d-d3c84663845an%40chromium.org.

Patrick Kettner

unread,
Jan 8, 2024, 7:00:27 PM1/8/24
to Chromium Extensions, stephen.y...@gmail.com
Hey Stephen,
Without seeing the project itself, it is hard to say for sure. But if it is something like handlebars or mustache or anything more complex than a data structure (like just a plain JSON response), then it would likely be in violation.

Stephen Kao

unread,
Jan 9, 2024, 9:05:38 AM1/9/24
to Chromium Extensions, Patrick Kettner, stephen.y...@gmail.com
Thanks for the quick response, Patrick!

I see, I see.  So for further clarification, something like a string template in a JSON object would be in violation as well?  Like:

{
    "componentType": "Button",
    "componentHtml": "<button>{{ buttonText }}</button>"
}

Then it'd be rendered by the content scripts accordingly:

const buttonHtml = render(buttonJson, { buttonText: 'Click me!' });
const target = document.querySelector('#target');
target.innerHTML = buttonHtml;

If so, do you have any suggestions on how this sort of "remote templating" could be handled without iframes or can it not be done?  Even if I'd have to use something like a simplistic "safelyRenderToHtml" helper, that'd be a great starting point.

Thanks again for the help!

wOxxOm

unread,
Jan 9, 2024, 9:13:36 AM1/9/24
to Chromium Extensions, Stephen Kao, Patrick Kettner
> But if it is something like handlebars or mustache or anything more complex than a data structure (like just a plain JSON response), then it would likely be in violation.

I don't think so.

> Building an interpreter to run complex commands

This clause was added to prevent extension developers from making a virtual machine or reimplementing a language interpreter to circumvent the remote code restriction, not to forbid the industry standard simple template processors like mustache or handlebars that are limited to html/DOM by design so there's no arbitrary code execution.

Oliver Dunk

unread,
Jan 9, 2024, 9:27:02 AM1/9/24
to wOxxOm, Chromium Extensions, Stephen Kao, Patrick Kettner
We have an example here which shows how to do some basic templating using a sandboxed page: https://developer.chrome.com/docs/extensions/how-to/security/sandboxing-eval. That is completely fine and hopefully the tutorial helps - you can find the code in our samples repo too :)

If you're building something yourself, or using a framework like React, you would be able to do something similar within an extension page without using eval and that is fine too.

The tricky bit (which I think is what Patrick was explaining) is when you go beyond simple templating with data and start allowing dynamic content rendered in this way to access dangerous capabilities, e.g building arbitrary UIs that can call arbitrary extension APIs. Beyond a point it becomes too hard to reason about the functionality of the extension and that would be in violation.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.

wOxxOm

unread,
Jan 9, 2024, 9:40:55 AM1/9/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Stephen Kao, Patrick Kettner, wOxxOm
>  arbitrary UIs that can call arbitrary extension APIs

A UI doesn't call anything. An extension can't call "arbitrary extension APIs", only those listed in its permissions. This is yet another discussion of this rule, full of opinions and not based on facts, because the rule is too vague and should be rephrased or at least the exceptions should be clearly listed like the pure DOM/HTML templates. 

Stephen Kao

unread,
Jan 9, 2024, 3:42:23 PM1/9/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Stephen Kao, Patrick Kettner, wOxxOm
Thank you for the reply, Oliver!

I guess my question is more about that aforementioned tricky bit rather than using eval/templating in the extension.  The example you mention has the templates as part of the extension source code in sandbox.html whereas in my use case they'll be coming from a CDN since they'll be maintained and updated outside of the typical release cycle.  Would this be in violation of the RHC policy if all the rendering happens in the sandbox (and the HTML content is messaged back to the host page)?

Thanks again for your continued assistance!

Oliver Dunk

unread,
Jan 10, 2024, 5:53:25 AM1/10/24
to Stephen Kao, Chromium Extensions, Patrick Kettner, wOxxOm
Would you be able to share more about your specific use case and why you need to display content from a server?

It sounds like you are probably still ok, but I'm hesitant to say for sure without understanding the context. In particular, it definitely doesn't sound like you're building an interpreter, but I want to make sure you will meet the bar that the "full functionality of an extension must be easily discernible from its submitted code".

Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

Stephen Kao

unread,
Jan 10, 2024, 9:52:50 AM1/10/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Patrick Kettner, wOxxOm, Stephen Kao
Sure, no problem!  I'm absolutely not building an interpreter; I'm certainly not smart enough to do so :P 

My team would like to be able to push out visual updates and bug fixes (i.e., component templates, CSS, images, and translation content) to our extension's functionality on our own release cycle, which is how I've understood the "externalized logic" section in the docs.  We currently have rendering logic that happens entirely in content scripts, but we'd like to serve the rendered content externally so we can reduce the time to release visual features and fixes.  In the past, we've had some holdups in the review process for small visual bug fixes, and although the time for the review process is understandable, the increased time to release can erode user trust and can ultimately result in uninstallations.  The actual rendering engine code would--and should--be subject to the extension review process, but we'd just like to update the content whenever necessary.

I hope this clarifies the concept, but let me know if I can provide any more details!

Oliver Dunk

unread,
Jan 11, 2024, 9:58:49 AM1/11/24
to Stephen Kao, Chromium Extensions, Patrick Kettner, wOxxOm
There's nothing wrong with shipping visual updates like that alone - you should be fine.

Just be mindful of what capabilities you expose. I imagine you will create some system for rendering UI components that can trigger logic when they are interacted with. If some of this logic performs actions which we can't see a use for, or that seem dangerous without us being able to understand exactly what the UI to trigger them might look like, that is when I would expect you may encounter issues during review. For example, if you were building a text editor - being able to change the appearance of buttons that change the font size isn't going to be a concern, even if the UI is generated in part by a remote server. On the other hand, if you're building a text editor and the renderer has unused functionality that allows the server to ask for a button with arbitrary text that sends a user's private data outside of the extension, that is much more likely to be a concern (even if we can't observe malicious behaviour, it is too hard in that case to determine the intended functionality).

I hope that helps.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

Stephen Kao

unread,
Jan 11, 2024, 11:34:46 AM1/11/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Patrick Kettner, wOxxOm, Stephen Kao
Got it--that all makes sense to me.  Thank you so much for your help!

Bob Wyman

unread,
Jan 11, 2024, 12:15:10 PM1/11/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Stephen Kao, Patrick Kettner, wOxxOm
Oliver Dunk wrote:
> how to do some basic templating using a sandboxed page:

Are there any templating packages whose use is permitted without a sandboxed page? If so, please name one or a few of them.

bob wyman


On Tuesday, January 9, 2024 at 9:27:02 AM UTC-5 Oliver Dunk wrote:

Oliver Dunk

unread,
Jan 11, 2024, 1:30:14 PM1/11/24
to Bob Wyman, Chromium Extensions, Stephen Kao, Patrick Kettner, wOxxOm
JSX in React definitely works. I imagine most frameworks would fall under that bracket too, as well as some more basic templating engines.

The reason why Handlebars specifically needs to take this approach is that it has some behaviour (I think constructing functions dynamically, but I'd need to check) that violate the script-src content security policy in chrome-extension:// pages. If your templating engine of choice is able to work under those restrictions it is fine to use it without a sandboxed page.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

wOxxOm

unread,
Jan 11, 2024, 1:31:15 PM1/11/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Stephen Kao, Patrick Kettner, wOxxOm, Bob Wyman
>  that violate the script-src content security policy in chrome-extension:// pages

It's impossible, because the policy is enforced internally.

Oliver Dunk

unread,
Jan 11, 2024, 1:39:48 PM1/11/24
to wOxxOm, Chromium Extensions, Stephen Kao, Patrick Kettner, Bob Wyman
You're right that it won't be allowed to perform the action. It is still usually referred to as a violation when this happens though.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

wOxxOm

unread,
Jan 11, 2024, 1:50:15 PM1/11/24
to Chromium Extensions, Oliver Dunk, Chromium Extensions, Stephen Kao, Patrick Kettner, Bob Wyman, wOxxOm
Semantics aside, an actual violation is still possible, and not just in the MAIN or USER_SCRIPT worlds, where it's the intended behavior, but also in the extension's own pages via the irresponsibly allowed exploit of self.onfetch, but that's not something that a popular/reputable template engine would do unless hijacked/spoofed. Of course, a responsible solution would be to either disable the exploit in the published extensions or at least describe it in the documentation so that the extension developers would be careful not to fall victim to some 3rd-party library that abuses this bug.
Reply all
Reply to author
Forward
0 new messages