Context
Found while investigating a report of the whole window becoming unresponsive (no clicks, no scrolling, no file selection) — fixed separately by making transparent overlays click-through. This issue tracks the underlying robustness problem that surfaced during that analysis.
The problem
Tauri injects a nonce on every <style> tag at build time and adds 'nonce-<n>' to the style-src directive. CSP Level 3 mandates that 'unsafe-inline' is ignored as soon as a nonce or hash is present in the directive. Since style-src-attr is not declared separately, it falls back to style-src — and a nonce cannot attach to an attribute.
The consequence: in a packaged build, style="..." attributes can be rejected at parse time, while the <style> block (which carries the nonce) still applies. Mutating styles through the CSSOM from JS (el.style.display = "flex") is unaffected — only the parsed attribute is dropped.
Our CSP (src-tauri/tauri.conf.json):
style-src 'self' 'unsafe-inline'
This does not reproduce on macOS 26.6.1, where inline attributes still apply. Enforcement appears to depend on the WebKit version, which makes this a latent, environment-dependent failure rather than a guaranteed one.
It only ever affects packaged builds: set_csp runs on the embedded-asset path, so npm run tauri dev (served from localhost) never goes through it. Anything broken this way is invisible in development.
Why it matters
index.html carries 9 style= attributes, and several of them are load-bearing rather than cosmetic — they hide elements:
#confirm-backdrop — display:none;z-index:2100
#prefs-backdrop — display:none
#markdown — display:none
#prefs-import-error — display:none
.prefs-editor-hide — display: contents
If those attributes are dropped, the two backdrops are displayed from the first launch: full-screen, fully transparent, covering the window. That is exactly the shape of the unresponsive-window report, reachable with no user interaction at all.
Proposed fix
- Structural (preferred) — stop expressing behaviour through
style= attributes. Move display and z-index into classes, e.g. .prefs-backdrop { display: none } .prefs-backdrop.open { display: flex }. Any future CSP hardening then becomes harmless.
- Targeted — add
style-src-attr 'unsafe-inline' to the CSP. Restores inline attributes while keeping nonce protection on <style> elements via style-src-elem.
The CSS safety net already shipped (.prefs-backdrop:not(.visible) { pointer-events: none; visibility: hidden }) means a stuck backdrop can no longer lock the window, so this is not urgent — but it does not address the cause, and other inline attributes remain exposed.
How to confirm
In a packaged build, open the inspector:
document.querySelector('meta[http-equiv="Content-Security-Policy"]').content
// expect a 'nonce-…' inside style-src
const e = document.getElementById('confirm-backdrop');
[e.getAttribute('style'), e.style.zIndex]
// attribute present but an empty CSSOM value is the signature of CSP blocking
The WebKit console should also log a CSP refusal for the attribute.
Context
Found while investigating a report of the whole window becoming unresponsive (no clicks, no scrolling, no file selection) — fixed separately by making transparent overlays click-through. This issue tracks the underlying robustness problem that surfaced during that analysis.
The problem
Tauri injects a nonce on every
<style>tag at build time and adds'nonce-<n>'to thestyle-srcdirective. CSP Level 3 mandates that'unsafe-inline'is ignored as soon as a nonce or hash is present in the directive. Sincestyle-src-attris not declared separately, it falls back tostyle-src— and a nonce cannot attach to an attribute.The consequence: in a packaged build,
style="..."attributes can be rejected at parse time, while the<style>block (which carries the nonce) still applies. Mutating styles through the CSSOM from JS (el.style.display = "flex") is unaffected — only the parsed attribute is dropped.Our CSP (
src-tauri/tauri.conf.json):This does not reproduce on macOS 26.6.1, where inline attributes still apply. Enforcement appears to depend on the WebKit version, which makes this a latent, environment-dependent failure rather than a guaranteed one.
It only ever affects packaged builds:
set_cspruns on the embedded-asset path, sonpm run tauri dev(served from localhost) never goes through it. Anything broken this way is invisible in development.Why it matters
index.htmlcarries 9style=attributes, and several of them are load-bearing rather than cosmetic — they hide elements:#confirm-backdrop—display:none;z-index:2100#prefs-backdrop—display:none#markdown—display:none#prefs-import-error—display:none.prefs-editor-hide—display: contentsIf those attributes are dropped, the two backdrops are displayed from the first launch: full-screen, fully transparent, covering the window. That is exactly the shape of the unresponsive-window report, reachable with no user interaction at all.
Proposed fix
style=attributes. Movedisplayandz-indexinto classes, e.g..prefs-backdrop { display: none } .prefs-backdrop.open { display: flex }. Any future CSP hardening then becomes harmless.style-src-attr 'unsafe-inline'to the CSP. Restores inline attributes while keeping nonce protection on<style>elements viastyle-src-elem.The CSS safety net already shipped (
.prefs-backdrop:not(.visible) { pointer-events: none; visibility: hidden }) means a stuck backdrop can no longer lock the window, so this is not urgent — but it does not address the cause, and other inline attributes remain exposed.How to confirm
In a packaged build, open the inspector:
The WebKit console should also log a CSP refusal for the attribute.