xtermjs / xterm.js

A terminal for the web
https://xtermjs.org/
MIT License
17.68k stars 1.63k forks source link

Latest version requires unsafe-inline due to inline styles #4445

Open rupertbg opened 1 year ago

rupertbg commented 1 year ago

Content Security Policies need to be set to 'unsafe-inline' to work with xterm.js. Older versions didn't use inline styles so this wasn't an issue.

Ideally xterm should stop using inline styles or support a user-provided nonce value that can be set in the CSP. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src

Details

Steps to reproduce

  1. Set a content security policy like "style-src 'self';"
  2. Make an xterm that has a resizable container
  3. Resizing causes CSP errors in the console.
  4. Resizing doesn't work properly
Tyriar commented 1 year ago

It always needed it depending on the renderer you are using. Is the proposal that the nonce is generated by the server and passed into xterm.js as an option?

Codehardt commented 1 year ago

Same issue here, properties like font-family are blocked by CSP in newest version 5.2.1. I would be fine if I can pass a server-generated nonce to the Terminal constructor.

Kind regards, Marcel

jerch commented 1 year ago

What would be the best way forward here? As I have lit. no clue about CSP scoping rules, some help from more experienced CSP-focused devs would be appreciated.

rupertbg commented 1 year ago

Well one option would be to use stylesheets instead of inline styles, which is the reason it became a problem in the first place.

jerch commented 1 year ago

Well one option would be to use stylesheets instead of inline styles, which is the reason it became a problem in the first place.

Thats not possible for all styling parts, as some are calculated from metrics in JS.

rupertbg commented 1 year ago

Well one option would be to use stylesheets instead of inline styles, which is the reason it became a problem in the first place.

Thats not possible for all styling parts, as some are calculated from metrics in JS.

You could consider updating css variables via setProperty on the :root instead of applying inline styles. I believe this does not count for the purposes of CSP.

Codehardt commented 1 year ago

The only thing that CSP is blocking if you use inline <style>...</style> or inline style="...". But there are still ways to dynamically set styles with JS that are not blocked by CSP, by using elem.setProperty(<prop>, <value>) or elem.style.<prop> = <value>. If this is no option, then there is also a nonce possible: Just allow passing a nonce string in the Terminal constructor and use this nonce in all <style> sections: <style nonce="<the nonce>">...</style>.

Tyriar commented 1 year ago

But there are still ways to dynamically set styles with JS that are not blocked by CSP, by using elem.setProperty(, ) or elem.style. = .

This is not an option as styling every single character like this would hurt performance.

Just allow passing a nonce string in the Terminal constructor and use this nonce in all .

This sounds fine, let's add a nonce/cspNonce option?

SimonSiefke commented 1 year ago

Maybe the CSSStyleSheet api could useful for this, for example:

const sheet = new CSSStyleSheet();
sheet.replaceSync("a { color: red; }");
document.adoptedStyleSheets.push(sheet)
Tyriar commented 1 year ago

@SimonSiefke if that works around the CSP issue we could use that method in the browsers that support it 👍

Tyriar commented 1 year ago

This change was reverted in https://github.com/xtermjs/xterm.js/pull/4680

deadbaed commented 6 months ago

A workaround until CSPs are implemented again: use the webgl addon!

I was getting CSP errors when importing xtermjs in my angular app, and had only a non functional black box. By using the webgl backend I am still getting CSP errors, but now I have a functional xtermjs!