flawopen.com/XSS en Swift/loadHTMLString
¿Es seguro WKWebView.loadHTMLString en iOS con contenido no confiable?
No automáticamente: WKWebView interpreta la cadena recibida como HTML, por lo que las etiquetas y el marcado con capacidad de ejecutar scripts siguen activos hasta que el contenido sea confiable o se trate para el contexto correcto. El texto simple y el HTML enriquecido creado por usuarios requieren controles distintos.
Uso seguro
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)
Riesgo adicional que debes revisar
Un manejador de mensajes del mundo de la página ofrece a sus scripts una vía al código de la app. `WKContentWorld` puede separar entornos JavaScript, pero los scripts de la página y de la app siguen compartiendo el DOM. Si conviven HTML no confiable y un puente, expón solo la capacidad mínima, valida el mensaje y su frame y autoriza cada operación; no confundas la separación de entornos con autorización.
Qué controla baseURL
Apple documenta `baseURL` como la base para resolver URL relativas en el HTML proporcionado. No sanea el marcado ni desactiva el JavaScript de la página. Asignar `nil` no protege contra XSS ni configura un sandbox; define por separado la política de recursos y navegación.
Elige un control para cada límite
Para texto simple dentro de un nodo de texto HTML, usa un codificador específico para ese contexto, como el siguiente; no lo reutilices en atributos, URL, CSS ni JavaScript. Para HTML enriquecido creado por usuarios, usa un sanitizador mantenido con listas explícitas de elementos, atributos y esquemas de URL permitidos. Pasa valores al JavaScript de la app mediante argumentos de `callAsyncJavaScript`, sin interpolarlos en el código fuente. Si la página no necesita JavaScript, `allowsContentJavaScript` puede desactivar los scripts como defensa en profundidad; no sustituye el tratamiento correcto de la salida.
Preguntas frecuentes
No: presenta el mismo riesgo y tampoco incorpora sanitización adicional. Migrar a WKWebView moderniza la tecnología, pero por sí solo no soluciona la seguridad.
No. Apple documenta `baseURL` para resolver URL relativas. No es un sanitizador HTML, un interruptor de scripts ni una garantía de sandbox.
No. Separa entornos JavaScript, pero estos comparten el DOM. Trata los datos del DOM y los mensajes como no confiables y autoriza cada operación nativa por separado.
Referencias
- Apple Developer — WKWebView
- flawopen.com — XSS en Swift
- Apple — WKWebView.callAsyncJavaScript(_:arguments:in:in:completionHandler:)
- Apple — WKContentWorld
- Apple — WKUserContentController.add(_:contentWorld:name:)
- Apple — WKWebpagePreferences.allowsContentJavaScript
- OWASP — Prevención de Cross Site Scripting
- Apple — WKWebView.loadHTMLString(_:baseURL:)