MASTG-BEST-0033: Securely Load File Content in a WebView
Avoid Enabling allowFileAccessFromFileURLs and allowUniversalAccessFromFileURLs¶
For WKWebView, allowFileAccessFromFileURLs and allowUniversalAccessFromFileURLs are not part of the public iOS WKWebView API. They are commonly accessed through Key-Value Coding (KVC), but should remain disabled unless there is a specific, well justified need.
If you must enable these properties, ensure that:
- The WebView only loads trusted content from controlled sources.
- Proper input validation and sanitization are implemented.
- The app does not store sensitive data in locations accessible to the WebView.
These settings apply only to WKWebView. UIWebView historically allowed broader local file access and lacked the modern isolation and control model provided by WKWebView, which is one reason UIWebView was deprecated and replaced. See Migrate from UIWebView to WKWebView.
Load Local Files Securely¶
When loading local HTML using loadHTMLString(_:baseURL:) or load(_:mimeType:characterEncodingName:baseURL:), set the baseURL deliberately.
- For
WKWebView, settingbaseURLtonilgives the document an opaque origin. This prevents it from being treated as same origin with local files and helps stop access to other local resources. - If the page needs bundled subresources such as CSS, images, or JavaScript, prefer
loadFileURL(_:allowingReadAccessTo:)orloadFileRequest(_:allowingReadAccessTo:)with a narrowly scoped read access URL. - If you do use a
file://base URL, keep it limited to a controlled resource location such as the app bundle.
Avoid broad file:// base URLs unless they are strictly necessary.
Use loadFileURL and loadFileRequest Carefully¶
When using loadFileURL(_:allowingReadAccessTo:) or loadFileRequest(_:allowingReadAccessTo:), ensure that the allowingReadAccessTo parameter grants the minimum required file system scope.
// Good: Restrict access to a specific file
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
.appendingPathComponent("safe.html")
webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL)
// Risky: Grants access to an entire directory
let dirURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
webView.loadFileURL(fileURL, allowingReadAccessTo: dirURL) // Avoid if possible
If directory access is required, ensure that the directory contains only WebView assets and no sensitive app data.
Additional Considerations¶
Even when these precautions are followed, WebViews should only load content from trusted sources. If attacker-controlled JavaScript executes in a WebView that can read local files, it may read and exfiltrate sensitive data from the app sandbox.
- Disable content JavaScript when the WebView only displays static content, using
WKWebpagePreferences.allowsContentJavaScript = false. - Avoid loading untrusted input into WebViews to prevent HTML or JavaScript injection.
- Keep WebView accessible files separate from app data, secrets, and credentials.
- Prefer loading content from the app bundle or controlled sources instead of broad
file://paths. - Consider App Bound Domains for WebViews that should only access app controlled domains and use powerful WebKit APIs.
Tests¶
MASTG-TEST-0333: Overly Broad File Read Access in WebViews MASTG-TEST-0335: WebView File Origin Access Relaxed by Configuration MASTG-TEST-0336: Runtime Setting of Relaxed WebView File Origin Policies