ltb-project / self-service-password

Web interface to change and reset password in an LDAP directory
https://self-service-password.readthedocs.io/en/latest/
GNU General Public License v3.0
1.18k stars 327 forks source link

Content-Security-Policy errors, crept back since 1.4 #951

Closed maglub closed 4 months ago

maglub commented 4 months ago

Introduction

This is related to https://github.com/ltb-project/self-service-password/issues/404, which was patched and closed with v1.4 already 2020. It crept back into the code in 2021 by David Coutadeur. I will look at this a bit and see if I can come up with a solution or workaround, but am also happy if someone else have a look.

In our environment, where we add a stricter CSP in our proxy servers, we get the console error:

index.php:119 Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self' www.google.com www.gstatic.com". Either the 'unsafe-inline' keyword, a hash ('sha256-cHwIqHc1H9/dJgzKT7RmVqfyir19aLCtoyGHJGEn/O0='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

The issue is in both templates/header.tpl, and templates/footer.tpl, where inlined styles (not so bad), and an inlined piece of javascript (worse) are used. I suggest that we try and break this out somehow.

16:45 $ git blame templates/footer.tpl
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  1) </div>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  2) {if $display_footer}
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  3) <div id="footer">LDAP Tool Box Self Service Password - version {$version}</div>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  4) {/if}
45254838 (David Coutadeur 2024-03-12 10:26:35 +0100  5) <script src="vendor/jquery/jquery.min.js"></script>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  6) <script src="vendor/bootstrap/js/bootstrap.min.js"></script>
0f79d3b7 (Clément OUDOT   2020-08-10 18:54:00 +0200  7) <script src="js/self-service-password.js"></script>
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100  8) <script>
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100  9)          // Get ssp local policy from json object.
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100 10)          // Stored in window.policy.[parameter]
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100 11)          json_policy = "{$json_policy}";
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100 12)          policy = JSON.parse(atob(json_policy));
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100 13) </script>
9ba1a779 (David Coutadeur 2024-02-27 18:59:24 +0100 14) <script src="js/ppolicy.js"></script>
fc2a7531 (David Coutadeur 2024-04-26 17:42:07 +0200 15) {if $captcha_js}
fc2a7531 (David Coutadeur 2024-04-26 17:42:07 +0200 16) {$captcha_js nofilter}
fc2a7531 (David Coutadeur 2024-04-26 17:42:07 +0200 17) {/if}
c342f77a (Clément OUDOT   2021-01-13 11:13:44 +0100 18) {if ($questions_count > 1)}
c342f77a (Clément OUDOT   2021-01-13 11:13:44 +0100 19) <script src="js/jquery.selectunique.js"></script>
c342f77a (Clément OUDOT   2021-01-13 11:13:44 +0100 20) <script>$(document).ready(function() { $('.question').selectunique(); })</script>
c342f77a (Clément OUDOT   2021-01-13 11:13:44 +0100 21) {/if}
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 22) </body>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 23) </html>
16:45 $ git blame templates/header.tpl
40528c33 (Clément OUDOT   2020-10-25 18:06:45 +0100  1) <!DOCTYPE html>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  2) <html lang="{$lang}">
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  3) <head>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  4)     <title>{$msg_title}</title>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  5)     <meta charset="utf-8" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  6)     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  7)     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  8)     <meta name="author" content="LDAP Tool Box" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100  9)     <link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css" />
45254838 (David Coutadeur 2024-03-12 10:26:35 +0100 10)     <link rel="stylesheet" type="text/css" href="vendor/font-awesome/css/all.min.css" />
45254838 (David Coutadeur 2024-03-12 10:26:35 +0100 11)     <!-- include v4-shims.min.css for compatibility with older icon names, typically: fa-check-square-o -->
45254838 (David Coutadeur 2024-03-12 10:26:35 +0100 12)     <link rel="stylesheet" type="text/css" href="vendor/font-awesome/css/v4-shims.min.css" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 13)     <link rel="stylesheet" type="text/css" href="css/self-service-password.css" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 14) {if $custom_css}
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 15)     <link rel="stylesheet" type="text/css" href="{$custom_css}" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 16) {/if}
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 17)     <link href="images/favicon.ico" rel="icon" type="image/x-icon" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 18)     <link href="images/favicon.ico" rel="shortcut icon" />
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 19) {if $background_image}
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 20)      <style>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 21)        html, body {
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 22)          background: url({$background_image}) no-repeat center fixed;
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 23)          background-size: cover;
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 24)        }
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 25)   </style>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 26) {/if}
fc2a7531 (David Coutadeur 2024-04-26 17:42:07 +0200 27) {if $captcha_css}
fc2a7531 (David Coutadeur 2024-04-26 17:42:07 +0200 28)   <style>{$captcha_css nofilter}</style>
fc2a7531 (David Coutadeur 2024-04-26 17:42:07 +0200 29) {/if}
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 30) </head>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 31) <body>
311da283 (Julien VEDRINE  2020-02-17 13:47:27 +0100 32) <div class="container">

The error message in Chrome:

index.php:119 Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self' www.google.com www.gstatic.com". Either the 'unsafe-inline' keyword, a hash ('sha256-cHwIqHc1H9/dJgzKT7RmVqfyir19aLCtoyGHJGEn/O0='), or a nonce ('nonce-...') is required to enable inline execution. Note also that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

In my nginx proxy:

add_header Content-Security-Policy "default-src 'self' www.google.com www.gstatic.com";
davidcoutadeur commented 4 months ago

Thanks for pointing this out. We'll give a look at this before the 1.7.0 release.

davidcoutadeur commented 4 months ago

Hello @maglub it should be ok with PR #953