-
Notifications
You must be signed in to change notification settings - Fork 3k
WKWebView navigation and security considerations
WKWebView navigations trigger the following:
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)
-
webView.url
KVO change
For security reasons it is critical not to update the displayed URL in the URL bar until the old html document is destroyed and the new one created (alternatively it could be said the JS context of the old page must be destroyed and a new one created). A common spoofing attack is to trick the browser to change the displayed URL and use JS to change the displayed page to a spoofed page.
The didStartProvisionalNavigation
happens too early to be used safely, only didCommit
happens at the correct time.
Sites such as youtube.com use JS frameworks that navigate purely by XHR requests to change the document body without navigating; they create the appearance of navigating by pushing URLs to the browser history using window.history.pushState
.
In WKWebView, these do not trigger any traditional navigational events:
- JS events not called:
onload
,hashchange
,DOMContentLoaded
, documentreadystatechange
- no WKWebView delegates get called
Fortunately WKWebView.url
KVO catches the change in the URL for the page. It is considered safe to update the displayed URL for navigations within an origin as spoofing attacks are not currently known to able to exploit that (see the 'same origin policy' link below). It is worth noting there is a cross-origin restriction on the history.pushState
function also. Therefore if the webpage URL changes but the origin is unchanged, it is safe to update the displayed URL in this case. In any other case, only didCommit
should be used.
See also: