FlawOpen

flawopen.com/XSS em Swift/loadHTMLString

O WKWebView.loadHTMLString do iOS é seguro para conteúdo não confiável?

Página de referência
Resposta curta

Não automaticamente: o WKWebView interpreta a string recebida como HTML, então tags e marcação capaz de executar scripts continuam ativas até que o conteúdo seja confiável ou tratado para o contexto correto. Texto simples e HTML rico escrito por usuários exigem controles diferentes.

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)

Risco adicional a verificar

Um manipulador de mensagens no mundo da página dá aos scripts um caminho até o código do app. `WKContentWorld` pode separar ambientes JavaScript, mas os scripts da página e do app ainda compartilham o DOM. Se HTML não confiável e uma ponte coexistirem, exponha apenas a capacidade mínima, valide a mensagem e seu frame e autorize cada operação; não confunda isolamento de mundo com autorização.

O que baseURL controla

A Apple documenta `baseURL` como a base usada para resolver URLs relativas no HTML fornecido. Ele não sanitiza a marcação nem desativa o JavaScript da página. Definir `nil` não é controle contra XSS nem de sandbox; defina separadamente a política de recursos e navegação.

Escolha um controle para cada limite

Para texto simples dentro de um nó de texto HTML, use um codificador próprio para esse contexto, como o abaixo; não o reutilize em atributos, URLs, CSS ou JavaScript. Para HTML rico escrito por usuários, use um sanitizador mantido com listas explícitas de elementos, atributos e esquemas de URL permitidos. Passe valores ao JavaScript do app por argumentos de `callAsyncJavaScript`, sem interpolá-los no código-fonte. Se a página não precisa de JavaScript, `allowsContentJavaScript` pode desativar scripts como defesa em profundidade; isso não substitui o tratamento correto da saída.

Perguntas frequentes

O UIWebView obsoleto é diferente?

Não: ele apresenta o mesmo risco e também não inclui sanitização adicional. Migrar para WKWebView moderniza a tecnologia, mas não corrige a segurança por si só.

`baseURL: nil` impede XSS?

Não. A Apple documenta `baseURL` para resolver URLs relativas. Ele não é um sanitizador HTML, controle de scripts ou garantia de sandbox.

`WKContentWorld` isola o DOM da página?

Não. Ele separa ambientes JavaScript, mas eles compartilham o DOM. Trate dados do DOM e mensagens como não confiáveis e autorize cada operação nativa separadamente.

Referências

Veja também Cross-Site Scripting (XSS, CWE-79): como funciona e como evitar em todas as linguagens — flawopen.com XSS refletido, armazenado e baseado em DOM: quais são as diferenças? Riscos de segurança do addJavascriptInterface no Android Proteção XSS do Angular: padrões seguros e APIs de bypass XSS por MIME sniffing: Content-Type e nosniff CSP e escape de saída: você precisa dos dois? dangerouslySetInnerHTML do React é seguro?