AJAX / SOSP / CORS / CSRF

(Ou 4 siglas, 16 letras e uma dor de cabeça)

Agenda

Mostrar como aplicações web ricas se comportam quando o conteúdo está vindo de uma fonte que não a fonte original.

A Idéia

Gerar uma view com conteúdo que será inserido em outro site; o conteúdo deverá abrir um modal para pedir mais dados para o usuário.

Passo 1: O Conteúdo

Carregado por AJAX, com jQuery. Fácil.


$(function() {
    $("#div-especial").load("http://outrosite.com/conteudo.html");
});
					

Problema 1: SOSP (Same Origin Security Policy)

Same Origin Security Policy é assegurado pelo browser, barrando requisições vindas de lugares que não são o lugar original.

"Lugar original" = URL requisitada tem mesmo esquema (http vs https), mesmo domínio (subdomínios não contam), mesma porta (ou implício 80) da URL que está fazendo a requisição.

Página em http://outrosite.com/conteudo.html pede:

  • http://outrosite.com/dados.json ⇒ OK
  • http://outrosite.com/dir/dados.json ⇒ OK
  • http://usuário:senha@outrosite.com/dir/dados.json ⇒ OK
  • http://outrosite.com:8080/dados.json ⇒ NOT!
  • https://outrosite.com/dados.json ⇒ NOT!
  • http://api.outrosite.com/dados.json ⇒ NOT!
  • http://outrosite.com:80/dados.json ⇒ talvez...

Apenas lembrando: isso é forçado pelo browser, não pelo serviço.

Outras aplicações podem passar por cima do Same Origin se quiserem.

Restrições de subdomínios podem ser relaxadas se scripts forem carregados de subdomínios diferentes:

Se a página em http://outrosite.com/ carregar um script de http://api.outrosite.com, a restrição de subdomínios pode ser removida para funções do script.

Se não tiver como relaxar as restrições, utiliza-se CORS.

Problema 2: CORS (Cross-Origin Resource Sharing)

CORS é implementado no servidor e diz se o serviço pode ou não utilizar aquele recurso.

Browser rodando em http://outrosite.com requisita serviço em http://api.outrosite.com/.

Para isso, envia o header Origin.


Origin: http://outrosite.com
						

Servidor olha o header, verifica se a URL tem permissão para acessar os recursos, é retornado o header Access-Control-Allow-Origin.


Access-Control-Allow-Origin: http://outrosite.com
						

De novo, isso é controlado pelo browser; um browser que não siga corretamente o controle de acesso ou um aplicativo qualquer poderiam passar por cima dessa restrição e continuar lendo o conteúdo.

Django-CORS-Headers

App para configurar CORS sozinho.


CORS_ORIGIN_WHITELIST = (
   'outrosite.com',
)
						

ou


CORS_ORIGIN_REGEX_WHITELIST = (
    '^(https?://)?(\w+\.)?outrosite\.com$', 
)
						

Agora o site externo consegue carregar o conteúdo das views.