Skip to content

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, setting baseURL to nil gives 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:) or loadFileRequest(_: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