0

On an small audience highly confident web application we are about use CSP to add a level of security. Most parts of the application could be moved to script files and script-src set to 'self' would be sufficient. Some parts however still have to use inline scripts. PHP Session IDs are recreated on a regular basis. We're considering creating a nonce for the remaining cases. Would this code be sufficient for this case?

$nonce = base64_encode(sha1(session_id()));

upon logoff we reset the session id. Would this setup offer a reasonable level of CSP protection?

2 Answers 2

4

The protection with nonce works reliably only if content returned form server to client each time has a new nonce. Each nonce should be used only once. Where as in your approach for the same session ID you will always get the same nonce. This will have only little protection effect. Instead, you should use some generator with more entropy, for instance openssl_random_pseudo_bytes().

2
  • Understood. I'm a bit concerned with the performance if for each request a new nonce has to be calculated. Also I saw (PHP) libraries that implement some sort of timeout after which the nonce is recalculated and thought this practice. But MDN proved you right. Thanks for the tip with openssl_random_pseudo_bytes(). does that have to be base64_encoded?
    – theking2
    Jun 2, 2022 at 14:44
  • 2
    This method generates a byte array. If you embed it into a page source (HTML, JavaScript), it can have unexpected results, because some bytes can be interpreted as special characters. For instance, 0 can be interpreted as "end of text" and thus your page code can be truncated at the place where this byte occurs. Bytes 10 and 13 can be interpreted as "new line" or "carriage return" respectively, which also will lead to unexpected interpretation of the source code. That's why we should convert it to some text. Base64, hexadecimal or something other - it doesn't matter.
    – mentallurg
    Jun 2, 2022 at 20:10
-1

In order to create a nonce with a reasonable strength according to MDN it should be used only once and preferable contain 128 bits of data from a cryptographically secure random number generator. In PHP that would be openssl_random_pseudo_bytes. An example to create a nonce:

    $strong = false;
    $this->nonce = base64_encode(openssl_random_pseudo_bytes(46,$strong));
    if( !$strong ) {
      error_log("Weak random for nonce");
    }

Which will log a warning if the nonce was based on a weak random. The PHP documentation is unclear about what strong/weak mean but I assume it has to do with an TPM available for random number generation.

A possible implementation on github

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .