CORS - Qual é a motivação por trás da introdução de pedidos de pré-voo?

Cross-origin resource sharing é um mecanismo que permite a uma página web fazer XMLHttpRequests para outro domínio (de wikipedia), e é muito importante (de mim :).

Tenho mexido com o CORS nos últimos dias e acho que tenho uma boa compreensão de como tudo funciona.

então a minha pergunta não é sobre como funciona o CORS / preflight, é sobre a razão por trás de aparecer com preflights como um novo tipo de pedido. Eu não vejo nenhuma razão pela qual o servidor a precisa enviar um pré - voo (PR) para o servidor B apenas para descobrir se o real pedido (RR) será aceito ou não-certamente seria possível para B aceitar/rejeitar RR sem qualquer PR anterior.

Depois de procurar um pouco, encontrei esta peça de informação em www.w3.org (7. 1. 5):

para proteger os recursos contra pedidos de origem cruzada que não podiam ter origem em determinados agentes de utilizadores antes da existência desta especificação, pré-voo pedido é feito para garantir que o recurso está ciente disso especificacao.

Acho que esta é a frase mais difícil de entender. A minha interpretação (deve chamar - lhe "melhor palpite") é que se trata de proteger o servidor B contra pedidos do servidor C que não está ciente da especificação.

Alguém pode explicar um cenário / mostrar um problema que o PR + RR resolve melhor que o RR sozinho?

Author: Ulysses Alves, 2013-03-13

9 answers

Passei algum tempo confuso quanto ao propósito do pedido de pré-voo, mas acho que já o tenho.

A chave é que os pedidos pré-voo não são uma coisa de segurança. Em vez disso, não mudam as regras.

Os pedidos pré-voo não têm nada a ver com segurança, e não têm nada a ver com as aplicações que estão a ser desenvolvidas agora, com a consciência do CORS. Em vez disso, o mecanismo de pré-voo beneficia os servidores que foram desenvolvidos sem uma consciência do CORS, e funciona como uma verificação de sanidade entre o cliente e o servidor que ambos estão cientes do CORS. Os desenvolvedores do CORS sentiram que havia servidores suficientes lá fora que estavam confiando na suposição de que eles nunca receberiam, por exemplo, um pedido de exclusão cross-domain que eles inventaram o mecanismo de pré-voo para permitir que ambos os lados se opt-in. Consideram que a alternativa, que teria sido simplesmente permitir as chamadas inter-domínios, teria quebrei demasiadas aplicações existentes. Há aqui três cenários:
  1. Servidores antigos, não mais em desenvolvimento, e desenvolvidos antes do CORS. Estes servidores podem fazer suposições de que nunca irão receber, por exemplo, um pedido de exclusão cross-domain. Este cenário é o principal beneficiário do mecanismo de pré-voo. sim, estes serviços já podem ser abusados por um agente de utilizador malicioso ou não conforme( E o CORS não faz nada para alterar isto), mas num mundo com CORS o mecanismo de pré-voo fornece uma "verificação de sanidade" extra para que clientes e servidores não quebrem porque as regras subjacentes da web foram alteradas.

  2. Servidores que ainda estão em desenvolvimento, mas que contêm um monte de código antigo e para o qual não é viável/desejável auditar todo o código antigo para se certificar de que ele funciona corretamente em um mundo de cross-domain. Este cenário permite aos servidores opt-in progressivamente ao CORS, por exemplo, dizendo "Agora vou permitir este cabeçalho particular", "Now i'll allow this particular HTTP verb", "Now i'll allow cookies / auth information to be sent", etc. Este cenário beneficia do mecanismo de pré-voo.

  3. Novos servidores que são escritos com uma consciência do CORS. De acordo com as práticas de segurança padrão, o servidor tem de proteger os seus recursos face a Qualquer pedido de entrada -- os servidores não podem confiar que os clientes não façam coisas maliciosas. Este cenário não beneficia do pré-voo. mecanismo: o mecanismo de pré-voo não traz segurança adicional a um servidor que tenha protegido adequadamente os seus recursos.

 245
Author: Michael Iles, 2013-06-05 20:35:33

qual foi a motivação por trás da introdução de pedidos pré-voo?

Foram introduzidos pedidos de pré-voo para que os navegadores pudessem ter a certeza de que estavam a lidar com um servidor ciente do CORS antes de enviar certos pedidos. Estes pedidos foram definidos como sendo os que eram potencialmente perigosos (mudança de estado) e novos (não é possível perante o CCS devido à mesma Política de origem ). A utilização de pedidos de pré-voo significa que os servidores devem registar-se (respondendo adequadamente ao pré-voo) para os novos, potencialmente perigosos tipos de pedido que o CORS torna possível.

