Appearance
Guidance for Content Security Policies (CSPs)
We recommend setting a strict Content Security Policy (CSP) as a part of a defense-in-depth strategy to mitigate XSS (Cross-Site Scripting), clickjacking, and cross-site leak vulnerabilities. CSPs help secure your site by informing your browser of resources that should be allowed to load for each page.
TIP
Content Security Policies impact your site’s functionality, so changes to your CSP should be made with care. Changes to your site may also require updates to your CSP.
CSP Basics
A Content Security Policy (CSP) is a set of rules that tell the browser what sources of content are valid. CSPs help prevent the browser from executing malicious scripts. They can be used to increase the security of any website.
To enable a CSP, you need to configure your web server to return the Content-Security-Policy
HTTP header. In that header, you specify a policy. A policy is described using a set of policy directives, each of which tells the browser what to do with respect to a given resource type.
Example: img-src
directive
For example, the img-src
directive tells the browser sources of images are valid. If you set this CSP header:
Content-Security-Policy: img-src https://my-website.com/
Then any <img>
from other sites will be blocked:
<img src="https://bad-website.com/image.jpg"/> {/* Error! This won't load! */}
Read the following guides to learn more:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
If you are using NextJS, follow their guide to configure your CSP. You can generally set the CSP header directly in your next.config.js
file.
CSP Recommendations
Some important directives
Policy directives tell the browser what to do for a given resource type.
- Keep
script-src
as locked down as possible. - Set
frame-ancestors
tonone
unless you expect your website to be embedded. - Keep
connect-src
as locked down as possible. This will prevent bad actors from injecting scripts and sending compromised data to third parties.
CSP directives for @privy-io/react-auth
As part of enforcing a CSP, you will need to allow certain trusted resources that your site needs to load as part of normal operation, such as the Privy iframe, Privy dependencies, and any other resources you intentionally consume. Below is a list of resources you must allow for Privy to operate as expected:
INFO
If you have a base domain enabled, you must also add your domain-specific Privy instance, e.g. https://privy.your-base-domain.com
.
child-src
- https://auth.privy.io (Privy iframe)
- https://verify.walletconnect.com (WalletConnect iframe)
- https://verify.walletconnect.org (WalletConnect fallback iframe)
frame-src
- https://auth.privy.io (Privy iframe)
- https://verify.walletconnect.com (WalletConnect iframe)
- https://verify.walletconnect.org (WalletConnect fallback iframe)
- https://challenges.cloudflare.com (Cloudflare Turnstile CAPTCHA iframe)
- If your app uses Telegram login or linking, please also add:
- https://oauth.telegram.org (Telegram OAuth domain)
connect-src
- https://auth.privy.io (Privy API)
- wss://relay.walletconnect.com (WalletConnect API)
- wss://relay.walletconnect.org (WalletConnect fallback API)
- wss://www.walletlink.org (Coinbase Wallet API)
- https://*.rpc.privy.systems (Privy RPC provider)
- For any non-Privy RPC providers, add them here (Privy uses the default RPC URL in Viem chain definitions if an override is not provided)
- If your app is on Solana, please also add the Solana cluster endpoints if an override is not provided:
- If your app uses Privy's funding kit, please also add:
- https://api.relay.link (Relay Bridging Provider)
- https://api.testnets.relay.link (Relay Bridging Provider for testnets)
script-src
- https://challenges.cloudflare.com (Cloudflare Turnstile CAPTCHA scripts)
- If your app uses Telegram login or linking, please also add:
- https://telegram.org (Telegram login domain)
Testing and deploying your CSP
TIP
We highly recommend testing your CSP thoroughly before deploying and enforcing in production.
Test your CSP in a staging environment
Run through your standard user flows in a staging environment with CSP enforcement. This may mean connecting to browser extension wallets / mobile app wallets, transacting, logging out, etc.
It is possible that directives need to be updated after Privy SDK upgrades. Whenever upgrading the Privy SDK, always test your CSP again before deploying the update to production.
Other software you use, such as MetaMask, may document their own guidance on CSP usage.
Using Report-Only mode
Most browsers support a Content-Security-Policy-Report-Only
header, which sends violation reports without actually enforcing policies. This allows the developer to judge whether a modification to their CSP will impact their site’s expected functionality.
If your policy is strict, you will see many reported violations due to extensions trying to inject scripts into the browser. This is completely normal. It's best to filter these out to avoid the noise.
Deployment
We recommend that you first deploy your CSP in report-only
mode with the header Content-Security-Policy-Report-Only
. Once it has been validated in production, you can migrate to Content-Security-Policy
, which will enforce directive violations.
Going forward, you can deploy with both Content-Security-Policy-Report-Only
and Content-Security-Policy
headers set simultaneously. This will allow you to test on the report only header and A/B test against your existing policy.
Monitoring
We recommend that you configure the report-uri
to see violation/enforcement reports and set up a monitoring dashboard so you can review reports.