Impede a divulgação da resposta por meio do seqüestro de JSON.
Em teoria, o conteúdo das respostas HTTP é protegido pela mesma diretiva de origem: as páginas de um domínio não podem obter nenhuma informação de páginas do outro domínio (a menos que seja explicitamente permitido).
Um invasor pode solicitar páginas em outros domínios em seu nome, por exemplo, usando uma tag <script src=...>
ou <img>
, mas não pode obter nenhuma informação sobre o resultado (cabeçalhos, conteúdo).
Portanto, se você visitar a página de um invasor, ele não poderá ler seu email no gmail.com.
Exceto que, ao usar uma tag de script para solicitar conteúdo JSON, o JSON é executado como Javascript no ambiente controlado de um invasor. Se o atacante puder substituir o construtor Array ou Object ou algum outro método usado durante a construção do objeto, qualquer coisa no JSON passará pelo código do invasor e será divulgada.
Observe que isso acontece no momento em que o JSON é executado como Javascript, não no momento em que é analisado.
Existem várias contramedidas:
Garantindo que o JSON nunca execute
Ao colocar uma while(1);
declaração antes dos dados JSON, o Google garante que os dados JSON nunca sejam executados como Javascript.
Somente uma página legítima poderia obter todo o conteúdo, remover while(1);
e analisar o restante como JSON.
Coisas como for(;;);
foram vistas no Facebook, por exemplo, com os mesmos resultados.
Certificando-se de que o JSON não é Javascript válido
Da mesma forma, adicionar tokens inválidos antes do JSON, como &&&START&&&
, garante que ele nunca seja executado.
Sempre retorne JSON com um objeto do lado de fora
Essa é a OWASP
maneira recomendada de proteger contra o seqüestro de JSON e é a menos invasiva.
Semelhante às contramedidas anteriores, garante que o JSON nunca seja executado como Javascript.
Um objeto JSON válido, quando não está incluído em nada, não é válido em Javascript:
eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :
No entanto, isto é JSON válido:
JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}
Portanto, sempre retorne um Objeto no nível superior da resposta para garantir que o JSON não seja Javascript válido, enquanto ainda é JSON válido.
Conforme observado por @hvd nos comentários, o objeto vazio {}
é Javascript válido, e saber que o objeto está vazio pode ser uma informação valiosa.
Comparação dos métodos acima
A maneira OWASP é menos invasiva, pois não precisa de alterações na biblioteca do cliente e transfere JSON válido. No entanto, não é certo se os erros anteriores ou futuros do navegador podem anular isso. Como observado por @oriadam, não está claro se os dados podem ter vazado em um erro de análise através de um tratamento de erros ou não (por exemplo, window.onerror).
A maneira do Google exige que a biblioteca do cliente suporte a desserialização automática e pode ser considerada mais segura em relação aos bugs do navegador.
Ambos os métodos exigem alterações no servidor para evitar que os desenvolvedores enviem acidentalmente JSON vulnerável.