Resources
Chrome Extension Starter
Complete starter repository with Privy authentication and wallet management.
Set up your Chrome extension project
First, create a React app and install Privy:manifest.json file in the public directory:
Security Guidelines
Below are comprehensive security guidelines for Chrome extensions. You can find more information in the Chrome extension security documentation.Security best practices
Security best practices
Content Security Policy
Add a strict CSP to your manifest to prevent code injection and framing attacks. You can see our broader CSP guidance here.Minimal permissions
Only request permissions your extension actually needs. Limiting permissions reduces attack surface if compromised:fetch() and XMLHttpRequest() to access domains specified in host_permissions. If the extension were compromised, it would still only have permission to interact with websites that meet the match pattern. The attacker would only have limited ability to access sites not in this list.Externally connectable
Restrict which external extensions and web pages can communicate with your extension:Web-accessible resources
Minimize web-accessible resources as they make your extension detectable and create attack vectors:Secure DOM manipulation
Avoiddocument.write() and innerHTML which can lead to script injection:Validate all inputs
Always validate and sanitize inputs, especially from content scripts:Content scripts can be compromised by malicious websites, so treat all messages from content
scripts as potentially malicious.
Configure your Privy dashboard
You’ll get your extension ID after loading the extension in Chrome’s developer mode at
chrome://extensions/.Enabling social login in your extension
Chrome extensions can’t handle social OAuth flows directly in the popup due to security restrictions. Social login requires opening either the options page or a popup window. This provides the full browser context needed for OAuth redirects. Both approaches follow the same flow:- User clicks “Sign in with social” in extension
- Open authentication context (options page or popup window)
- Privy handles the OAuth flow
- User is redirected back to the extension authenticated
1
2
Open authentication context (options page or popup window)
Both approaches use the same authentication logic:
3
Redirect back to the extension
Redirect the user back to the extension after authentication.
That’s it! 🎉
You’ve now implemented Privy authentication in your Chrome extension.Avoiding Chrome Web Store rejection for remote code
The Chrome Web Store prohibits extensions from loading remotely hosted code. By default,@privy-io/react-auth bundles dependencies that inject remote scripts at runtime, which can cause your extension to be rejected during review — even if those scripts never execute.
Remote scripts in the React SDK
The React SDK conditionally loads these remote scripts:Step 1: Disable features that load remote scripts
In the Privy dashboard:- Disable CAPTCHA in App settings > Advanced. This prevents the Turnstile and hCaptcha scripts from loading at runtime.
- Disable Telegram login in Authentication if your extension does not need it. This prevents the Telegram login script from loading.
Step 2: Remove bundled remote-code references
Disabling these features prevents the scripts from loading at runtime, but the Chrome Web Store review scans your extension package statically. The CAPTCHA wrapper code may still appear in your bundled output as a separate chunk, even if it is never executed. To remove it from the bundle entirely, alias the underlying CAPTCHA dependencies to empty stubs in your bundler config:- Webpack
- Vite
Production considerations
Before publishing to the Chrome Web Store:- Remove unnecessary permissions from manifest
- Limit host permissions to only required domains
- Minimize web-accessible resources to reduce attack surface
- Implement strict CSP with
frame-ancestors 'none' - Validate all inputs from content scripts and external sources
- Update OAuth configuration with production URLs in Privy dashboard
- Review externally connectable settings for trusted domains only

