Skip to content

Commit

Permalink
Add a nonce to the script elements. This allows CSP to pick
Browse files Browse the repository at this point in the history
 up the nonce value and include it into the header.
  • Loading branch information
johan-smits committed Jun 5, 2024
1 parent cb2cf04 commit af69755
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ once_cell = "1"
open = "5"
oxipng = "9"
parking_lot = "0.12"
rand = "0.8.5"
remove_dir_all = "0.8"
reqwest = { version = "0.12", default-features = false, features = ["stream", "trust-dns"] }
sha2 = "0.10"
Expand Down
11 changes: 11 additions & 0 deletions src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ pub mod html_rewrite;

use anyhow::{anyhow, bail, Context, Result};
use async_recursion::async_recursion;
use base64::{engine::general_purpose, Engine};
use console::Emoji;
use once_cell::sync::Lazy;
use rand::RngCore;
use std::collections::HashSet;
use std::ffi::OsStr;
use std::fmt::Debug;
Expand Down Expand Up @@ -262,3 +264,12 @@ pub fn path_to_href(path: impl AsRef<Path>) -> String {
.collect::<Vec<_>>();
path.join("/")
}

/// A nonce random generator for script and style
///
/// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce
pub fn nonce() -> String {
let mut buffer = [0u8; 16];
rand::rngs::OsRng.fill_bytes(&mut buffer);
general_purpose::STANDARD.encode(buffer)
}
11 changes: 8 additions & 3 deletions src/pipelines/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use super::{trunk_id_selector, AssetFile, Attrs, TrunkAssetPipelineOutput, ATTR_HREF, ATTR_TYPE};
use crate::common::html_rewrite::Document;
use crate::common::nonce;
use anyhow::{bail, Context, Result};
use std::path::PathBuf;
use std::str::FromStr;
Expand Down Expand Up @@ -125,9 +126,13 @@ impl InlineOutput {
pub async fn finalize(self, dom: &mut Document) -> Result<()> {
let html = match self.content_type {
ContentType::Html | ContentType::Svg => self.content,
ContentType::Css => format!(r#"<style>{}</style>"#, self.content),
ContentType::Js => format!(r#"<script>{}</script>"#, self.content),
ContentType::Module => format!(r#"<script type="module">{}</script>"#, self.content),
ContentType::Css => format!(r#"<style nonce="{}">{}</style>"#, nonce(), self.content),
ContentType::Js => format!(r#"<script nonce="{}">{}</script>"#, nonce(), self.content),
ContentType::Module => format!(
r#"<script type="module" nonce="{}">{}</script>"#,
nonce(),
self.content
),
};

dom.replace_with_html(&trunk_id_selector(self.id), &html)
Expand Down
8 changes: 5 additions & 3 deletions src/pipelines/rust/output.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::super::trunk_id_selector;
use crate::{
common::html_rewrite::Document,
common::{html_rewrite::Document, nonce},
config::{rt::RtcBuild, types::CrossOrigin},
pipelines::rust::{sri::SriBuilder, RustAppType},
};
Expand Down Expand Up @@ -130,6 +130,8 @@ window.{bindings} = bindings;
false => ("", String::new()),
};

let nonce = nonce();

// the code to fire the `TrunkApplicationStarted` event
let fire = r#"
dispatchEvent(new CustomEvent("TrunkApplicationStarted", {detail: {wasm}}));
Expand All @@ -138,7 +140,7 @@ dispatchEvent(new CustomEvent("TrunkApplicationStarted", {detail: {wasm}}));
match &self.initializer {
None => format!(
r#"
<script type="module">
<script type="module" nonce="{nonce}">
import init{import} from '{base}{js}';
const wasm = await init('{base}{wasm}');
Expand All @@ -148,7 +150,7 @@ const wasm = await init('{base}{wasm}');
),
Some(initializer) => format!(
r#"
<script type="module">
<script type="module" nonce="{nonce}">
{init}
import init{import} from '{base}{js}';
Expand Down
5 changes: 3 additions & 2 deletions src/pipelines/sass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
ATTR_INLINE, ATTR_NO_MINIFY,
};
use crate::{
common::{self, dist_relative, html_rewrite::Document, target_path},
common::{self, dist_relative, html_rewrite::Document, nonce, target_path},
config::rt::RtcBuild,
processing::integrity::{IntegrityType, OutputDigest},
tools::{self, Application},
Expand Down Expand Up @@ -206,7 +206,8 @@ impl SassOutput {
let html = match self.css_ref {
// Insert the inlined CSS into a `<style>` tag.
CssRef::Inline(css) => format!(
r#"<style {attrs}>{css}</style>"#,
r#"<style {attrs} nonce="{}">{css}</style>"#,
nonce(),
attrs = AttrWriter::new(&self.attrs, AttrWriter::EXCLUDE_CSS_INLINE)
),
// Link to the CSS file.
Expand Down
5 changes: 3 additions & 2 deletions src/pipelines/tailwind_css.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
ATTR_INLINE, ATTR_NO_MINIFY,
};
use crate::{
common::{self, dist_relative, html_rewrite::Document, target_path},
common::{self, dist_relative, html_rewrite::Document, nonce, target_path},
config::rt::RtcBuild,
processing::integrity::{IntegrityType, OutputDigest},
tools::{self, Application},
Expand Down Expand Up @@ -174,7 +174,8 @@ impl TailwindCssOutput {
let html = match self.css_ref {
// Insert the inlined CSS into a `<style>` tag.
CssRef::Inline(css) => format!(
r#"<style {attrs}>{css}</style>"#,
r#"<style {attrs} nonce="{}">{css}</style>"#,
nonce(),
attrs = AttrWriter::new(&self.attrs, AttrWriter::EXCLUDE_CSS_INLINE)
),
// Link to the CSS file.
Expand Down

0 comments on commit af69755

Please sign in to comment.