Skip to content

fix(core): SHA256 hash for JS scripts CSP on Windows - #14265

Merged
lucasfernog merged 2 commits into
devfrom
fix/csp-windows
Oct 10, 2025
Merged

fix(core): SHA256 hash for JS scripts CSP on Windows#14265
lucasfernog merged 2 commits into
devfrom
fix/csp-windows

Conversation

@lucasfernog

Copy link
Copy Markdown
Member

we hash JS scripts as SHA256 for the Content-Security-Policy (CSP) header. The isolation pattern is broken on Windows due to the hash including carriage return characters, which are not processed when the webview checks the script hash to see if the CSP allows the script.

we hash JS scripts as SHA256 for the Content-Security-Policy (CSP) header. The isolation pattern is broken on Windows due to the hash including carriage return characters, which are not processed when the webview checks the script hash to see if the CSP allows the script.
@lucasfernog
lucasfernog requested a review from a team as a code owner October 8, 2025 19:24
@github-actions

github-actions Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

Package Changes Through b5ae335

There are 10 changes which include @tauri-apps/api with minor, tauri-cli with minor, tauri-utils with minor, tauri-runtime-wry with minor, tauri-runtime with minor, tauri with minor, tauri-bundler with minor, @tauri-apps/cli with minor, tauri-codegen with patch, tauri-macros with patch

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
@tauri-apps/api 2.8.0 2.9.0
tauri-utils 2.7.0 2.8.0
tauri-bundler 2.6.1 2.7.0
tauri-runtime 2.8.0 2.9.0
tauri-runtime-wry 2.8.1 2.9.0
tauri-codegen 2.4.0 2.4.1
tauri-macros 2.4.0 2.4.1
tauri-plugin 2.4.0 2.4.1
tauri-build 2.4.1 2.4.2
tauri 2.8.5 2.9.0
@tauri-apps/cli 2.8.4 2.9.0
tauri-cli 2.8.4 2.9.0

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector


/// Normalize line endings in script content to match what the browser uses for CSP hashing.
///
/// According to the HTML spec, browsers normalize:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a source that we could put a link here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried to find one but couldn't 😂 maybe this was AI hallucination

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better be clear about this, I'm afraid to introduce regressions on other platforms if this is not true for them (although rare, they could also have files ending in CRLF), and if that's a behavior we shouldn't rely on, it could break in the future

@Legend-Master Legend-Master Oct 10, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some information: I was wondering how this worked for the regular inline script in user provided HTML, and from testing, kuchiki::parse_html seems to convert \r\n to \n which seemed to make it work, but for the isolation case, we inserted the js file in inline_isolation directly to the document tree, so it preserved the CRLF

fn inject_script_hashes(document: &NodeRef, key: &AssetKey, csp_hashes: &mut CspHashes) {
if let Ok(inline_script_elements) = document.select("script:not(:empty)") {
let mut scripts = Vec::new();
for inline_script_el in inline_script_elements {
let script = inline_script_el.as_node().text_contents();
let mut hasher = Sha256::new();
hasher.update(&script);
let hash = hasher.finalize();
scripts.push(format!(
"'sha256-{}'",
base64::engine::general_purpose::STANDARD.encode(hash)
));
}
csp_hashes
.inline_scripts
.entry(key.clone().into())
.or_default()
.append(&mut scripts);
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh i was wondering the same - good to know

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh so maybe we should fix inline_isolation instead? :|

@Legend-Master Legend-Master Oct 10, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea, I feel like this is pure magic now, I have no idea in which step, the CRLF became LF (using save as in the webview2 devtools on the index.html response gave me LF while we surely returned one ending in CRLF, don't know if it's the devtools or it's something else) (don't know if the CSP is calculated from something like innerText or from the HTML file directly either), I would say switching to use nouce in inline_isolation is a more realistic fix 😂

@lucasfernog
lucasfernog merged commit 7b0d4e7 into dev Oct 10, 2025
27 checks passed
@lucasfernog
lucasfernog deleted the fix/csp-windows branch October 10, 2025 11:11
@Legend-Master

Copy link
Copy Markdown
Contributor

I don't know how you even found this out, good job! 😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants