Skip to content

Commit

Permalink
Prevent swizzling WKWebView when we detect is not safe to do so (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArielDemarco authored Jan 21, 2025
1 parent 239a70f commit 3f48e0a
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions Sources/EmbraceCore/Capture/WebView/WebViewCaptureService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import OpenTelemetryApi
public final class WebViewCaptureService: CaptureService {

@objc public let options: WebViewCaptureService.Options
private static let knownBadProxies = [
"SafeDKWKNavigationDelegateInterceptor"
]
private let lock: NSLocking
private var swizzlers: [any Swizzlable] = []

Expand Down Expand Up @@ -59,11 +62,30 @@ public final class WebViewCaptureService: CaptureService {
}

private func initializeSwizzlers() {
swizzlers.append(WKWebViewSetNavigationDelegateSwizzler(delegate: self))
swizzlers.append(WKWebViewLoadRequestSwizzler())
swizzlers.append(WKWebViewLoadHTMLStringSwizzler())
swizzlers.append(WKWebViewLoadFileURLSwizzler())
swizzlers.append(WKWebViewLoadDataSwizzler())
if shouldPreventFromKnownSwizzlingErrors() {
swizzlers.append(WKWebViewSetNavigationDelegateSwizzler(delegate: self))
swizzlers.append(WKWebViewLoadRequestSwizzler())
swizzlers.append(WKWebViewLoadHTMLStringSwizzler())
swizzlers.append(WKWebViewLoadFileURLSwizzler())
swizzlers.append(WKWebViewLoadDataSwizzler())
}
}

// Embrace wants to track internal navigation events in `WKWebViews` to assist our customers with debugging.
// To do so, we forcefully set a nil `WKNavigationDelegate` to be injected into the `WKWebView` when the delegate is already nil.
// This is safe because any other player is free to overwrite our delegate with their own (and we'd swizzle and track their delegate).
// Occasionally, players doing something similar (proxying) implement their logic poorly and fail to recognize that they must overwrite
// our delegate, or they could have weird validations that prevent from calling the original delegate.
// In this case it is not safe for us to inject as we are likely to break application functionality.
// To err on the side of caution we will not inject if we detect these problematic classes in memory.
// Currently the only known bad-actor is SafeDK/AppLovin.
private func shouldPreventFromKnownSwizzlingErrors() -> Bool {
for proxy in WebViewCaptureService.knownBadProxies {
if NSClassFromString(proxy) != nil {
return false
}
}
return true
}
}

Expand Down

0 comments on commit 3f48e0a

Please sign in to comment.