javaScriptEnabled
property of WKWebView
, it can be completely disabled, preventing all script injection flaws.JavaScriptCanOpenWindowsAutomatically
can be used to prevent JavaScript from opening new windows, such as pop-ups.hasOnlySecureContent
property can be used to verify resources loaded by the WebView are retrieved through encrypted connections.WKWebView
implements out-of-process rendering, so memory corruption bugs won't affect the main app process.SFSafariViewController
and this is one of the reasons why the usage of WKWebView
is recommended when the goal is extending the app's user interface.SFSafariViewController
also shares cookies and other website data with Safari.SFSafariViewController
are not visible to the app, which cannot access AutoFill data, browsing history, or website data.SFSafariViewController
s may not be hidden or obscured by other views or layers.init(frame:configuration:)
):WKWebView
s, as a best practice, JavaScript should be disabled unless it is explicitly required. To verify that JavaScript was properly disabled search the project for usages of WKPreferences
and ensure that the javaScriptEnabled
property is set to false
:UIWebView
s, when using WKWebView
s it is possible to detect mixed content (HTTP content loaded from a HTTPS page). By using the method hasOnlySecureContent
it can be verified whether all resources on the page have been loaded through securely encrypted connections.
In the compiled binary:ObjC.choose()
to find instances of the different types of WebViews and also search for the properties javaScriptEnabled
and hasonlysecurecontent
:loadHTMLString:baseURL:
or loadData:MIMEType:textEncodingName:baseURL:
to load content.loadHTMLString:baseURL:
or loadData:MIMEType:textEncodingName:baseURL:
to load local HTML files and loadRequest:
for web content. Typically, the local files are loaded in combination with methods including, among others: pathForResource:ofType:
, URLForResource:withExtension:
or init(contentsOf:encoding:)
. In addition, you should also verify if the app is using the method loadFileURL:allowingReadAccessToURL:
. Its first parameter is URL
and contains the URL to be loaded in the WebView, its second parameter allowingReadAccessToURL
may contain a single file or a directory. If containing a single file, that file will be available to the WebView. However, if it contains a directory, all files on that directory will be made available to the WebView. Therefore, it is worth inspecting this and in case it is a directory, verifying that no sensitive data can be found inside it.file://
scheme is always enabled.file://
URLs is always enabled.file://
URLs is always enabled.UIWebView
where baseURL
is also set to nil
you will see that it is not set to "null", instead you'll obtain something similar to the following: applewebdata://5361016c-f4a0-4305-816b-65411fc1d78
0. This origin "applewebdata://" is similar to the "file://" origin as it does not implement Same-Origin Policy and allow access to local files and any web resources.allowFileAccessFromFileURLs
(WKPreferences
, false
by default): it enables JavaScript running in the context of a file://
scheme URL to access content from other file://
scheme URLs.allowUniversalAccessFromFileURLs
(WKWebViewConfiguration
, false
by default): it enables JavaScript running in the context of a file://
scheme URL to access content from any origin.JSContext
, JavaScriptCore automatically wraps the block in a JavaScript function.JSExport
-inherited protocol are mapped to JavaScript objects that are available to all JavaScript code. Modifications of objects that are in the JavaScript environment are reflected in the native environment.JSExport
protocol are made accessible to JavaScript code.
Look out for code that maps native objects to the JSContext
associated with a WebView and analyze what functionality it exposes, for example no sensitive data should be accessible and exposed to WebViews.
In Objective-C, the JSContext
associated with a UIWebView
is obtained as follows:WKWebView
can still send messages back to the native app but in contrast to UIWebView
, it is not possible to directly reference the JSContext
of a WKWebView
. Instead, communication is implemented using a messaging system and using the postMessage
function, which automatically serializes JavaScript objects into native Objective-C or Swift objects. Message handlers are configured using the method add(_ scriptMessageHandler:name:)
."name"
(or "javaScriptBridge"
in the example above) causes the JavaScript function window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage
to be defined in all frames in all web views that use the user content controller. It can be then used from the HTML file like this:evaluateJavascript
below) you can be interested on overriding the function that is going to be executed to steal the result.
For example, in the script below the function javascriptBridgeCallBack
is going to be executed with 2 params (the called function and the result). If you control the HTML that is going to be loaded you can create an alert with the result like:stringByEvaluatingJavaScriptFromString:
for UIWebView
and evaluateJavaScript:completionHandler:
for WKWebView
).console.log()
are not printed to the Xcode logs. It's still relatively easy to debug web content with Safari's developer tools, although there are a couple of limitations: