IC前端更改CSP内容安全策略的方法

发布于 2024-05-14  71 次阅读


前言

首先说明,在前端资产中的index.html中直接添加<meta>标签去设置CSP策略并不能在IC前端应用生效。

修改的原因是,0.13.0版本之后,IC前端资产默认有较严格的CSP内容安全策略,无法加载源站和data:之外的图片资源,也无法向源站和IC的几个必需服务之外的域名发起请求。这会导致无法从图床加载图片、无法从前端直接向OSS发起存储等问题。

更改方法

步骤一:修改适当的安全策略

在前端资产的src/public/.ic-assets.json5文件中修改CSP规则,并请确保该文件位于dfx.json中配置的前端资产路径下。

.ic-assets.json5文件内容示例如下:

[
    {
        "match": "**/*",
        "headers": {
            // Security: The Content Security Policy (CSP) given below aims at working with many apps rather than providing maximal security.
            // We recommend tightening the CSP for your specific application. Some recommendations are as follows:
            // - Use the CSP Evaluator (https://csp-evaluator.withgoogle.com/) to validate the CSP you define.
            // - Follow the “Strict CSP” recommendations (https://csp.withgoogle.com/docs/strict-csp.html). However, note that in the context of the IC,
            //   nonces cannot be used because the response bodies must be static to work well with HTTP asset certification.
            //   Thus, we recommend to include script hashes (in combination with strict-dynamic) in the CSP as described
            //   in https://csp.withgoogle.com/docs/faq.html in section “What if my site is static and I can't add nonces to scripts?”.
            //   See for example the II CSP (https://github.com/dfinity/internet-identity/blob/main/src/internet_identity/src/http.rs).
            // - It is recommended to tighten the connect-src directive. With the current CSP configuration the browser can
            //   make requests to https://*.icp0.io, hence being able to call any canister via https://icp0.io/api/v2/canister/{canister-ID}.
            //   This could potentially be used in combination with another vulnerability (e.g. XSS) to exfiltrate private data.
            //   The developer can configure this policy to only allow requests to their specific canisters,
            //   e.g: connect-src 'self' https://icp-api.io/api/v2/canister/{my-canister-ID}, where {my-canister-ID} has the following format: aaaaa-aaaaa-aaaaa-aaaaa-aaa
            // - It is recommended to configure style-src, style-src-elem and font-src directives with the resources your canister is going to use
            //   instead of using the wild card (*) option. Normally this will include 'self' but also other third party styles or fonts resources (e.g: https://fonts.googleapis.com or other CDNs)

            // Notes about the CSP below:
            // - script-src 'unsafe-eval' is currently required because agent-js uses a WebAssembly module for the validation of bls signatures.
            //   There is currently no other way to allow execution of WebAssembly modules with CSP.
            //   See: https://github.com/WebAssembly/content-security-policy/blob/main/proposals/CSP.md.
            // - We added img-src data: because data: images are used often.
            // - frame-ancestors: none mitigates clickjacking attacks. See https://owasp.org/www-community/attacks/Clickjacking.
            "Content-Security-Policy": "default-src 'self';script-src 'self' 'unsafe-eval';connect-src 'self' http://localhost:* https://icp0.io https://*.icp0.io https://icp-api.io https://xxx.oss-cn-xxxplace.aliyuncs.com;img-src 'self' * data:;style-src * 'unsafe-inline';style-src-elem * 'unsafe-inline';font-src *;object-src 'none';base-uri 'self';frame-ancestors 'none';form-action 'self';upgrade-insecure-requests;",

            // Security: The permissions policy disables all features for security reasons. If your site needs such permissions, activate them.
            // To configure permissions go here https://www.permissionspolicy.com/
            "Permissions-Policy": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()",

            // Security: Mitigates clickjacking attacks.
            // See: https://owasp.org/www-community/attacks/Clickjacking.
            "X-Frame-Options": "DENY",

            // Security: Avoids forwarding referrer information to other origins.
            // See: https://owasp.org/www-project-secure-headers/#referrer-policy.
            "Referrer-Policy": "same-origin",

            // Security: Tells the user’s browser that it must always use HTTPS with your site.
            // See: https://owasp.org/www-project-secure-headers/#http-strict-transport-security
            "Strict-Transport-Security": "max-age=31536000; includeSubDomains",

            // Security: Prevents the browser from interpreting files as a different MIME type to what is specified in the Content-Type header.
            // See: https://owasp.org/www-project-secure-headers/#x-content-type-options
            "X-Content-Type-Options": "nosniff",

            // Security: Enables browser features to mitigate some of the XSS attacks. Note that it has to be in mode=block.
            // See: https://owasp.org/www-community/attacks/xss/
            "X-XSS-Protection": "1; mode=block"
        },
        // Uncomment to redirect all requests from .raw.icp0.io to .icp0.io
        // "allow_raw_access": false
    },
]

步骤二:在链上应用策略

截至目前,IC有个bug,直接重新部署前端资产容器并不能更新CSP安全策略,需要reinstall,即卸载原有容器内容并重新install。

指令如下:

dfx deploy frontend_canister_name --ic --mode reinstall

补充

还要设置clipboard-write 'self',如果是clipboard-write=()的话是不能通过JS复制内容到剪贴板的。

相关资料


A Student on the way to full stack of Web3.