CSP 问题执行内联脚本 Paypal 按钮

Posted

技术标签:

【中文标题】CSP 问题执行内联脚本 Paypal 按钮【英文标题】:CSP problem execute inline script Paypal button 【发布时间】:2020-03-02 03:25:52 【问题描述】:

我正在使用 Braintree javascript v3 sdk 并为我的商店使用 paypal 结帐按钮。 代码示例:

braintree.client.create(
      authorization: 'sandbox_xxxx'
    , function(err, clientInstance) 
      if (err) 
        console.log(err);
        return;
      
braintree.paypalCheckout.create(
            client: clientInstance
          , function (paypalCheckoutErr, paypalCheckoutInstance) 

            if (paypalCheckoutErr) 
              console.error('Error creating PayPal Checkout:', paypalCheckoutErr);
              return;
            

            paypal.Button.render(
              env: 'sandbox',
              commit: true,
              buttonStyle: 
                  color: 'blue',
                  shape: 'rect',
                  size: 'medium'
                ,      
              payment: function () 
                return paypalCheckoutInstance.createPayment(
                    flow: 'checkout', 
                    amount: '10.00', 
                    currency: 'EUR'
                );
              ,

              onAuthorize: function (data, actions) 
                return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) 
                    document.getElementById("paynonce").value = payload.nonce;
                    document.getElementById("paymentform").submit();
                );
              ,

              onCancel: function (data) 
                console.log('checkout.js payment cancelled', JSON.stringify(data, 0, 2));
              ,

              onError: function (err) 
                console.error('checkout.js error', err);
              
            , '#paypal-button').then(function () 

            );

          );
    );

使用我的内容安全策略来保护我的应用程序:

    add_header Content-Security-Policy "default-src 'none'; 
    img-src 'self' *.paypal.com data:;
    manifest-src 'self'; 
    style-src 'self' 'unsafe-inline' *.braintreegateway.com *.braintree-api.com https://www.gstatic.com https://fonts.googleapis.com; 
    script-src 'self' 'nonce-xxxx' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com; 
    font-src 'self' https://fonts.gstatic.com; 
    connect-src 'self' *.paypal.com *.paypalobjects.com *.braintreegateway.com *.braintree-api.com https://fonts.googleapis.com https://www.google-analytics.com https://www.gstatic.com https://fonts.gstatic.com; 
    object-src 'none'; 
    base-uri 'self'; 
    form-action 'self'; 
    frame-src *.paypal.com *.braintreegateway.com *.braintree-api.com; 
    frame-ancestors 'none';";

按钮工作正常,但问题是我仍然收到报告和错误,因为贝宝执行内联 Javascript:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-xxxx' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com". Either the 'unsafe-inline' keyword, a hash ('sha256-xxx='), or a nonce ('nonce-...') is required to enable inline execution.

[Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'nonce-xxxx' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com".

如您所见,我将所有重要的网址都列入了白名单。我还添加了一个随机数来运行脚本:

<script nonce="xxxx" src="https://www.paypalobjects.com/api/checkout.js" data-version-4 log-level="warn"></script>
<script nonce="xxxx" src="https://js.braintreegateway.com/web/3.55.0/js/paypal-checkout.min.js"></script>

不确定是否与: 对于跨站点 cookie,我使用 session.cookie_samesite = Strict 收到此警告:

A cookie associated with a cross-site resource at http://developer.paypal.com/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
A cookie associated with a cross-site resource at http://www.paypal.com/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

总共 9 个贝宝子域。

编辑: 我检查了我的 html,发现有多个内联脚本呈现到 paypalbutton html 检查我的附件。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

对于 cookie 警告,这些警告与 PayPal 的域相关联,更新它们是他们的责任。在当前稳定的 Chrome 中,这些警告纯粹是信息性的,不会影响行为。但是,如果您使用的是 Canary、Dev 或 Beta 版本,您可能会遇到这些 cookie 被阻止的情况。

更多上下文见:

https://web.dev/samesite-cookie-recipes https://www.chromium.org/updates/same-site

听起来好像那些 PayPal 脚本正试图在页面中注入其他脚本。您可能需要考虑'strict-dynamic' 以允许将信任传播到其他资源:

script-src 'nonce-xxxx' 'strict-dynamic';

这将导致白名单或源表达式,例如'self''unsafe-inline',但您也可以将它们包含在不支持strict-dynamic 的浏览器中。

您的错误专门针对'unsafe-inline''unsafe-eval',因此对于较旧的浏览器,您可能还需要考虑这些问题。不过,我会先用strict-dynamic 进行测试,看看是否满足您的需求。

script-src 'nonce-xxxx' 'strict-dynamic' 'unsafe-inline' 'unsafe-eval' 'self' *.paypal.com *.paypalobjects.com *.braintreegateway.com https://www.gstatic.com; 

我还将验证您在页面中肯定没有任何您错过的内联脚本(来自您自己的代码或不是 PayPal 的其他第三方服务),以防这些是错误的来源.

【讨论】:

这不是加载我网站的本地css和js,如何解决?

以上是关于CSP 问题执行内联脚本 Paypal 按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何允许内联 JS 脚本使用 Nonce 进行 CSP

在 Firefox 中使用 csp sha-256 将内联脚本列入白名单

拒绝执行内联事件处理程序,因为它违反了 CSP。 (沙盒)

Web 安全之内容安全策略(Content-Security-Policy,CSP)详解

chrome扩展拒绝执行内联脚本

jQuery 3.5.1 和 CSP 脚本-src-elem