Este é o Significado de esta parte do caderno de especificações: "para proteger os recursos contra pedidos de origem cruzada que não podiam ser originários de certos agentes de utilizadores antes da existência desta especificação, é feito um pedido prévio para garantir que o recurso tem conhecimento desta especificação."

pode dar-me um exemplo?

Vamos. imagine que um utilizador do navegador está ligado ao seu site bancário em A.com. Quando eles navegam para o malicioso B.com, essa página inclui algum Javascript que tenta enviar um pedido DELETE para A.com/account. Uma vez que o usuário está logado em A.com, esse pedido, se enviado, incluirá cookies que identificam o usuário.

Antes do CORS, a mesma Política de origem do navegador teria bloqueado o envio deste pedido. Mas uma vez que o propósito do CORS é fazer apenas este tipo de comunicação de origem cruzada possível, isso já não é apropriado.

O navegador poderia simplesmente enviar o DELETE directamente e deixar tudo para o servidor. Mas e se não estiver ciente do protocolo CORS? Pode ir em frente e executar o perigoso. Ele assumiu que nunca poderia receber tal pedido devido à mesma Política de origem do navegador, e então ele nunca foi projetado para impedir tal ataque.

Para proteger esses servidores não conscientes do CORS, então, o protocolo requer o navegador para enviar primeiro um pedido de pré-voo . Este novo tipo de pedido é algo que apenas servidores conscientes do CORS podem responder corretamente, permitindo que o navegador saiba se é Seguro ou não enviar o real DELETE.

