Swift Dynamic JavaScript Evaluation in a WebView

Dynamic JavaScript evaluation in a WebView

Description

Passing a script built through concatenation or interpolation to WKWebView.evaluateJavaScript can cause external input to execute as JavaScript, allowing code injection in the WebView context.

Potential impact

  • JavaScript injection in the WebView
  • Theft of local data
  • Manipulation of user sessions or displayed content

Remediation

  1. Pass only static scripts to evaluateJavaScript.
  2. Supply external data through APIs that separate it from code, such as the arguments dictionary of callAsyncJavaScript.
  3. Do not concatenate or interpolate user input into JavaScript source strings.

Examples

Before

swift
webView.evaluateJavaScript("console.log(" + remoteData + ")")

After

swift
try await webView.callAsyncJavaScript(
    "console.log(data)",
    arguments: ["data": remoteData],
    contentWorld: .page
)

Explanation:

  • Before: External data is concatenated into JavaScript source and executed.
  • After: Code and data are passed separately.

References