The react-native-webview package embeds a full native browser view inside a React Native app, and unless you constrain what it can load and execute, it becomes one of the largest attack surfaces in a mobile application. It is the officially recommended WebView component since the core WebView was extracted out of React Native, and it powers everything from in-app help pages to embedded checkout flows.
The library itself is well maintained. The current release at the time of writing is 13.16.1, published to npm with a healthy release cadence. The risk is almost never a bug in the package. It is how you wire it up.
Why a WebView is inherently risky
A WebView renders arbitrary HTML and JavaScript with the network access and, potentially, the native capabilities of your app. When you use react native webview to load content you control from a trusted origin, the risk is modest. The moment you load a remote URL, follow links inside the page, or inject JavaScript that talks back to native code, you are running untrusted code next to your users' data.
Three categories of problem show up repeatedly in mobile pentests:
- Cross-site scripting reaching the native bridge. If injected script can call
window.ReactNativeWebView.postMessage, an XSS bug in the loaded page becomes a channel into your React Native layer. - Open navigation. A WebView that follows any link can be steered to a malicious origin through a redirect or a crafted deep link.
- File and content access. Enabling file access or universal access from file URLs lets loaded content read local files.
CVE-2020-6506 and the Android WebView layer
The most cited advisory associated with react-native-webview is CVE-2020-6506, a universal cross-site scripting (UXSS) issue. It is worth being precise about what it actually is: the flaw lived in the underlying Android WebView system component, not in the JavaScript of the library. It allowed a cross-origin iframe to execute script in the top-level document.
The vulnerability affected apps that allowed navigation to arbitrary URLs when running on devices with an Android System WebView older than 83.0.4103.106. The remediation had two parts. Users needed to update the Android System WebView via the Play Store, and on the library side, react-native-webview 11.0.0 introduced a prop to restrict which origins the WebView would render. The lesson generalizes: much of your WebView's security posture depends on a platform component you do not ship, so you cannot assume the runtime is patched.
The props that actually matter
Most hardening comes down to turning capabilities off unless you genuinely need them. The high-value settings:
<WebView
source={{ uri: 'https://app.example.com/help' }}
originWhitelist={['https://app.example.com']}
javaScriptEnabled={true}
allowFileAccess={false}
allowFileAccessFromFileURLs={false}
allowUniversalAccessFromFileURLs={false}
allowsBackForwardNavigationGestures={false}
onShouldStartLoadWithRequest={(req) => req.url.startsWith('https://app.example.com')}
/>
The originWhitelist prop and the onShouldStartLoadWithRequest callback are your navigation guardrails. Together they ensure the WebView renders only origins you trust and refuses to follow a link off to somewhere you did not sanction. Setting the three file-access props to false closes the local-file read path. If you do not need JavaScript at all, disabling it entirely removes the largest single risk.
Locking down the message bridge
The bridge between web and native is the feature people reach for and the feature attackers love. If your page calls postMessage and your native side handles it with onMessage, treat every message as hostile input:
const onMessage = (event) => {
let payload;
try {
payload = JSON.parse(event.nativeEvent.data);
} catch {
return; // reject anything that is not the shape you expect
}
if (payload.type !== 'ADD_TO_CART') return;
// validate every field before acting on it
};
Never eval message content, never map a message field directly to a native action without an allowlist of permitted actions, and never inject secrets into the page through injectedJavaScript assuming the page cannot leak them. Content rendered in a WebView can be inspected, so anything you inject is effectively public.
Managing it as a dependency
react-native-webview brings its own transitive footprint through the React Native and platform toolchains. Keep the package current, because navigation and origin-handling fixes land regularly, and watch the advisories for both the JavaScript package and the native WebView runtime it wraps. An SCA tool such as Safeguard can flag when a version you depend on has a published advisory, including issues that arrive transitively rather than in the top-level package.json.
For remote content you own, pair the client-side hardening above with a strict Content Security Policy served on the pages the WebView loads. That gives you defense in depth: even if a WebView setting drifts during a refactor, the CSP still constrains what injected script can reach. Dynamic testing against the deployed pages, covered in our guide on DAST scanning, catches the server-side XSS that would otherwise flow straight into the bridge.
FAQ
Is react-native-webview safe to use in production?
Yes, when configured defensively. The library is actively maintained and widely deployed. Risk comes from loading untrusted content, leaving file access enabled, or exposing the native message bridge without validation. Whitelist origins, disable file access you do not need, and validate every onMessage payload.
What is CVE-2020-6506?
CVE-2020-6506 is a universal XSS vulnerability in the Android System WebView component that affected React Native apps allowing navigation to arbitrary URLs on Android WebView versions older than 83.0.4103.106. Fixing it required updating the Android System WebView and restricting navigation origins in the app.
How do I prevent XSS from reaching my native code?
Restrict which origins the WebView can load with originWhitelist and onShouldStartLoadWithRequest, serve a strict Content Security Policy on the pages you render, and treat every message received through onMessage as untrusted by parsing and validating it against an allowlist of expected actions.
Should I disable JavaScript in the WebView?
If the content you render does not need it, yes. Disabling JavaScript removes the largest class of WebView risk. When you do need it, keep the origin whitelist tight and never inject secrets through injectedJavaScript, since anything in the page can be read.