Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
@formidable-webview/web
Advanced tools
A security-aware WebView
component for
react-native-web aimed at
feature parity.
npm add @formidable-webview/web
yarn add @formidable-webview/web
You just need to add a new line to map react-native-webview in your webpack config script (webpack.config.js):
config.resolve.alias['react-native-webview'] = '@formidable-webview/web';
This library uses
<iframe>
elements to render remote resources and reproduce the WebView
component behavior on web pages. This comes with limitations you
should be aware of.
Most notably, some features will only work on same origins. This limitation is enforced by web browsers. Check the Origin column for each feature. When a prop or method is marked with “Same Origin”, it means that one of the following conditions must be met for this feature to work:
Using source={{ html }}
prop;
Using source={{ uri }}
prop and the uri
domain is equal to
the page domain;
Using source={{ uri }}
prop and the uri
domain shares a
superdomain with the page domain and both pages declare the same
superdomain with document.domain
.
You are strongly advised to read the Security Notes chapter to learn more.
This is a support overview for
WebViewSharedProps
in this library.
Prop | Support | Origin | Comments |
---|---|---|---|
javaScriptEnabled | :heavy_check_mark: | Any | When sandboxEnabled is false , JavaScript will always be enabled. |
containerStyle | :heavy_check_mark: | Any | Default styling is guaranteed strictly equivalent with community WebView for mobile platforms. |
style | :heavy_check_mark: | Any | Default styling is guaranteed strictly equivalent with community WebView for mobile platforms. |
renderError | :heavy_check_mark: | Any | Because HTTP requests from the browser cannot be accessed for obvious security reasons, and onerror events are not triggered on iframes in modern browsers, we use a little trick: we send an opaque HTTP HEAD request to the resource, and catch an error when the host is unavailable. You can disable this feature by setting errorRenderingEnabled to false . |
renderLoading | :heavy_check_mark: | Any | |
mediaPlaybackRequiresUserAction | :heavy_check_mark: | Any | |
showsHorizontalScrollIndicator | :heavy_check_mark: | Any | |
showsVerticalScrollIndicator | :heavy_check_mark: | Any | |
source | :warning: | Any | Both remote URI (with the exception of body , headers and method ) and inline HTML (including baseUrl ) are supported. Local files are not supported. |
injectedJavaScript | :warning: | Same origin | |
injectedJavaScriptBeforeContentLoaded | :warning: | Same origin | |
originWhitelist | :warning: | Same origin | Note that contrary to mobile platforms, this prop will default to [] , because it makes little sense to allow navigation within the iframe. |
injectedJavaScriptForMainFrameOnly | :x: | Any | Consider the behavior of web as if this prop was forced to true . |
injectedJavaScriptBeforeContentLoadedForMainFrameOnly | :x: | Any | Consider the behavior of Ersatz as if this prop was forced to true . |
nativeConfig | :x: | None | |
userAgent | :x: | None | |
applicationNameForUserAgent | :x: | None | |
allowsFullscreenVideo | :x: | None | Use allowsFullscreen instead. |
cacheEnabled | :x: | None | |
javaScriptCanOpenWindowsAutomatically | :x: | None | Popups opened with window.open will be suppressed by modern browsers. |
startInLoadingState | :x: | None |
Event Handler | Support | Origin | Comments |
---|---|---|---|
onScroll | :heavy_check_mark: | Any | |
onLoad | :heavy_check_mark: | Any | Invoked when the WebView has finished the load operation with success. |
onLoadEnd | :heavy_check_mark: | Any | Invoked when the WebView has finished the load operation, either with a success or failure |
onError | :heavy_check_mark: | Any | Invoked when the WebView has finished the load operation with a failure. |
onLoadStart | :heavy_check_mark: | Any | Invoked when the WebView is starting to load from a source object. |
onLoadProgress | :heavy_check_mark: | Any | Although we support this, only one event will be fired at the end with progress: 1 . |
onMessage | :warning: | Same Origin | Invoked when a script in the backend has posted a message with window.ReactNativeWebView.postMessage . |
onNavigationStateChange | :warning: | Same Origin | Navigation events from a cross origin will not be tracked. |
onShouldStartLoadWithRequest | :warning: | Same Origin | Navigation events from a cross origin will not be cancelable. |
onHttpError | :x: | None | There is no way to access HTTP requests submitted by browsers. |
onFileDownload | :x: | None |
Prop | Type | Default | Origin | Comments |
---|---|---|---|---|
|
|
| Any | Set iframe |
|
|
| Any | Set iframe |
|
|
| Any | Sets whether Geolocation API can be used. |
|
|
| Any | Sets whether Fullscreen API can be used. |
|
|
| Any | Sets whether PaymentRequest API can be used. |
|
|
| Any | Sets whether the embedded browsing context preserves its own origin. Setting this prop to |
|
|
| Any | Set iframe |
|
|
| Any | By default, the iframe will be sandboxed for safety. You can disable this behavior by setting this prop to |
|
|
| Any | Sets whether |
|
| Variable (depends on other props) | Any | A map to override iframe allow and sandbox attributes to set permission policies. If you need access to specific peripherals, it can be allowed here (microphone, camera, battery …). Read our detailed guide: In-depth Review of prop. |
For any of the unsupported methods, a method is defined but will do nothing when invoked.
Method | Support | Origin | Comments |
---|---|---|---|
requestFocus | :heavy_check_mark: | Any | |
injectJavaScript | :warning: | Same Origin | Document is not accessible in cross-origins iframes. |
reload | :warning: | Any | Reload works, but navigation history will be lost. |
goBack | :x: | None | Navigation is not supported. |
goForward | :x: | None | Navigation is not supported. |
stopLoading | :x: | None | Method is present but does nothing. |
Iframes have been an attack vector and security breach for a long time. Nowadays, iframes feature new attributes to protect the embedding page from attacks.
By default, the IframeWebView
component will sandbox the underlying
iframe
to limit attack surface. You are encouraged to review the
sandbox attribute by reading this article:
www.html5rocks.com/en/tutorials/security/sandboxed-iframes/.
You’ll be able to use webPolicies
prop to grant specific sandbox
permissions. See In-depth Review of prop.
Because of the same origin policy, iframes
will be rendered in a
restricted environment when the origin of the WebView doesn’t match
the origin of the current page. In such restricted environments, the
current page will not have access to the content of the cross origin
page, and thus many features will be affected, among which:
JavaScript injection will be disabled;
Messaging will be disabled;
These restriction do not apply to inline HTML. If you are in control of the cross origin and this cross origin is a subdomain of this page or vice versa, you can set an explicit superdomain in the subdomain page(s) to work around this issue:
document.domain = "company.com";
Also note that when allowsPreserveOrigin
prop is set to false
, the
embedded browsing context will have a unique opaque origin, meaning it
won’t share its origin with the embedding page, nor with itself. Under
the hood, this prop maps to sandbox="allow-same-origin"
attribute when
true
. Disabling the same origin is probably the safest approach,
especially when the embedding page shares its origin with the embedded,
but it comes with great limitations.
You are encouraged to use props mapped to iframe attributes to address security concerns in iframes:
Iframe Attribute | IframeWebView Props | Security Gain |
---|---|---|
allow | webPolicies | Configure which web APIs are available in the embedded page and to which origins, such as payments, peripherals… Read more about permissions policies here. |
csp | csp | Enforce the embedded browsing context to limit the range of origins from which external resources can be loaded. |
referrerpolicy | referrerPolicy | Instruct which referrer the browser should attach with HTTP requests sent to embedded pages hosts. |
sandbox | sandboxEnabled , webPolicies , allowsPreserveOrigin | Whitelist embedded page permissions (javascript, forms…) and allow or deny the page to preserve its own origin. |
If you are using CSP directives, you should make sure the domain
rendered in the WebView
is whitelisted. For example, the most specific
directive for embedding youtube player would be:
Content-Security-Policy: frame-src https://*.youtube.com;
If no frame-src
directives is set, user agents will fallback to, by
order of preference, child-src
and default-src
directives. Read
more on
MDN.
webPolicies
propwebPolicies
prop is a map to override iframe
allow
and
sandbox
attributes to set permission policies. Keys of this map are the
camelCased translation of the following items:
Browser features;
Sandbox features.
The value for each key can either be:
true
, which will enable the permission with no allowlist (defaults
to *
);
false
, which will disable the permission by setting allowlist to
'none'
;
a string, which should follow the allowlist syntax to specify origins.
Some policies will be derived from specific props such as
allowsFullscreen
. Policies from webPolicies
will be merged into
policies derived from props, meaning you can override derived policies
from props with webPolicies
. It is however best advised to favor the
most specific props when available, as other iframe attributes might be
set as a result for retro-compatibility.
Some webPolicies
relate to iframe sandbox
attribute.
When such policies are set, the corresponding rules will be mapped to
both allow
and sandbox
iframe attributes, to follow W3C proposed
standard
while still being retro-compatible. The only exception is
allow-same-origin
, which will be determined by allowsPreserveOrigin
prop. An exhaustive sandbox features list is maintained by W3C and
available
here.
The below component
const webPolicies = {
forms: "https://*.other-domain.com",
};
function MyComponent() {
return (
<IframeWebView
allowsPreserveOrigin
javaScriptEnabled
webPolicies={webPolicies}
source={{ uri: "https://domain.com/" }}
/>
);
}
will be rendered as
<iframe
src="https://domain.com/"
allow="scripts; forms https://*.other-domain.com"
sandbox="allow-same-origin allow-scripts allow-forms"
></iframe>
You will notice a few things:
scripts
rules are derived from javaScriptEnabled
prop;
allow-same-origin
sandbox rule is derived from
allowsPreserveOrigin
prop;
The forms
web policy is mapped to both sandbox
and allow
, but
the latest is more restrictive: it only allows forms on subdomains
of other-domain.com with https protocol. As per the proposed
standard, the most restrictive rule should be enforced if the web
browser supports policy-controlled sandbox features.
Browser features includes, among other things:
Data-sensitive APIs such as Camera, Microphone and other sensors;
Payment and Fullscreen APIs;
Outdated APIs such as synchronous XHR;
Images responsiveness enforcement.
Some features will be derived from specific props such as:
allowsPayment
;
allowsFullscreen
;
mediaPlaybackRequiresUserAction
;
geolocationEnabled
.
These props will map to any of the corresponding web features. An exhaustive features list is maintained by W3C and available here.
The below component
const webPolicies = {
accelerometer: "https://domain.cdn.com",
camera: false,
// Don't do this; this policy is derived from allowsFullscreen prop.
fullscreen: false,
pictureInPicture: true
};
function MyComponent() {
return (
<IframeWebView
allowsPayment
allowsFullscreen
javaScriptEnabled
webPolicies={webPolicies}
source={{ uri: "https://domain.com/" }}
/>
);
}
will be rendered as
<iframe
src="https://domain.com/"
allow="accelerometer https://domain.cdn.com; camera 'none'; payment; fullscreen; picture-in-picture"
sandbox="allow-same-origin allow-scripts"
></iframe>
FAQs
🚀 Render WebViews with react-native-web
We found that @formidable-webview/web demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.