FlawOpen

flawopen.com/XSS en Swift/loadHTMLString

¿Es seguro WKWebView.loadHTMLString en iOS con contenido no confiable?

Página de referencia
Respuesta breve

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

RISKY
let html = "

\(untrustedText)

" webView.loadHTMLString(html, baseURL: nil)
SAFER
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

¿La obsoleta UIWebView es diferente?

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.

¿`baseURL: nil` evita XSS?

No. Apple documenta `baseURL` para resolver URL relativas. No es un sanitizador HTML, un interruptor de scripts ni una garantía de sandbox.

¿`WKContentWorld` aísla el DOM de la página?

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

Véase también Cross-Site Scripting (XSS, CWE-79): cómo funciona y cómo evitarlo en cada lenguaje — flawopen.com XSS reflejado, almacenado y basado en DOM: ¿en qué se diferencian? Riesgos de seguridad de addJavascriptInterface en Android Protección XSS de Angular: valores seguros y APIs de omisión XSS por MIME sniffing: Content-Type y nosniff CSP y escape de salida: ¿necesitas ambos? ¿Es seguro dangerouslySetInnerHTML en React?