Configurable third party content in the extension (user defined infographics related to video stream)

Hello there,

I’m trying to create an extension which would show some interactive infographics over the video stream. This infographics would be clickable by viewer, would display some animated panels containing additional information related to the video stream. For better understading, let’s imagine a football video stream where user can interactively show and hide player statistics, match information etc. while other streamer could provide different video stream with different infographics. This infographics would be configurable by the streamer by providing a URL address to the infographics ‘renderer’ in the extension settings. This content URL is limited to a domain which is whitelisted in the extension features settings so the extension would not be able to be abused by inserting any random content.

My question is - is there a way how the extension could load, display and execute content from such a domain? It means html page, css styles, images, json data files, javascript. I have tried to render the content to element with the ‘data’ attribute set to the URL address but this doesn’t seem to work as the extension blocks this content by CSP. Changing default-src, script-src and other related attributes in Content-Security-Policy meta header doesn’t seem to work. I have read the Guidelines and Policies, especially paragraph 2.8 saying that all files used by the extension must be included in the zip file for your assets. And here is the problem - I do not know which files will be used by the extension because it is the streamer who will say which content will be displayed.

I have also tried to load the content in the extension with the fetch() function and set the response as .innerHTML, which worked, but this would not load any additional content required by the infographics page, like javascripts, images etc.

Does this have a solution? Can I, for example, use my custom configuration service API to store the infographics content and then load it from configuration on viewers side during runtime? Or is there a way how to setup CSP to allow the extension to load and run my external content?

Thanks for any advices.

TLDR: yes this is possible.

Long answer follows and another TLDR at the end:

Long answer: extension use of innerHTML is considered not "safe

see Policy 2.7, and might be rejected during review.

So what you would want to do is pass a JSON representation of the content you want to show and construct HTML of that JSON data on the fly, binding listeners as needed

So for example:

{
    "items": [
        { "type": "text", "a paragraph here"}
        { "type": "img", "an image url here", "width": 200, "height": 200)
       etc
    ]
}

Twitch doesn’t support CSP via meta tags as it’s server set via server headers for security reasons.

Twitch CSP is set in the Developer Console.

CSP Cliff Notes from the TwitchDev Discord helper command:

Here are the Cliff Notes on the CSP Changes for Extensions:

You won’t be able to dynamically include additional Javascript like this for security reasons. So you’d have to bundle all the needed Javascript into static JS included in the ZIP file, all Javascript is reviewed as part of the reivew process, so you can’t arbitarily add more after release (without a new version)

Additionally, last I checked dumping a HTML block into innerHTML won’t “trigger” Javascript to download and run anyway, thats the purpose of iFrames (broadly speaking), which you can’t use in Extensions (Policy 2.2)

As in the Twitch Config Service or your Own that you fetch from?

Both would work, but Twitch limits you to 5kb per slot. So that might not be big enough.

And as already mentioned you won’t be able to store Javascript or links to Javascript for use in there for security reasons

Sounds like what you are trying to do really is “poor man iframes” which you can’t do for security.

The ability to load external JS aside, as thats a no go, you need to abide by 2.7

2.7 You must not inject directly into the DOM any data obtained dynamically over AJAX without first validating and processing that data.

So you would want to dynamically be constructing HTML not direct passing it to innerHTML

Another TLDR

  • CSP via Meta tags → No use the Developt Console
  • Inject Javascript → Not Permitted
  • Inject HTML → Not a good idea, and you can keep the data/transfer size down if you fetch JSON representation and construct HTML on the fly
  • The Infographics need to be “templated” so you know what you are going to render. (which helps abide by 2.12)

FINAL TLDR:

Yes you can do this. but you can’t do it via “blind” HTML injection.
And all Javascript has to be “predifined”

Thank you for your response. I appretiate it especially when taking into account how much time you had to spend only with writing such a long message :slight_smile: Thank you for you help, I’ll try to figure out my solution with these information.