|
32 | 32 | // https://developers.google.com/web/fundamentals/security/csp/
|
33 | 33 |
|
34 | 34 | // First we generate a pseudorandom nonce for each included or inline script
|
35 |
| -// Nonce for including the reCAPTCHA library |
36 |
| -$recaptchaNonce = base64_encode(openssl_random_pseudo_bytes(16)); |
37 |
| -// Nonce for our inline code |
38 |
| -$inlineNonce = base64_encode(openssl_random_pseudo_bytes(16)); |
39 |
| - |
40 |
| -// Note: this is not related to reCAPTCHA, but if you enable a CSP like this |
41 |
| -// you either need to include either a nonce or appropriate domain for any |
42 |
| -// scripts on the page. |
43 |
| -// Nonce for including Google Analytics library. |
44 |
| -$gaIncNonce = base64_encode(openssl_random_pseudo_bytes(16)); |
45 |
| -// Nonce for firing the Google Analytics call |
46 |
| -$gaCfgNonce = base64_encode(openssl_random_pseudo_bytes(16)); |
| 35 | +$nonce = base64_encode(openssl_random_pseudo_bytes(16)); |
47 | 36 |
|
48 | 37 | // Send the CSP header
|
49 | 38 | // Try commenting out the various lines to see what effect it has
|
|
56 | 45 | "Content-Security-Policy: "
|
57 | 46 | ."default-src 'none'; " // By default we will deny everything
|
58 | 47 |
|
59 |
| - ."script-src " |
60 |
| - ." 'nonce-".$recaptchaNonce."' " // nonce allowing the reCAPTCHA library to be included |
61 |
| - ." 'nonce-".$inlineNonce."' " // nonce for inline page code |
62 |
| - ." 'nonce-".$gaIncNonce."' 'nonce-".$gaCfgNonce."'; " // nonces for other scripts |
| 48 | + ."script-src 'nonce-".$nonce."'; " // nonce allowing the reCAPTCHA library and other third-party scripts to be included |
63 | 49 |
|
64 | 50 | ."img-src https://www.gstatic.com/recaptcha/ https://www.google-analytics.com; " // allow images from these URLS
|
65 | 51 | ."frame-src https://www.google.com/; " // allow frames from this URL
|
|
82 | 68 | // reCAPTCHA supports 40+ languages listed here: https://developers.google.com/recaptcha/docs/language
|
83 | 69 | $lang = 'en';
|
84 | 70 |
|
| 71 | +// The v3 API lets you provide some context for the check by specifying an action. |
| 72 | +// See: https://developers.google.com/recaptcha/docs/v3 |
| 73 | +$pageAction = 'examples/csp'; |
| 74 | + |
85 | 75 | ?>
|
86 | 76 | <!DOCTYPE html>
|
87 | 77 | <html lang="en">
|
|
99 | 89 | <title>reCAPTCHA demo - Content Security Policy</title>
|
100 | 90 | <header>
|
101 | 91 | <h1>reCAPTCHA demo</h1><h2>Content Security Policy</h2>
|
102 |
| - <p><a href="/">↤ Home</a></p> |
| 92 | + <p><a href="/">↩️ Home</a></p> |
103 | 93 | </header>
|
104 | 94 | <main>
|
105 | 95 | <?php
|
|
114 | 104 | <p><strong>NOTE:</strong>This is a sample implementation, the score returned here is not a reflection on your Google account or type of traffic. In production, refer to the distribution of scores shown in <a href="https://www.google.com/recaptcha/admin" target="_blank">your admin interface</a> and adjust your own threshold accordingly. <strong>Do not raise issues regarding the score you see here.</strong></p>
|
115 | 105 | <ol id="recaptcha-steps">
|
116 | 106 | <li class="step0">reCAPTCHA script loading</li>
|
117 |
| - <li class="step1 hidden"><kbd>grecaptcha.ready()</kbd> fired, calling <pre>grecaptcha.execute('<?php echo $siteKey; ?>', {action: 'examples/csp'})'</pre></li> |
| 107 | + <li class="step1 hidden"><kbd>grecaptcha.ready()</kbd> fired, calling <pre>grecaptcha.execute('<?php echo $siteKey; ?>', {action: '<?php echo $pageAction; ?>'})'</pre></li> |
118 | 108 | <li class="step2 hidden">Received token from reCAPTCHA service, sending to our backend with:
|
119 | 109 | <pre class="token">fetch('/recaptcha-v3-verify.php?token=abc123</pre></li>
|
120 | 110 | <li class="step3 hidden">Received response from our backend: <pre class="response">{"json": "from-backend"}</pre></li>
|
121 | 111 | </ol>
|
122 |
| - <p><a href="/recaptcha-content-security-policy.php">⟳ Try again</a></p> |
| 112 | + <p><a href="/recaptcha-content-security-policy.php">⤴️ Try again</a></p> |
123 | 113 |
|
124 | 114 | <!-- Add the nonce for our inline script to this tag -->
|
125 |
| - <script nonce="<?php echo $inlineNonce; ?>"> |
| 115 | + <script nonce="<?php echo $nonce; ?>"> |
126 | 116 | var onloadCallback = function() {
|
127 | 117 | const steps = document.getElementById('recaptcha-steps');
|
128 | 118 | grecaptcha.ready(function() {
|
129 | 119 | document.querySelector('.step1').classList.remove('hidden');
|
130 |
| - grecaptcha.execute('<?php echo $siteKey; ?>', {action: 'examples/csp'}).then(function(token) { |
131 |
| - document.querySelector('.token').innerHTML = 'fetch(\'/recaptcha-v3-verify.php?action=examples/csp&token=\'' + token; |
| 120 | + grecaptcha.execute('<?php echo $siteKey; ?>', {action: '<?php echo $pageAction; ?>'}).then(function(token) { |
| 121 | + document.querySelector('.token').innerHTML = 'fetch(\'/recaptcha-v3-verify.php?action=<?php echo $pageAction; ?>&token=\'' + token; |
132 | 122 | document.querySelector('.step2').classList.remove('hidden');
|
133 | 123 |
|
134 |
| - fetch('/recaptcha-v3-verify.php?action=examples/csp&token='+token).then(function(response) { |
| 124 | + fetch('/recaptcha-v3-verify.php?action=<?php echo $pageAction; ?>&token='+token).then(function(response) { |
135 | 125 | response.json().then(function(data) {
|
136 | 126 | document.querySelector('.response').innerHTML = JSON.stringify(data, null, 2);
|
137 | 127 | document.querySelector('.step3').classList.remove('hidden');
|
|
142 | 132 | };
|
143 | 133 | </script>
|
144 | 134 | <!-- Add the nonce value for the reCAPTCHA library to its script tag -->
|
145 |
| - <script async defer src="https://www.google.com/recaptcha/api.js?render=<?php echo $siteKey; ?>&onload=onloadCallback" nonce="<?php echo $recaptchaNonce; ?>"></script> |
| 135 | + <script async defer src="https://www.google.com/recaptcha/api.js?render=<?php echo $siteKey; ?>&onload=onloadCallback" nonce="<?php echo $nonce; ?>"></script> |
146 | 136 |
|
147 | 137 | <?php
|
148 | 138 | endif;?>
|
149 | 139 | </main>
|
150 | 140 |
|
151 |
| -<!-- Google Analytics - adding both nonces here for the library and the inline code --> |
152 |
| -<script async defer src="https://www.googletagmanager.com/gtag/js?id=UA-123057962-1" nonce="<?php echo $gaIncNonce; ?>"></script> |
153 |
| -<script async nonce="<?php echo $gaCfgNonce; ?>">window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-123057962-1');</script> |
| 141 | +<!-- Google Analytics - adding nonces here for the library and the inline code --> |
| 142 | +<script async defer src="https://www.googletagmanager.com/gtag/js?id=UA-123057962-1" nonce="<?php echo $nonce; ?>"></script> |
| 143 | +<script async nonce="<?php echo $nonce; ?>">window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-123057962-1');</script> |
0 commit comments