flawopen.com/XSS в Swift/loadHTMLString
Безопасен ли WKWebView.loadHTMLString в iOS для недоверенного содержимого?
Не автоматически: WKWebView разбирает переданную строку как HTML, поэтому теги и разметка, способная запускать скрипты, остаются активными, пока содержимое не является доверенным или не обработано для нужного контекста. Для обычного текста и пользовательского HTML нужны разные меры.
Безопасное использование
let html = "\(untrustedText)
" webView.loadHTMLString(html, baseURL: nil)
func escapeHTMLText(_ value: String) -> String {
value
.replacingOccurrences(of: "&", with: "&")
.replacingOccurrences(of: "<", with: "<")
.replacingOccurrences(of: ">", with: ">")
.replacingOccurrences(of: "\"", with: """)
.replacingOccurrences(of: "'", with: "'")
}
let html = "\(escapeHTMLText(untrustedText))
"
webView.loadHTMLString(html, baseURL: nil)
Дополнительный риск для проверки
Обработчик сообщений в мире страницы даёт её скриптам путь к коду приложения. `WKContentWorld` может разделять среды JavaScript, но скрипты страницы и приложения по-прежнему используют общий DOM. Если вместе используются недоверенный HTML и мост, предоставляйте только минимальные возможности, проверяйте сообщение и его frame и отдельно авторизуйте каждое действие; не путайте разделение миров с авторизацией.
Что контролирует baseURL
Apple описывает `baseURL` как базовый адрес для разрешения относительных URL в переданном HTML. Этот параметр не очищает разметку и не отключает JavaScript страницы. Значение `nil` не защищает от XSS и не включает sandbox; политику ресурсов и навигации задавайте отдельно.
Выбирайте защиту для каждой границы
Для обычного текста в HTML-текстовом узле используйте кодирование именно для этого контекста, как ниже; не применяйте его повторно к атрибутам, URL, CSS или JavaScript. Для пользовательского HTML с разметкой используйте поддерживаемый санитайзер с явными списками разрешённых элементов, атрибутов и схем URL. Передавайте значения JavaScript приложения через аргументы `callAsyncJavaScript`, не подставляя их в исходный код. Если JavaScript страницы не нужен, `allowsContentJavaScript` может отключить его как дополнительную меру; это не заменяет корректную обработку вывода.
Вопросы и ответы
Нет: риск тот же, и дополнительной встроенной очистки там тоже нет. Переход на WKWebView обновляет технологию, но сам по себе не устраняет проблему безопасности.
Нет. Apple документирует `baseURL` для разрешения относительных URL. Это не HTML-санитайзер, не переключатель скриптов и не гарантия sandbox.
Нет. Он разделяет среды JavaScript, но они используют общий DOM. Считайте данные DOM и сообщения недоверенными и отдельно авторизуйте каждое нативное действие.
Источники
- Apple Developer — WKWebView
- flawopen.com — XSS в Swift
- Apple — WKWebView.callAsyncJavaScript(_:arguments:in:in:completionHandler:)
- Apple — WKContentWorld
- Apple — WKUserContentController.add(_:contentWorld:name:)
- Apple — WKWebpagePreferences.allowsContentJavaScript
- OWASP — предотвращение Cross Site Scripting
- Apple — WKWebView.loadHTMLString(_:baseURL:)