Como posso ter certeza de que meus arquivos JavaScript entregues em um CDN não foram alterados?

88

Estou trabalhando em um cenário em que alguns arquivos JavaScript devem ser hospedados em um CDN. Desejo ter algum mecanismo para que, quando esses arquivos forem baixados no lado do usuário, eu possa garantir que os arquivos não foram adulterados e, de fato, vêm do CDN especificado.

Eu entendo que a tarefa é muito fácil se eu estiver usando SSL, mas ainda assim, quero garantir que os arquivos certos sejam servidos mesmo em HTTP sem SSL.

Tanto quanto eu pude pesquisar, não há mecanismo existente, como assinatura digital para arquivos JavaScript, que seja compatível com várias plataformas. Talvez não seja necessário?

Existe algum método embutido nos navegadores para verificar o autor dos arquivos JavaScript? Há algo que eu possa fazer para fazer isso de maneira segura?

baba26
fonte
13
Embora eu ache essa pergunta interessante, ela não está fora do assunto?
evolutionxbox
20
por que você serviria arquivos em http?
njzk2
12
"Mas por que não existe tal mecanismo?" Porque é muito difícil . Assim que seus dados saírem do servidor, está tudo pronto. HTTPS ajuda, mas se for uma conexão HTTP simples, qualquer validação pode falhar (ou melhor, passar). Um ataque MITM pode apenas modificar sua assinatura esperada e / ou a assinatura daquilo que você recebe antes que o navegador atenda às expectativas. Então, quando o usuário recebe alguma carga útil, ela é considerada completamente segura ... quando não é necessariamente isso.
VLAZ 01 de
4
"Mas por que não existe tal mecanismo?" Porque já existe uma solução barata, eficaz e amplamente aplicável em HTTPS.
Kevin Krumwiede 01 de
9
Provavelmente deve estar em ServerFault ou Security, pois trata-se realmente de servir arquivos de forma segura, e qualquer relação com a programação é apenas tangencial, visto que tais arquivos representam o código-fonte.
sublinhado_d

Respostas:

140

Na verdade, um recurso como esse está sendo elaborado atualmente com o nome de Integridade de sub-recursos . Observe o integrityatributo da <script>tag. Embora ainda não seja totalmente adotado em todo o quadro , ele cumpre exatamente esse propósito.

integrity

Contém metadados embutidos que um agente do usuário pode usar para verificar se um recurso buscado foi entregue sem manipulação inesperada. Consulte Integridade de sub-recursos.

Fonte

Subresource Integrity (SRI) é um recurso de segurança que permite que os navegadores verifiquem se os arquivos que buscam (por exemplo, de um CDN) são entregues sem manipulação inesperada. Ele funciona permitindo que você forneça um hash criptográfico que um arquivo buscado deve corresponder.

Fonte


Exemplo:

<script src="https://example.com/example-framework.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    crossorigin="anonymous"></script>

Observe, entretanto, que isso não o protegerá contra ataques do Man in the Middle se você estiver transferindo seus recursos via HTTP simples. Nesse caso, o código hash pode ser falsificado pelo invasor, tornando inútil a defesa contra arquivos de script manipulados.

Por esse motivo, você deve sempre usar conexões HTTPS seguras em vez de HTTP simples, além das medidas de segurança descritas acima.

Timo
fonte
9
Acho que vale a pena mencionar que a verificação de integridade pode ser facilmente falsificada assumindo que o OP planeja enviar seu HTML em HTTP, bem como seus arquivos de ativos. Se o site deles for HTTPS e eles quiserem fornecer ativos via HTTP, a maioria dos navegadores não gostará disso e ignorará silenciosamente os ativos HTTP.
MonkeyZeus de
3
@MonkeyZeus Isso só seria verdade no caso de um ataque MITM ou se nosso próprio servidor for comprometido, correto? Meu entendimento é que a questão pergunta explicitamente como se defender contra um CDN comprometido.
Timo
10
@TimoSta Exatamente! Sem essas verificações em vigor, se você incluir um script de, por exemplo, https://code.jquery.com/qualquer pessoa que comprometa code.jquery.compoderá executar XSS em seu site, independentemente de estar ou não code.jquery.comsendo acessado por HTTPS. Com essas verificações, o invasor pode apenas impedir o carregamento dos scripts, não substituí-los por scripts maliciosos.
Ajedi32 de
1
@MonkeyZeus Eu adicionei uma nota à minha resposta, declarando suas preocupações. Você concorda com o texto?
Timo
1
@TimoSta Muito bom, gostei! btw, eu fiz +1 antes mesmo de postar meu primeiro comentário :-)
MonkeyZeus
36

Você está procurando verificações de integridade de sub-recursos .

Por exemplo, aqui está o snippet jQuery CDN:

<script src="https://code.jquery.com/jquery-3.1.0.js"
        integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
        crossorigin="anonymous"></script>