Por que toda esta confusão sobre o navegador, o atacante não pode simplesmente enviar um pedido {[[2]} de seu próprio computador?

Claro, mas tal pedido não incluirá os cookies do utilizador. O ataque que este é projetado para evitar depende do fato que o navegador irá enviar cookies (em particular, informações de autenticação para o Usuário) para o outro domínio, juntamente com o pedido.

parece Que Cross-Site Request Forgery, onde um formulário no site B.com pode POST para A.com com os cookies do usuário e de causar danos.

Isso mesmo. Outra forma de colocar isso é que pedidos de pré-voo foram criados de modo a não aumentar a superfície de ataque da CSRF para não-CORS-cientes servidor.

mas olhando para os requisitos para pedidos "simples" que não requerem pré-luzes, vejo que POST ainda é permitido. Isso pode mudar o estado e apagar dados como um DELETE!

Isso é verdade! O CORS não protege o seu site de ataques da CSRF. Por outro lado, sem o CORS também não está protegido dos ataques da CSRF. O propósito dos pedidos de pré-voo é apenas para limitar a sua exposição CSRF ao que já existia nos pré-Coors mundo.

suspiro. Aceito relutantemente a necessidade de pedidos pré-voo. Mas por que temos que fazer isso para cada recurso (URL) no servidor? O servidor ou lida com o CORS ou não..

Tens a certeza disso? Não é incomum que vários servidores lidem com pedidos de um único domínio. Por exemplo, pode ser que os pedidos para A.com/url1 sejam tratados por um tipo de servidor e os pedidos para A.com/url2 sejam tratados por um tipo diferente de servidor. É ... não é geralmente o caso de o servidor lidar com um único recurso pode fazer garantias de segurança sobre todos os recursos nesse domínio.

está bem. Vamos fazer um acordo. Vamos criar um novo cabeçalho do CORS que permite ao servidor indicar exatamente os recursos pelos quais ele pode falar, para que os pedidos de pré-voo adicionais para esses URLs possam ser evitados.

Boa ideia! Na verdade, o cabeçalho Access-Control-Policy-Path foi proposto para este propósito. Em última análise, porém, foi deixado de fora do Especificação, aparentemente porque alguns servidores implementaram incorrectamente a especificação URI de tal forma que os pedidos de caminhos que pareciam seguros para o navegador não seriam de facto seguros nos servidores quebrados.

Esta foi uma decisão prudente que priorizou a segurança sobre o desempenho, permitindo que os navegadores implementassem imediatamente a especificação do CORS sem colocar os servidores existentes em risco? Ou era míope condenar a internet à largura de banda desperdiçada e duplicar latência apenas para acomodar bugs em um servidor em particular em um momento específico?

As opiniões divergem.

bem, pelo menos os navegadores vão guardar o pré-voo para um único URL?

Sim. Mas provavelmente não por muito tempo. Nos navegadores WebKit,o tempo máximo de cache pré-voo é de momento 10 minutos .

suspiro. Bem, se eu souber que os meus servidores estão cientes do CORS, e por isso não preciso da protecção oferecida pelo pedidos pré-voo, posso evitá-los?

A sua única opção real é certificar-se de que cumpre os requisitos para pedidos "simples". Isso pode significar deixar de fora cabeçalhos personalizados que você de outra forma incluiria (como X-Requested-With), mentir sobre o Content-Type, ou mais.

Faça o que fizer, deve certificar - se de que tem as protecções adequadas da CSRF em vigor, uma vez que a especificação do CORS não aborda a rejeição de pedidos" simples", incluindo a inseguro POST. tal como a especificação diz: "os recursos para os quais os pedidos simples têm significado para além da recuperação devem proteger-se da falsificação de pedidos através do sítio".

 81
Author: Kevin Christopher Henry, 2018-06-20 05:34:20

Considere o mundo dos pedidos de cross-domain antes do CORS. Você pode fazer um POST de formulário padrão, ou usar um script ou uma marca image para emitir um pedido de obtenção. Você não poderia fazer qualquer outro tipo de pedido além de GET/POST, e você não poderia emitir quaisquer cabeçalhos personalizados nestes pedidos.

Com o advento do CORS, os autores das especificações foram confrontados com o desafio de introduzir um novo mecanismo transversal sem quebrar a semântica existente da web. Eles escolheram fazer isso dando servidores uma forma de opt-in para qualquer novo tipo de pedido. Este opt-in é o pedido de pré-voo.

Por isso, os pedidos de obtenção/publicação sem quaisquer cabeçalhos personalizados não precisam de um pré-voo, uma vez que estes pedidos já eram possíveis antes do CORS. Mas qualquer pedido com cabeçalhos personalizados, ou pedidos PUT/DELETE, do precisa de um pré-voo, uma vez que estes são novos para o CORS spec. Se o servidor não sabe nada sobre o CORS, ele irá responder sem quaisquer cabeçalhos específicos do CORS, e o pedido real não será feito.

Sem o pedido de pré-voo, os servidores poderiam começar a ver pedidos inesperados de navegadores. Isso poderia levar a uma questão de segurança se os servidores não estivessem preparados para este tipo de Pedidos. O PRELIGHT do CORS permite que os pedidos cross-domain sejam introduzidos na web de forma segura.

 45
Author: monsur, 2013-03-13 16:34:30

O CORS permite-lhe indicar mais cabeçalhos e tipos de métodos do que anteriormente era possível com origem cruzada {[[0]} ou <form action>.

Alguns servidores poderiam ter sido (pouco) protegidos com a suposição de que um navegador não pode fazer, por exemplo, pedido de origem cruzada DELETE ou pedido de origem cruzada com o cabeçalho X-Requested-With, por isso esses pedidos são "de confiança".

Para ter a certeza que o servidor suporta realmente o CORS e não apenas responde a pedidos aleatórios, o pré-voo é executado.

 28
Author: Kornel, 2013-03-13 11:43:08
Aqui está outra forma de olhar para ele, usando o código:
<!-- hypothetical exploit on evil.com -->
<!-- Targeting banking-website.example.com, which authenticates with a cookie -->
<script>
jQuery.ajax({
  method: "POST",
  url: "https://banking-website.example.com",
  data: JSON.stringify({
    sendMoneyTo: "Dr Evil",
    amount: 1000000
  }),
  contentType: "application/json",
  dataType: "json"
});
</script>
([[4]] Pre-Coors, a tentativa de exploração acima falharia porque viola a mesma política de origem. Uma API projetada desta forma não precisava de proteção XSRF, porque estava protegida pelo modelo de segurança nativo do navegador. Era impossível para um navegador pré-CORS gerar um post JSON de origem cruzada. Agora, o CORS aparece no local-se não fosse necessário optar pelo CORS antes do voo, de repente este local teria um uma enorme vulnerabilidade, sem culpa própria. Para explicar porque é que alguns pedidos são autorizados a saltar o pré-voo, isto é respondido pelo spec:

Um simples pedido de origem cruzada foi definido como congruente com aqueles que podem ser gerados por agentes de utilizadores actualmente implantados que não em conformidade com esta especificação.

Para desvendar isso, GET não é pré-iluminado porque é um "método simples", como definido por 7.1.5. (Os cabeçalhos devem também ser "simples", a fim de evitar o pré-voo). A justificação para isso é que o pedido de obtenção de origem cruzada "simples" já poderia ser realizado por exemplo <script src=""> (é assim que o JSONP funciona). Uma vez que qualquer elemento com um atributo src pode desencadear uma origem cruzada obter, sem pré-voo, não haveria nenhum benefício de segurança para exigir pré-luta em XHRs "simples".

 12
Author: Dylan Tack, 2016-05-05 01:01:58
Acho que as outras respostas não se concentram na razão pela qual o pré-combate aumenta a segurança.

Cenários:

1) com pré-voo . Um atacante forja um pedido do site dummy-forums.com enquanto o utilizador é autenticado safe-bank.com
Se o servidor não verificar a origem, e de alguma forma tiver uma falha, o navegador emitirá um pedido de pré-voo, método de opção. O servidor não conhece nenhum desses CORS que o navegador está esperando como resposta o navegador não irá prosseguir (nenhum dano de qualquer forma)

2) sem pré-voo . Um atacante forja o pedido sob o mesmo cenário que acima, o navegador irá emitir o POST ou colocar o pedido imediatamente, o servidor aceita-o e pode processá-lo, isso irá potencialmente causar algum dano.

Se o atacante envia um pedido directamente, origem cruzada, de alguma máquina Aleatória, é mais provável que esteja a pensar num pedido com No autenticação. É um pedido falso, mas não um xsrf. então o servidor tem Vai verificar as credenciais e falhar. CORS não tenta impedir um atacante que tem as credenciais para emitir pedidos, embora um whitelist poderia ajudar a reduzir este vetor de ataque.

O mecanismo de pré-voo aumenta a segurança e a coerência entre os clientes e os servidores. Não sei se vale a pena o aperto de mão extra para cada pedido, uma vez que caching é resistente usar-able lá, mas é assim que funciona.
 9
Author: Hirako, 2016-08-14 11:07:28

Adicionalmente, para os métodos de pedido HTTP que podem causar efeitos secundários em dados do usuário (em particular, para métodos HTTP que não o GET, ou para POST utilização com certos tipos MIME), a especificação determina que: navegadores "preflight" o pedido

Origem

 3
Author: Oliver Weichhold, 2013-03-13 12:28:12

Os pedidos pré-iluminados não são sobreDesempenho ? Com os pedidos pré-iluminados um cliente pode saber rapidamente se a operação é permitida antes de enviar uma grande quantidade de dados, por exemplo, em JSON com o método de PUT. Ou antes de viajar dados sensíveis em cabeçalhos de autenticação sobre o fio.

O fato de PUT, DELETE e outros métodos, além de cabeçalhos personalizados, não são permitidos por padrão(eles precisam de permissão explícita com" Access-Control-Request-Methods " e "Access-Control-Request-Headers"), que soa exatamente como uma verificação dupla, porque essas operações poderiam ter mais implicações para os dados do usuário, em vez de obter pedidos. Então, parece:

"Eu vi que você permite pedidos cruzados de http://foo.exemplo , mas tens a certeza que vais permitir apagar pedidos? Você considerou os impactos que esses pedidos podem causar nos dados do Usuário?"

Eu não entendia a correlação citada entre os pré-iluminados. os pedidos e os antigos servidores beneficiam. Um serviço Web que foi implementado antes do CORS, ou sem uma conscientização do CORS, NUNCA receberá nenhum pedido cross-site, porque primeiro a sua resposta não terá o cabeçalho "Access-Control-Allow-Origin".
 1
Author: Nipo, 2015-05-02 20:38:57

Em um browser que suporta o CORS, leitura pedidos (como CHEGAR) já estão protegidos pela mesma origem: Um site mal-intencionado tentando fazer um autenticado cruz-solicitação de domínio (por exemplo, para a vítima de internet do site do banco ou do router interface de configuração) não será capaz de ler os dados retornados porque o banco ou o roteador não definir o Access-Control-Allow-Origin cabeçalho.

No entanto, com escrita pedidos (como POST) o dano é feito quando o pedido chega ao servidor web.* Um servidor web poderia verificar o cabeçalho Origin para determinar se o pedido é legítimo, mas esta verificação muitas vezes não é implementada porque ou o servidor web não tem necessidade de CORS ou o servidor web é mais velho do que o CORS e, portanto, está assumindo que as postagens cross-domain são completamente proibidas pela Política de mesma origem.

É por isso que é dada aos webservers a oportunidade de optarem por receber pedidos de escrita de domínio cruzado.

* essencialmente o AJAX version of CSRF.

 1
Author: AndreKR, 2017-11-03 20:18:09