Skip to content

Commit 938bf13

Browse files
committed
Add nonceScriptSrcElem(), remove mintedNonce()
Added nonceScriptSrcElem() to wire the request nonce into script-src-elem (valid there per CSP3), needed when a page's script-src-elem uses 'strict-dynamic'. Removed mintedNonce(): inspecting whether a nonce was minted anywhere is the wrong signal for the inline viewer - the deciding factor is whether the governing script directive uses 'strict-dynamic'; callers inspect directive() instead.
1 parent 41d47a1 commit 938bf13

2 files changed

Lines changed: 17 additions & 29 deletions

File tree

modules/web/web-api/src/main/java/com/enonic/xp/web/csp/ContentSecurityPolicy.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ public final class ContentSecurityPolicy
8383

8484
private static final String SCRIPT_SRC = "script-src";
8585

86+
private static final String SCRIPT_SRC_ELEM = "script-src-elem";
87+
8688
private static final String STYLE_SRC = "style-src";
8789

8890
private static final String NONE = "'none'";
@@ -620,27 +622,23 @@ public String nonceScriptSrc()
620622
}
621623

622624
/**
623-
* Wires the request nonce into {@code style-src} and returns its value (for stamping on inline
624-
* {@code <style nonce="...">} tags).
625+
* Wires the request nonce into {@code script-src-elem} and returns its value (for stamping on a
626+
* {@code <script nonce="...">} element that must satisfy a page whose {@code script-src-elem}
627+
* uses {@code 'strict-dynamic'}, where {@code 'self'} and host sources are ignored). A nonce is
628+
* valid on {@code script-src-elem} per CSP Level 3.
625629
*/
626-
public String nonceStyleSrc()
630+
public String nonceScriptSrcElem()
627631
{
628-
return nonceFor( STYLE_SRC );
632+
return nonceFor( SCRIPT_SRC_ELEM );
629633
}
630634

631635
/**
632-
* The request nonce if some {@code nonce*} call already minted it during this request; empty
633-
* otherwise. Passive: never mints a nonce and never touches a directive. For code late in the
634-
* pipeline that injects markup and wants it to ride through a strict, nonce-based policy: stamp
635-
* the nonce only when one is present — calling {@link #nonceScriptSrc()} instead would make the
636-
* minted nonce the page's only {@code script-src} entry on pages whose policy has none, blocking
637-
* every other script. The nonce is shared across the enforcing, report-only and added rule sets,
638-
* so this answers for the whole request. It does not verify the entry is still wired into any
639-
* directive (a later {@link #resetTo} drops wired entries while the value stays stable).
636+
* Wires the request nonce into {@code style-src} and returns its value (for stamping on inline
637+
* {@code <style nonce="...">} tags).
640638
*/
641-
public Optional<String> mintedNonce()
639+
public String nonceStyleSrc()
642640
{
643-
return Optional.ofNullable( this.nonce.value );
641+
return nonceFor( STYLE_SRC );
644642
}
645643

646644
/**

modules/web/web-api/src/test/java/com/enonic/xp/web/csp/ContentSecurityPolicyTest.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -834,23 +834,13 @@ void resetTo_drops_external_nonce_sources()
834834
}
835835

836836
@Test
837-
void mintedNonce_is_passive_and_empty_until_a_nonce_call_mints()
837+
void nonceScriptSrcElem_wires_the_request_nonce_into_script_src_elem()
838838
{
839839
final ContentSecurityPolicy csp = new ContentSecurityPolicy();
840-
assertThat( csp.mintedNonce() ).isEmpty();
841-
assertThat( csp.serialize() ).isEmpty();
842-
843-
final String nonce = csp.nonceScriptSrc();
844-
assertThat( csp.mintedNonce() ).contains( nonce );
845-
}
846-
847-
@Test
848-
void mintedNonce_answers_for_the_whole_request_across_rule_sets()
849-
{
850-
final ContentSecurityPolicy csp = new ContentSecurityPolicy();
851-
final String nonce = csp.reportOnly().nonceStyleSrc();
852-
assertThat( csp.mintedNonce() ).contains( nonce );
853-
assertThat( csp.addPolicy().mintedNonce() ).contains( nonce );
840+
final String nonce = csp.nonceScriptSrcElem();
841+
assertThat( csp.serialize() ).isEqualTo( "script-src-elem 'nonce-" + nonce + "'" );
842+
// shares the one request nonce with the other nonce* methods
843+
assertThat( csp.nonceScriptSrc() ).isEqualTo( nonce );
854844
}
855845

856846
@Test

0 commit comments

Comments
 (0)