Stencil version:
Current behavior:
When attempting to inject a web component, built using Stencil, into a webpage via a browser extension's content script, an error is encountered:
TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment.
Expected behavior:
The process of injecting a Stencil-generated web component into a webpage through a browser extension's content script should occur seamlessly, without triggering any errors related to content security policies or HTML trust requirements.
Other information:
This issue arises due to Stencil's bootstrap process for components, which relies on the innerHTML method. This method can be considered unsafe in the context of Chrome extensions, leading to stricter security checks and the resulting error.
https://github.com/ionic-team/stencil/blob/a69b4d619ebf4f65f54e7ad35c24b28f2416d9c8/src/runtime/bootstrap-lazy.ts#L197
https://github.com/ionic-team/stencil/blob/a69b4d619ebf4f65f54e7ad35c24b28f2416d9c8/src/runtime/bootstrap-lazy.ts#L202
The error encountered indicates a conflict with the Content Security Policy (CSP) typically enforced in browser extensions. CSP aims to mitigate risks associated with cross-site scripting (XSS) and data injection attacks, which are particularly sensitive in the context of extensions that have elevated access to the user's browser.
As a proposed solution, replacing innerHTML with textContent in these contexts could mitigate the issue. textContent is generally considered a safer alternative and aligns well with the security requirements of browser extensions. An example substitution could be as follows:
// Add styles for `slot-fb` elements if any of our components are using slots outside the Shadow DOM
if (hasSlotRelocation) {
dataStyles.textContent += SLOT_FB_CSS;
}
// Add hydration styles
if (BUILD.invisiblePrehydration && (BUILD.hydratedClass || BUILD.hydratedAttribute)) {
dataStyles.textContent += cmpTags + HYDRATED_CSS;
}
Rationale for prefering textContent over innerHTML here:
- Security: The most compelling reason to prefer textContent is its inherent security. Unlike innerHTML, textContent does not parse HTML tags and therefore, cannot execute potentially malicious scripts. This makes it a safer choice for dynamic content insertion, aligning with the strict security requirements of browser extensions.
- Performance: For simple text manipulations, textContent is generally faster than innerHTML because it does not involve HTML parsing and rendering overhead.
- Impact on Web Applications Using
<style> Elements: In the case of appending CSS to <style> elements, the switch from innerHTML to textContent carries no functional drawbacks for classical web applications. Since the content being manipulated is CSS (a form of text), and not HTML, there are no functional disadvantages to using textContent over innerHTML. Both methods effectively achieve the same result when used to update the content of <style> elements.
In the specific scenario of appending CSS to <style> elements within Stencil's component initialisation process, the adoption of textContent is not only a security enhancement but also aligns with best practices for performance and code clarity. This change would positively impact both browser extensions and traditional web applications, without any loss of functionality or capability.
System Info:
System: node 18.17.1
Platform: darwin (23.1.0)
CPU Model: Apple M1 (8 cpus)
Compiler: /Users/theo/.nvm/versions/node/v18.17.1/lib/node_modules/@stencil/core/compiler/stencil.js
Build: 1702922611
Stencil: 4.9.0 🐏
TypeScript: 5.2.2
Rollup: 2.42.3
Parse5: 7.1.2
jQuery: 4.0.0-pre
Terser: 5.26.0
Code Reproduction URL:
Stencil Bug Reproduction Repository
Steps to Reproduce:
The steps to reproduce the issue can be found here
Stencil version:
Current behavior:
When attempting to inject a web component, built using Stencil, into a webpage via a browser extension's content script, an error is encountered:
Expected behavior:
The process of injecting a Stencil-generated web component into a webpage through a browser extension's content script should occur seamlessly, without triggering any errors related to content security policies or HTML trust requirements.
Other information:
This issue arises due to Stencil's bootstrap process for components, which relies on the
innerHTMLmethod. This method can be considered unsafe in the context of Chrome extensions, leading to stricter security checks and the resulting error.https://github.com/ionic-team/stencil/blob/a69b4d619ebf4f65f54e7ad35c24b28f2416d9c8/src/runtime/bootstrap-lazy.ts#L197
https://github.com/ionic-team/stencil/blob/a69b4d619ebf4f65f54e7ad35c24b28f2416d9c8/src/runtime/bootstrap-lazy.ts#L202
The error encountered indicates a conflict with the Content Security Policy (CSP) typically enforced in browser extensions. CSP aims to mitigate risks associated with cross-site scripting (XSS) and data injection attacks, which are particularly sensitive in the context of extensions that have elevated access to the user's browser.
As a proposed solution, replacing innerHTML with textContent in these contexts could mitigate the issue. textContent is generally considered a safer alternative and aligns well with the security requirements of browser extensions. An example substitution could be as follows:
Rationale for prefering
textContentoverinnerHTMLhere:<style>Elements: In the case of appending CSS to<style>elements, the switch frominnerHTMLtotextContentcarries no functional drawbacks for classical web applications. Since the content being manipulated is CSS (a form of text), and not HTML, there are no functional disadvantages to usingtextContentoverinnerHTML. Both methods effectively achieve the same result when used to update the content of<style>elements.In the specific scenario of appending CSS to
<style>elements within Stencil's component initialisation process, the adoption oftextContentis not only a security enhancement but also aligns with best practices for performance and code clarity. This change would positively impact both browser extensions and traditional web applications, without any loss of functionality or capability.System Info:
Code Reproduction URL:
Stencil Bug Reproduction Repository
Steps to Reproduce:
The steps to reproduce the issue can be found here