Skip to content

Commit 5940f17

Browse files
committed
Swift: Docs + doctests
1 parent 7585541 commit 5940f17

File tree

5 files changed

+152
-92
lines changed

5 files changed

+152
-92
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Evaluating JavaScript that contains a substring from a remote origin may lead to remote code execution. Code under control of an attacker can execute arbitrary unauthorized actions, including exfiltration of local data by sending it to a third party web service.</p>
7+
8+
</overview>
9+
<recommendation>
10+
11+
<p>When loading JavaScript into a web view, evaluate only known, locally-defined source code. If a part of the input does come from a remote source, instead of injecting it into the JavaScript code to be evaluated, prefer sending it as data to the web view using an API such as <code>WKWebView.callAsyncJavaScript</code> with the <code>arguments</code> dictionary to pass remote data objects.</p>
12+
13+
</recommendation>
14+
<example>
15+
16+
<p>In the following example, a call to <code>WKWebView.evaluateJavaScript</code> evaluates JavaScript source code that is tainted with remote data, potentially introducing a code injection vulnerability.</p>
17+
18+
<sample src="UnsafeJsEvalBad.swift" />
19+
20+
<p>To fix the problem, we sanitize the remote data by passing it using the <code>arguments</code> dictionary of <code>WKWebView.callAsyncJavaScript</code>. This ensures that untrusted data cannot be evaluated as JavaScript source code.</p>
21+
22+
<sample src="UnsafeJsEvalGood.swift" />
23+
24+
</example>
25+
<references>
26+
27+
<li>
28+
<a href="https://developer.apple.com/documentation/webkit/wkwebview/3824703-callasyncjavascript">Apple Developer Documentation - WKWebView.callAsyncJavaScript(_:arguments:in:contentWorld:)</a>
29+
</li>
30+
31+
</references>
32+
</qhelp>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
let webview: WKWebView
2+
let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.json")!)
3+
4+
...
5+
6+
_ = try await webview.evaluateJavaScript("alert(" + remoteData + ")") // BAD
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
let webview: WKWebView
2+
let remoteData = try String(contentsOf: URL(string: "http://example.com/evil.json")!)
3+
4+
...
5+
6+
_ = try await webview.callAsyncJavaScript(
7+
"alert(JSON.parse(data))",
8+
arguments: ["data": remoteData], // GOOD
9+
contentWorld: .page
10+
)

0 commit comments

Comments
 (0)