如何在 yii2 中为 smartsupp 聊天添加内容安全策略(CSP)?

How to add Content Security Policy (CSP) in yii2 for smartsupp chat?

我正在使用 Yii2 https://github.com/tomlutzenberger/yii2-smartsupp-chat 小部件,它工作得很好,但无法在他们的网站上录制视频,他们建议添加称为 CSP 的东西。

https://help.smartlook.com/en/articles/3470377-content-security-policy-csp-smartlook

谁能建议在何处以及如何添加以下代码?

Content-Security-Policy: default-src 'self'; script-src 'self' https://*.smartlook.com https://*.smartlook.cloud 'nonce-randomlyGeneratedBase64Nonce' 'unsafe-eval'; connect-src 'self' https://*.smartlook.com https://*.smartlook.cloud; worker-src 'self' blob:

<script nonce="randomlyGeneratedBase64Nonce">...Your Smartlook Tracking Script...</script>

@F Baghi 建议

$randomNonce = Yii::$app->security->generateRandomString(64);

$nonce = "nonce-$randomNonce";

$hostSubdomains = "https://*.smartlook.com https://*.smartlook.cloud";

Yii::$app->response->headers->add(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' $hostSubdomains $nonce 'unsafe-eval'; connect-src 'self' $hostSubdomains; worker-src 'self' blob"
);
  1. YII2 框架有 secure-headers extension 用于配置内容安全策略和其他保护 headers。这是首选方式。

  2. 或者您可以在 web server config 中设置 CSP(参见页面底部的示例)。在这种情况下管理 CSP 并使用 nonce-value 令牌并不容易。

  3. 也可以在meta tag中设置CSP。在这种情况下,任何 third-party 脚本都可以窃取 nonce-value 并使用它,因此这是最不受欢迎的方式。

但是如果您不知道如何以及在哪里设置CSP,为Smartlook设置CSP规则后,您的网页很可能会停止正常运行。因为上面的 CSP 规则仅涵盖 Smartlook 源,但是您的网页有自己的脚本/样式/字体等
所以你需要将Smartlook CSP规则和你自己的网页CSP规则合二为一

最好的方法是首先将 Content-Security-Policy-Report-Only: default-src 'self... 设置为报告模式并检查浏览器控制台错误(在开发工具中)或违规报告。然后将 Content-Security-Policy: default-src 'self... 设置为强制(阻塞)模式。

您需要将 Content-Security-Policy header 添加到 Bootstrap 组件之类的响应组件中。使用 s.th 如:

Yii::$app->response->headers->add(
    'Content-Security-Policy',    
     "default-src 'self' $hostSubdomains http://google.com https://google.com https://www.google.com http://www.google.com"
);

我将在生产中添加的新配置如果成功,我将 post。

分机:- https://github.com/hyperia-sk/yii2-secure-headers

里面 web/main.php

function generateRandomString($length = 10) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}
$randomNonce  = generateRandomString(64);
'components' => [
      ...
      'headers' => [
            'class' => '\hyperia\security\Headers',
            
            ...

            'cspDirectives' => [
                  'default-src' => "'self'"
                  'connect-src' => "'self' https://*.smartlook.com https://*.smartlook.cloud",
                  'script-src' => "'self' https://*.smartlook.com https://*.smartlook.cloud 'nonce-$randomNonce' 'unsafe-eval'",
                  'worker-src' => "'self' blob:",
            ],

            ...
      ]
]

在你的视图文件中 在全局变量中添加 $defaultNonce,您可以在任何地方访问该变量

这就是我在 web/main.php

中为自己做的
 'components'[

 'on beforeRequest' => function ()use($randomNonce) {
        Yii::$app->params['defaultNonce'] = $randomNonce;
    }

]

然后最后下面的代码

$defaultNonce = Yii::$app->params['defaultNonce'] ?? null;

 <script nonce="<?=$defaultNonce?>">
        window.smartlook||(function(d) {
            var o=smartlook=function(){ o.api.push(arguments)},h=d.getElementsByTagName('head')[0];
            var c=d.createElement('script');o.api=new Array();c.async=true;c.type='text/javascript';
            c.charset='utf-8';c.src='https://rec.smartlook.com/recorder.js';h.appendChild(c);
        })(document);
        smartlook('init', 'yourKey');
    </script>