0

I'm having prod.js module like this which I'm using to set content security policy

const helmet = require('helmet');
const compression = require('compression');

module.exports = function (app) {

    app.use((req, res, next) => {
        res.locals.cspNonce = crypto.randomBytes(16).toString("hex");
        next();
      });
      
    app.use(
        helmet.contentSecurityPolicy({
          useDefaults: true,
          directives: {
            scriptSrc: [ "'self'", 'js.stripe.com', 'https://checkout.stripe.com', 'js.stripe.com',  'https://billing.stripe.com', ( request, response ) => `'nonce-${res.locals.cspNonce}'` ],
            styleSrc:  ["'unsafe-inline'"],
            connectSrc:[" * 'self' https://checkout.stripe.com https://billing.stripe.com"],
            frameSrc:  ["'self'  https://checkout.stripe.com  https://billing.stripe.com https://js.stripe.com ;"],
            imgSrc:    [" 'self' blob: https://api.company.com/  data:"], 
          },
        })
      );


    app.use(compression());
};

I want to access this nonce value created in index.html inside my react app. So that I can pass it to script tags like this

React app index.html

 <!DOCTYPE html>

<html lang="en">
  <head>      

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    
    <script 
      nonce={.........//Get the nonce value here............}
    >
    </script>

    
    <title>Some title</title>


But I'm not able to figure out how to access nonce inside my Index.html.

P.S: I'm new to programming. Please let me know if you need any other info to help me with this case.

Adding additional info ----------

I'm invoking prod.js in my Index.js file inside my node project.

My Index.js looks like this

const express = require('express');
const https = require('https');
const path = require('path');
const app = express();


require('./startup/routes')(app);
require('./startup/db')();
require('./startup/config')();
require('./startup/validation')();
require('./startup/prod')(app);

Arsene Wenger
  • 587
  • 4
  • 21
  • Are you fetching that value through a REST API route or is it returned somewhere in the document body ? What calls the function you are showing ? – Peterrabbit Feb 25 '22 at 09:17
  • @Peterrabbit I have added additional info toward the end of the answer. – Arsene Wenger Feb 25 '22 at 09:49
  • I don't understand when you say your value is created in you index.html. Is it written somewhere in your index.html ? – Peterrabbit Feb 25 '22 at 10:43
  • @Peterrabbit I think this (nonce )value comes as server response header. I need to access it from Index.html somehow. – Arsene Wenger Feb 25 '22 at 13:02
  • Ok but then, how is fetched that response, is it a REST entrypoint ? Do you fetch it with an AJAX request from your React app ? If yes it cannot e defined directly in the index.html, your app must fetch it first and then define it. – Peterrabbit Feb 25 '22 at 13:04
  • I quite new to programming. So don't know exactly how to do it . Stuck here. But answer from Gprost looks very close to what I'm looking for -> https://stackoverflow.com/questions/44354763/how-do-i-get-http-headers-in-react-js But unfortunately, I didn't understand it totally. – Arsene Wenger Feb 25 '22 at 13:08
  • Indeed that's pretty much what I'm saying also. You'd have to make an AJAX call from your React App to resolve that value, and only then you'll be able to use it. – Peterrabbit Feb 25 '22 at 13:11
  • If you are not comfortable with AJAX request etc, you can have a look to the MDN documentation about the fetch API https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API – Peterrabbit Feb 25 '22 at 13:12
  • Nonces are stripped from the code by the browser/user agent. The point of the nonces is to ensure that only the server sending them, and the user agent receiving them, know what they are, so that the user agent knows the scripts marked by them have not been modified during transit. It would defeat that purpose if an attacker's script on the client could take that nonce and apply it to itself. – Heretic Monkey Feb 25 '22 at 13:33

1 Answers1

0

Your nonce value will be resolved after you fetch it from your API. Here is a simplistic example of implementation:

class MyApp {
    constructor() {
        this.nonce = "";
        this.app_ready = false;
        this.fetchNonce();
    }

    setNonce(value) {
        this.nonce = value;
        this.app_ready = true;
        // Do what you have to do when your app is ready, mount your components, etc...
    }

    fetchNonce() {
        fetch("https://url/to/your/api")
            .then(response => {
               this.setNonce(response.headers.key.to.your.value)
            })
            .catch(error => {/*Handle you app state in case of error...*/})
    }

}
Peterrabbit
  • 2,166
  • 1
  • 3
  • 19