WebView App Security: How to Handle SSL, Deep Links, and JavaScript Injection
A WebView app is essentially a browser embedded in a native shell. That means it inherits both web vulnerabilities AND native app attack surfaces. If you're building or maintaining a WebView app, security isn't optional — it's the difference between a safe product and a data breach waiting to happen.
TL;DR: Disable JavaScript where not needed, validate all URLs before loading, implement SSL pinning for sensitive apps, never expose sensitive native APIs through the JavaScript bridge, and always sanitize data flowing between web and native layers.
The WebView Threat Model
WebView apps face threats from three directions:
- Web-side attacks: XSS, CSRF, clickjacking — all standard web vulnerabilities apply
- Bridge attacks: Malicious JavaScript accessing native APIs through the JavaScript bridge
- Network attacks: Man-in-the-middle (MITM), SSL stripping, DNS spoofing
1. SSL/TLS Security
Always Enforce HTTPS
Never allow HTTP connections in your WebView app. Both Android and iOS have mechanisms to enforce this:
- Android: Set
android:usesCleartextTraffic="false"in your AndroidManifest.xml - iOS: App Transport Security (ATS) enforces HTTPS by default. Never disable it in production.
Consider SSL Pinning
For apps handling sensitive data (banking, healthcare, personal information), implement certificate pinning to prevent MITM attacks:
- Pin the public key hash, not the certificate itself (certificates expire)
- Include backup pins in case your primary certificate is rotated
- Be cautious: incorrect pinning can brick your app if certificates change
Pro tip: If you're not sure whether you need SSL pinning, you probably don't. It's essential for financial apps but overkill for content sites. The risk of misconfiguration often outweighs the security benefit for non-sensitive apps.
2. JavaScript Bridge Security
The JavaScript bridge is the most dangerous attack surface in a WebView app. If compromised, an attacker can execute native code from the web layer.
Rules for a Secure Bridge
- Whitelist bridge methods: Only expose methods that are absolutely necessary. Never expose file system access, shell commands, or raw database queries.
- Validate all inputs: Every parameter passed from JavaScript to native code must be validated and sanitized.
- Check the calling URL: Before executing any bridge method, verify that the request comes from your domain, not a third-party iframe or injected script.
- Use postMessage, not evaluateJavaScript: On iOS, prefer WKScriptMessageHandler over evaluating raw JavaScript strings.
Example: Unsafe vs Safe Bridge
// ❌ UNSAFE: Exposes file system to any JavaScript
bridge.registerHandler("readFile", (path) => {
return fs.readFileSync(path);
});
// ✅ SAFE: Validates input, restricts to allowed directory
bridge.registerHandler("readConfig", (key) => {
const allowedKeys = ["theme", "language", "fontSize"];
if (!allowedKeys.includes(key)) return null;
return config.get(key);
});
3. URL Navigation Security
A WebView can be tricked into navigating to malicious URLs. Always validate navigation:
Whitelist Allowed Domains
- Intercept all navigation requests in
shouldOverrideUrlLoading(Android) ordecidePolicyFor(iOS) - Only allow navigation to your domain and trusted third-party domains (payment processors, OAuth providers)
- Open unknown URLs in the system browser, not inside your WebView
Deep Link Validation
If your app supports deep links (custom URL schemes or Universal Links), validate every incoming URL:
- Never load arbitrary URLs from deep links into your WebView
- Validate the host and path against a whitelist
- Sanitize query parameters before passing them to your web content
4. Cookie and Session Security
- Secure flag: Ensure session cookies have the
Secureflag set (HTTPS only) - HttpOnly flag: Prevents JavaScript from accessing session cookies, reducing XSS impact
- SameSite attribute: Set to
LaxorStrictto prevent CSRF attacks. Note:SameSite=Nonemay be needed for cross-origin iframes in WebView. - Persistent sessions: Use the native Keychain (iOS) or EncryptedSharedPreferences (Android) for storing authentication tokens, not just cookies
5. Content Security
Prevent JavaScript Injection
- Implement Content Security Policy (CSP) headers on your server
- Disable
allowFileAccessandallowContentAccesson Android WebView (they're enabled by default!) - On Android, set
setJavaScriptEnabled(true)only for your main content — disable it for error pages or static content
Disable Dangerous WebView Settings
// Android: Secure WebView settings
webView.settings.apply {
allowFileAccess = false
allowContentAccess = false
allowFileAccessFromFileURLs = false
allowUniversalAccessFromFileURLs = false
setGeolocationEnabled(false) // unless needed
}
Security Checklist Summary
| Category | Action | Priority |
|---|---|---|
| Network | Enforce HTTPS everywhere | Critical |
| Network | SSL pinning for sensitive apps | High |
| Bridge | Whitelist bridge methods | Critical |
| Bridge | Validate calling URL origin | Critical |
| Navigation | Domain whitelist for URLs | High |
| Navigation | Deep link validation | High |
| Data | Secure cookie flags | High |
| Data | Disable file access in WebView | Critical |
| Content | CSP headers on server | Medium |
FAQ
Is a WebView app less secure than a native app?
Not inherently. A well-configured WebView with proper security measures can be just as secure as a native app. The risk comes from misconfiguration — especially leaving JavaScript bridge methods too permissive or not validating URLs.
Should I disable JavaScript in WebView?
Only if your content doesn't need it (rare for modern web apps). For most apps, JavaScript is required for the site to function. Focus on Content Security Policy and bridge security instead of disabling JS entirely.
How does Code2Native handle security?
The generated apps include HTTPS enforcement, domain whitelisting, secure JavaScript bridge with origin validation, proper cookie handling, and disabled file access by default. All sensitive native APIs require explicit opt-in during the build configuration.
Code2Native Engineering
Engineering team
Written by the Code2Native engineering team — the people who build and operate the cloud build pipeline.