Brian
fonte
2
Totalmente inútil porque um invasor pode modificar o campo de integridade ao mesmo tempo em que modifica o script que você está baixando.
Lightness Races in Orbit
15
@LightnessRacesinOrbit: Não se você controlar seu próprio domínio, que é acessado por HTTPS, mas não controla code.jquery.com. Isso pode protegê-lo de um comprometimento code.jquery.com.
SilverlightFox
2
@SilverlightFox: Ok, totalmente inútil contra ataques MITM *
Lightness Races in Orbit
@LightnessRacesinOrbit Sim. Ainda é muito útil e teria evitado este ataque, por exemplo: bleepingcomputer.com/news/security/…
Adrian Mouat
6

Isenção de responsabilidade: como sempre, você só deve considerar esses mecanismos como tendo alguma utilidade ao usar https, pois eles podem ser facilmente desabilitados via MitM com http

Além do mecanismo nas respostas acima, você também pode usar os cabeçalhos de resposta http da política de segurança de conteúdo na página pai.

http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Política de segurança de conteúdo: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng ='

Existem algumas coisas a serem observadas aqui. O prefixo sha * - especifica o algoritmo usado para gerar o hash. No exemplo acima, sha256- é usado. CSP também oferece suporte para sha384- e sha512-. Ao gerar o hash, não inclua as tags. A capitalização e os espaços em branco também são importantes, incluindo espaços em branco à esquerda ou à direita.

Usando o Chrome 40 ou posterior, você pode abrir DevTools e recarregar sua página. A guia Console conterá mensagens de erro com o hash sha256 correto para cada um de seus scripts embutidos.

Este mecanismo já existe há algum tempo, então o suporte do navegador é provavelmente muito bom, mas certifique-se de verificar.

Além disso, se você quiser garantir que navegadores não compatíveis mais antigos não sejam inseguros, inclua um script de redirecionamento síncrono na parte superior da página que não seja permitido pela política.

Fabio Beltramini
fonte
já existe há algum tempo, mas o suporte ao navegador não é muito bom. caniuse.com/subresource-integrity
Sp0T
@ Sp0t - Integridade de sub-recursos (sobre o que trata seu link) é o mecanismo nas outras respostas. Minha resposta é sobre a política de segurança de conteúdo, que tem um suporte muito melhor
Fabio Beltramini
3

Há um ponto importante sobre o que esse tipo de assinatura pode e não pode fazer. Ele pode proteger o usuário de ataques hipotéticos nos quais alguém modifica seu código. Ele não pode garantir ao seu site que seu código seja o código que está sendo executado. Em outras palavras, você ainda não pode confiar em nada que venha do cliente ao seu site.

ddyer
fonte
2

Se o modelo do seu adversário permite que um invasor modifique os arquivos JavaScript à medida que são entregues a partir de um CDN, o modelo do seu adversário permite que um invasor modifique a fonte de referência à medida que é entregue para remover qualquer tentativa de verificação, para alterar o endereço de origem para outro que não o CDN e / ou para remover a referência ao JavaScript inteiramente.

E não vamos abrir a lata de vermes de como seu aplicativo pode determinar se o resolvedor do usuário está ou não resolvendo corretamente para o CDN por meio de solicitações HTTP (ou qualquer outro mecanismo que não tenha uma cadeia de confiança verificada).

/ etc / hosts:

#  ...
1.2.3.4    vile-pirates.org    trustworthy.cdn
#  ...
Eric Towers
fonte
2
A primeira frase é totalmente falsa. E se a página de referência for carregada por HTTPS e o arquivo JavaScript for carregado por HTTP-não-S?
user253751
Ou se o próprio CDN estiver comprometido, mas não o seu servidor?
Ajedi32
@immibis: Eu escolho assumir que o OP não é tão irracional a ponto de propor tal cenário.
Eric Towers
1
@immibis Não é por isso que os navegadores geralmente não permitem que páginas HTTPS carreguem JS sobre HTTP?
Barmar
1
@immibis Eu estava dizendo que melhora uma situação que nem é possível, porque os navegadores não permitem.
Barmar
1

Você pode garantir isso com Subresource Integrity. Muitos CDNs públicos incluem hashes SRI no código incorporável oferecido em sites de CDN. Por exemplo, em PageCDN, quando você clica no arquivo jquery no jQuery CDN página, você tem a opção de copiar a URL ou usar a tag script que contém hash de SRI como abaixo:

<script src="https://pagecdn.io/lib/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>

No carregamento da página, o navegador emitirá uma solicitação para este recurso e, na conclusão da solicitação, ele combinará o hash do arquivo recebido com aquele fornecido como o valor de integridade na tag de script. Se os dois hashes não corresponderem, o navegador descartará o arquivo jquery.

No momento, esse recurso é compatível com 91% dos navegadores em todo o mundo. Mais detalhes sobre caniuse .

5377037
fonte