Skip to content

Function activateScriptElement overwrite CSP nonce with empty string causing violation #1502

@mildred

Description

@mildred

There is an issue with the function activateScriptElement here that I could trace it from a CSP violation in my app. It has been called from PageRenderer function copyNewHeadScriptElements.

turbo/src/util.js

Lines 1 to 15 in 055eb8f

export function activateScriptElement(element) {
if (element.getAttribute("data-turbo-eval") == "false") {
return element
} else {
const createdScriptElement = document.createElement("script")
const cspNonce = getCspNonce()
if (cspNonce) {
createdScriptElement.nonce = cspNonce
}
createdScriptElement.textContent = element.textContent
createdScriptElement.async = false
copyElementAttributes(createdScriptElement, element)
return createdScriptElement
}
}

The issue is that when creating the script element, the code correctly assigns the nonce to the script element using the cspNonce variable that is correctly computed. However, later on the copyElementAttributes overrides the nonce with an empty string because the DOM attribute is an empty string (element.getAttribute('nonce') is an empty string).

This is because accessing the nonce via the DOM returns an empty string for security reasons. But at this point, the HTML has probably passed multiple stages and even element.nonce is an empty string.

The solution would be to apply the nonce after copying element attributes:

 export function activateScriptElement(element) { 
    if (element.getAttribute("data-turbo-eval") == "false") { 
      return element 
    } else { 
      const createdScriptElement = document.createElement("script") 
      const cspNonce = getCspNonce() 
-     if (cspNonce) { 
-       createdScriptElement.nonce = cspNonce 
-     } 
      createdScriptElement.textContent = element.textContent 
      createdScriptElement.async = false 
      copyElementAttributes(createdScriptElement, element) 
+     if (cspNonce) { 
+       createdScriptElement.nonce = cspNonce 
+     } 
      return createdScriptElement 
    } 
  } 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions