Skip to content

Commit 85756ba

Browse files
committed
Generate 144-bit nonce to satisfy https://w3c.github.io/webappsec-csp/#security-nonces (although, I'm fairly sure the 128-bit number was pulled straight from someone's ass, and not based on research). Fixes issue #2.
1 parent 7a56ca1 commit 85756ba

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# mod_cspnonce
22

3-
"mod_cspnonce" is an Apache2 module that makes it dead simple to add "nonce" values to the [CSP (`Content-Security-Policy`) headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).
3+
"mod_cspnonce" is an Apache2 module that makes it dead simple to add cryptographically random "nonce" values to the [CSP (`Content-Security-Policy`) headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy).
44

55
`nonce` values are a great way to enable CSP headers while still having dynamic scripts and styles in your web app. Here's an [example from MDN web docs showing a use of `nonce` with `script-src` CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src).
66

mod_cspnonce.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,19 @@ typedef unsigned char byte;
5252
*/
5353
const char * GenSecureCSPNonce(const request_rec * r)
5454
{
55-
// Generate 9 random bytes. Any multiple of 3 will work
55+
// Generate 18 random bytes (144-bits). Any multiple of 3 will work
5656
// well because the base64 string generated will not require
5757
// padding (i.e. useless characters).
5858
// If you modify this number you'll need to modify the string length
5959
// and null terminator below.
60-
byte random_bytes[9];
60+
byte random_bytes[18];
61+
62+
// This number is based on the seemlingly made-up number used in
63+
// the W3C "webappsec-csp" document. It seems made-up (i.e. a number
64+
// not based on either theoretical or real-world testing) because
65+
// 128-bits cannot be divided evenly into a base64-encoded string.
66+
// But, whatever, I'll let someone else fight that battle.
67+
// Here is the nonsense source: https://w3c.github.io/webappsec-csp/#security-nonces
6168

6269
#ifdef _WIN32
6370
BCRYPT_ALG_HANDLE Prov;
@@ -104,21 +111,30 @@ const char * GenSecureCSPNonce(const request_rec * r)
104111
h = random();
105112
memcpy(random_bytes + 4, &h, 4);
106113

107-
// fill up bytes 5,6,7,8
114+
// fill up bytes 8,9,10,11
115+
h = random();
116+
memcpy(random_bytes + 8, &h, 4);
117+
118+
// fill up bytes 12,13,14,15
119+
h = random();
120+
memcpy(random_bytes + 12, &h, 4);
121+
122+
// fill up bytes 14,15,16,17
108123
// Yes, there's overlap.
109124
h = random();
110-
memcpy(random_bytes + 5, &h, 4);
125+
memcpy(random_bytes + 14, &h, 4);
126+
111127
#endif
112128

113129
char * cspNonce;
114130

115-
// Allocate 13 bytes for the base64 string + NULL.
131+
// Allocate 25 bytes for the base64 string + NULL.
116132
// Base64 uses 4 ascii characters to encode 24-bits (3 bytes) of data
117-
// Thus we need 12 characters + 1 NULL char to store 9 bytes of random data.
118-
cspNonce = (char *)apr_palloc(r->pool, 13);
133+
// Thus we need 24 characters + 1 NULL char to store 18 bytes of random data.
134+
cspNonce = (char *)apr_palloc(r->pool, 25);
119135

120136
// null terminate string
121-
cspNonce[12] = '\0';
137+
cspNonce[24] = '\0';
122138

123139
apr_base64_encode(cspNonce, (const char *)random_bytes, sizeof(random_bytes));
124140

mod_cspnonce.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
1 VERSIONINFO
2-
FILEVERSION 1, 2, 0, 0
3-
PRODUCTVERSION 1, 2, 0, 0
2+
FILEVERSION 1, 3, 0, 0
3+
PRODUCTVERSION 1, 3, 0, 0
44
FILEFLAGSMASK 0x3fL
55
#ifdef _DEBUG
66
FILEFLAGS 0x1L
@@ -17,12 +17,12 @@ BLOCK "040904b0"
1717
BEGIN
1818
VALUE "CompanyName", "wyDay, LLC"
1919
VALUE "FileDescription", "cspnonce_module for Apache"
20-
VALUE "FileVersion", "1.2"
20+
VALUE "FileVersion", "1.3"
2121
VALUE "InternalName", "mod_cspnonce.so"
2222
VALUE "LegalCopyright", "Copyright 2005-2020 wyDay, LLC"
2323
VALUE "OriginalFilename", "mod_cspnonce.so"
2424
VALUE "ProductName", "Apache HTTP Server"
25-
VALUE "ProductVersion", "1.2"
25+
VALUE "ProductVersion", "1.3"
2626
END
2727
END
2828
END

0 commit comments

Comments
 (0)