Ao comparar um HTTP GET com um HTTP POST, quais são as diferenças de uma perspectiva de segurança? Uma das opções é inerentemente mais segura que a outra? Se sim, por quê?
Sei que o POST não expõe informações na URL, mas há algum valor real nisso ou é apenas segurança através da obscuridade? Existe alguma razão para eu preferir o POST quando a segurança é uma preocupação?
Editar: em
HTTPS, os dados do POST são codificados, mas os URLs podem ser detectados por terceiros? Além disso, estou lidando com JSP; ao usar JSP ou uma estrutura semelhante, seria justo dizer que a melhor prática é evitar colocar dados confidenciais no POST ou GET completamente e usar o código do lado do servidor para manipular informações confidenciais?
Respostas:
Quanto à segurança, eles são inerentemente iguais. Embora seja verdade que o POST não expõe informações via URL, ele expõe tantas informações quanto um GET na comunicação de rede real entre o cliente e o servidor. Se você precisar passar informações confidenciais, sua primeira linha de defesa seria passá-las usando HTTP Seguro.
As postagens GET ou string de consulta são realmente boas para as informações necessárias para marcar um item em particular ou para ajudar na otimização do mecanismo de pesquisa e na indexação de itens.
O POST é adequado para formulários padrão usados para enviar dados únicos. Eu não usaria GET para postar formulários reais, a menos que talvez em um formulário de pesquisa em que você queira permitir que o usuário salve a consulta em um marcador ou algo nesse sentido.
fonte
A solicitação GET é marginalmente menos segura que a solicitação POST. Nenhum dos dois oferece "segurança" verdadeira por si só; o uso de solicitações POST não tornará magicamente seu site seguro contra ataques maliciosos em uma quantidade perceptível. No entanto, o uso de solicitações GET pode tornar um aplicativo seguro caso contrário.
O mantra que você "não deve usar solicitações GET para fazer alterações" ainda é muito válido, mas isso tem pouco a ver com códigos maliciosos comportamento . Os formulários de login são os mais sensíveis a serem enviados usando o tipo de solicitação errado.
Aranhas de pesquisa e aceleradores da Web
Essa é a verdadeira razão pela qual você deve usar solicitações POST para alterar dados. As aranhas de busca seguirão todos os links do seu site, mas não enviarão formulários aleatórios que encontrarem.
Os aceleradores da Web são piores que os spiders de pesquisa, porque são executados na máquina do cliente e "clicam" em todos os links no contexto do usuário conectado . Assim, um aplicativo que usa uma solicitação GET para excluir itens, mesmo que exija um administrador, obedecerá com satisfação às ordens do acelerador da web (não malicioso!) E excluirá tudo o que vê .
Vice-ataque confuso
Um ataque de deputado confuso (em que o deputado é o navegador) é possível, independentemente de você usar uma solicitação GET ou POST .
Em sites controlados por invasores, GET e POST são igualmente fáceis de enviar sem a interação do usuário .
O único cenário em que o POST é um pouco menos suscetível é que muitos sites que não estão sob o controle do invasor (por exemplo, um fórum de terceiros) permitem incorporar imagens arbitrárias (permitindo que o invasor injete uma solicitação GET arbitrária), mas evitam todas maneiras de injetar uma solicitação POST arbitrária, seja automática ou manual.
Pode-se argumentar que os aceleradores da Web são um exemplo de ataque confuso, mas isso é apenas uma questão de definição. De qualquer forma, um invasor mal-intencionado não tem controle sobre isso; portanto, dificilmente é um ataque , mesmo que o deputado seja confuso.
Logs de proxy
É provável que os servidores proxy registrem URLs GET na sua totalidade, sem retirar a string de consulta. Os parâmetros de solicitação POST normalmente não são registrados. É improvável que os cookies sejam registrados nos dois casos. (exemplo)
Este é um argumento muito fraco a favor do POST. Em primeiro lugar, o tráfego não criptografado pode ser totalmente registrado; um proxy malicioso já tem tudo o que precisa. Em segundo lugar, os parâmetros de solicitação são de uso limitado para um invasor: o que eles realmente precisam são os cookies; portanto, se a única coisa que eles têm são logs de proxy, é improvável que eles consigam atacar um URL GET ou POST.
Há uma exceção para solicitações de login: elas tendem a conter a senha do usuário. Salvar isso no log do proxy abre um vetor de ataque ausente no caso do POST. No entanto, o login através de HTTP simples é inerentemente inseguro de qualquer maneira.
Cache de proxy
Os proxies de armazenamento em cache podem reter respostas GET, mas não respostas POST. Dito isto, as respostas GET podem ser tornadas não armazenáveis em cache com menos esforço do que converter a URL em um manipulador POST.
"Referenciador" HTTP
Se o usuário navegar para um site de terceiros a partir da página veiculada em resposta a uma solicitação GET, esse site de terceiros verá todos os parâmetros da solicitação GET.
Pertence à categoria "revela parâmetros de solicitação a terceiros", cuja gravidade depende do que está presente nesses parâmetros. As solicitações POST são naturalmente imunes a isso, no entanto, para explorar a solicitação GET, um hacker precisaria inserir um link para seu próprio site na resposta do servidor.
Histórico do navegador
Isso é muito semelhante ao argumento "logs de proxy": as solicitações GET são armazenadas no histórico do navegador, juntamente com seus parâmetros. O invasor pode obtê-los facilmente se tiver acesso físico à máquina.
Ação de atualização do navegador
O navegador tentará novamente uma solicitação GET assim que o usuário clicar em "atualizar". Isso pode ser feito ao restaurar as guias após o desligamento. Qualquer ação (por exemplo, um pagamento) será repetida sem aviso prévio.
O navegador não tentará novamente uma solicitação POST sem um aviso.
Esse é um bom motivo para usar apenas solicitações POST para alterar dados, mas não tem nada a ver com comportamento malicioso e, portanto, com segurança.
Então, o que eu deveria fazer?
Não, eles não podem ser cheirados. Mas os URLs serão armazenados no histórico do navegador.
Depende de quão sensível é, ou mais especificamente, de que maneira. Obviamente, o cliente verá. Qualquer pessoa com acesso físico ao computador do cliente o verá. O cliente pode falsificá-lo ao enviá-lo de volta para você. Se isso for importante, mantenha os dados confidenciais no servidor e não deixe que eles saiam.
fonte
<body onload="document.getElementById('a').submit()"><form id="a" action="http://example.com/delete.php" action="post"><input type="hidden" name="id" value="12"></form>
não é realmente difícil de enviar um post em algum lugar automaticamente, clicando em um link (que contém o html)Você não tem maior segurança fornecida porque as variáveis são enviadas por HTTP POST do que pelas variáveis enviadas por HTTP GET.
O HTTP / 1.1 nos fornece vários métodos para enviar uma solicitação :
Vamos supor que você tenha o seguinte documento HTML usando GET:
O que o seu navegador pergunta? Ele pergunta o seguinte:
Agora vamos fingir que alteramos esse método de solicitação para um POST:
Ambas as solicitações HTTP são:
Muitos navegadores não suportam métodos HTTP que não sejam POST / GET.
Muitos navegadores comportamentos de armazenam o endereço da página, mas isso não significa que você possa ignorar qualquer um desses outros problemas.
Para ser específico:
Isso está correto, porque o software que você está usando para falar HTTP tende a armazenar as variáveis de solicitação com um método, mas outro não apenas impede que alguém olhe para o histórico do navegador ou algum outro ataque ingênuo de uma criança de 10 anos que pensa entender o h4x0r1ng , ou scripts que verificam seu repositório de histórico. Se você tem um script que pode verificar seu histórico, você pode facilmente ter um que verifique o tráfego da sua rede, de modo que toda essa segurança através da obscuridade está fornecendo obscuridade apenas para crianças de script e namoradas ciumentas.
Veja como o SSL funciona. Lembra dos dois pedidos que enviei acima? Aqui está a aparência deles no SSL: (alterei a página para https://encrypted.google.com/, como o example.com não responde no SSL).
POST sobre SSL
GET sobre SSL
(nota: eu converti o HEX para ASCII, alguns deles obviamente não devem ser exibidos)
Toda a conversa HTTP é criptografada, a única parte visível da comunicação está na camada TCP / IP (ou seja, o endereço IP e as informações da porta de conexão).
Então deixe-me fazer uma grande declaração ousada aqui. Seu site não oferece maior segurança sobre um método HTTP do que outro, hackers e jornalistas de todo o mundo sabem exatamente como fazer o que acabei de demonstrar aqui. Se você deseja segurança, use SSL. Navegadores tendem a armazenar histórico, é recomendado pelo RFC2616 9.1.1 NÃO usar GET para executar uma ação, mas pensar que o POST fornece segurança é totalmente errado.
A única coisa que o POST é uma medida de segurança? Proteção contra seu ex ciumento, folheando o histórico do navegador. É isso aí. O resto do mundo está conectado à sua conta rindo de você.
Para demonstrar ainda mais por que o POST não é seguro, o Facebook usa solicitações POST em todo o lugar, então como podem existir softwares como o FireSheep ?
Observe que você pode ser atacado com CSRF, mesmo que use HTTPS e seu site não contenha vulnerabilidades XSS . Em resumo, esse cenário de ataque supõe que a vítima (o usuário do seu site ou serviço) já esteja logada e tenha um cookie adequado e, em seguida, o navegador da vítima seja solicitado a fazer algo com o site (supostamente seguro). Se você não tiver proteção contra o CSRF, o invasor ainda poderá executar ações com as credenciais das vítimas. O atacante não pode ver a resposta do servidor porque ela será transferida para o navegador da vítima, mas o dano já está feito nesse momento.
fonte
+1
.Não há segurança adicional.
Os dados de postagem não aparecem no histórico e / ou nos arquivos de log, mas se os dados devem ser mantidos em segurança, você precisa de SSL.
Caso contrário, qualquer pessoa que cheire o fio pode ler seus dados de qualquer maneira.
fonte
Mesmo que
POST
não ofereça nenhum benefício real de segurançaGET
, para formulários de login ou qualquer outro formulário com informações relativamente confidenciais, verifique se você está usandoPOST
como:POST
ed não serão salvas no histórico do usuário.GET
, elas serão visíveis no histórico e na barra de URL).Além disso,
GET
possui um limite teórico de dados.POST
não.Para informações confidenciais reais, use
SSL
(HTTPS
)fonte
Nenhum GET e POST é inerentemente "mais seguro" que o outro, assim como nenhum fax e telefone é "mais seguro" que o outro. Os vários métodos HTTP são fornecidos para que você possa escolher o que for mais adequado ao problema que está tentando resolver. GET é mais apropriado para idempotente consultas enquanto o POST é mais adequado para consultas de "ação", mas você pode se dar bem com qualquer uma delas, se não entender a arquitetura de segurança do aplicativo que está mantendo.
Provavelmente, é melhor se você ler o Capítulo 9: Definições de método da RFC HTTP / 1.1 para obter uma idéia geral do que GET e POST foram originalmente previstos ou médios.
fonte
A diferença entre GET e POST não deve ser vista em termos de segurança, mas em suas intenções em relação ao servidor. O GET nunca deve alterar dados no servidor - pelo menos, exceto nos logs -, mas o POST pode criar novos recursos.
Os proxies agradáveis não armazenam em cache os dados do POST, mas podem armazenar em cache os dados GET da URL, portanto, você pode dizer que o POST deve ser mais seguro. Mas os dados do POST ainda estariam disponíveis para proxies que não funcionam bem.
Como mencionado em muitas das respostas, a única aposta segura é via SSL.
Mas verifique se os métodos GET não confirmam alterações, como excluir linhas do banco de dados, etc.
fonte
Minha metodologia usual para escolher é algo como:
fonte
Isso não está relacionado à segurança, mas ... os navegadores não armazenam em cache as solicitações POST .
fonte
Nenhum deles confere segurança magicamente a uma solicitação, no entanto, GET implica alguns efeitos colaterais que geralmente impedem que ela seja segura.
Os URLs GET aparecem no histórico do navegador e nos logs do servidor da web. Por esse motivo, eles nunca devem ser usados para itens como formulários de login e números de cartão de crédito.
No entanto, apenas postar esses dados também não os torna seguros. Para isso você quer SSL. GET e POST enviam dados em texto sem formatação pela conexão quando usados por HTTP.
Também existem outros bons motivos para os dados do POST - como a capacidade de enviar quantidades ilimitadas de dados ou ocultar parâmetros de usuários casuais.
A desvantagem é que os usuários não podem marcar os resultados de uma consulta enviada via POST. Para isso, você precisa de GET.
fonte
Considere esta situação: Uma API desleixada aceita solicitações GET como:
Em algumas configurações, quando você solicita esse URL e se houver um erro / aviso sobre o pedido, toda essa linha é registrada no arquivo de log. Pior ainda: se você esquecer de desativar as mensagens de erro no servidor de produção, essas informações serão exibidas simplesmente no navegador! Agora você acabou de entregar sua chave de API a todos.
Infelizmente, existem APIs reais funcionando dessa maneira.
Eu não gostaria da idéia de ter algumas informações confidenciais nos logs ou exibi-las no navegador. POST e GET não são os mesmos. Use cada um onde for apropriado.
fonte
SEGURANÇA como segurança dos dados EM TRÂNSITO: nenhuma diferença entre POST e GET.
SEGURANÇA como segurança dos dados NO COMPUTADOR: O POST é mais seguro (sem histórico de URL)
fonte
A noção de segurança não tem sentido, a menos que você defina contra o que deseja se proteger.
Se você deseja se proteger contra o histórico armazenado do navegador, alguns tipos de registro e pessoas que olham para seus URLs, o POST é mais seguro.
Se você deseja se proteger contra alguém que cheira sua atividade de rede, não há diferença.
fonte
Muitas pessoas adotam uma convenção (mencionada por Ross) de que solicitações GET apenas recuperam dados e não modificam nenhum dado no servidor, e solicitações POST são usadas para todas as modificações de dados. Enquanto um não é inerentemente mais seguro do que o outro, se fazer seguir essa convenção, você pode aplicar a lógica de segurança transversal (por exemplo, apenas as pessoas com contas pode modificar os dados, os postos de modo não autenticados são rejeitados).
fonte
É mais difícil alterar uma solicitação POST (requer mais esforço do que editar a cadeia de consulta). Edit: Em outras palavras, é apenas segurança pela obscuridade, e apenas isso.
fonte
Não vou repetir todas as outras respostas, mas há um aspecto que ainda não vi mencionado - é a história de dados desaparecendo. Não sei onde encontrá-lo, mas ...
Basicamente, trata-se de um aplicativo da Web que, misteriosamente, todas as noites perde todos os seus dados e ninguém sabe o porquê. Ao inspecionar os logs, mais tarde, foi revelado que o site foi encontrado pelo google ou por outra aranha arbitrária, que obteve (leia: GOT) todos os links encontrados no site, incluindo "excluir esta entrada" e "tem certeza?" links.
Na verdade - parte disso foi mencionada. Esta é a história por trás de "não altere dados no GET, mas apenas no POST". Os rastreadores seguirão felizmente GET, nunca POST. Mesmo o robots.txt não ajuda contra rastreadores que se comportam mal.
fonte
Você também deve estar ciente de que, se seus sites contiverem links para outros sites externos que você não controla usando GET, esses dados serão colocados no cabeçalho do refeerer nos sites externos quando eles pressionarem os links em seu site. Portanto, a transferência de dados de login pelos métodos GET é SEMPRE um grande problema. Uma vez que isso pode expor as credenciais de login para facilitar o acesso, basta verificar os logs ou procurar no Google analytics (ou similar).
fonte
RFC7231:
"Os URIs devem ser compartilhados, não protegidos, mesmo quando identificam recursos seguros. Os URIs geralmente são mostrados nos monitores, adicionados aos modelos quando uma página é impressa e armazenados em uma variedade de listas de favoritos não protegidas. Portanto, não é aconselhável incluir informações em um URI sensíveis, identificáveis pessoalmente ou com risco de divulgação.
Os autores dos serviços devem evitar formulários baseados em GET para o envio de dados confidenciais, porque esses dados serão colocados no destino da solicitação. Muitos servidores, proxies e agentes de usuário existentes registram ou exibem o destino da solicitação em locais onde ele pode estar visível para terceiros. Esses serviços devem usar o envio de formulários baseados em POST ".
Essa RFC indica claramente que dados confidenciais não devem ser enviados usando GET. Devido a essa observação, alguns implementadores podem não manipular os dados obtidos da parte da consulta de uma solicitação GET com o mesmo cuidado. Estou trabalhando em um protocolo que garante a integridade dos dados. De acordo com esta especificação, eu não deveria ter que garantir a integridade dos dados GET (o que farei porque ninguém adere a essas especificações)
fonte
Como anteriormente algumas pessoas disseram, o HTTPS traz segurança.
No entanto, o POST é um pouco mais seguro que o GET, pois o GET pode ser armazenado no histórico.
Mais ainda, infelizmente, às vezes a eleição do POST ou do GET não depende do desenvolvedor. Por exemplo, um hiperlink é sempre enviado por GET (a menos que seja transformado em um formulário de postagem usando javascript).
fonte
GET é visível para qualquer pessoa (mesmo a que está no seu ombro agora) e é salva no cache, portanto, é menos seguro o uso de post, btw post sem alguma rotina criptográfica não é certo; por um pouco de segurança, você deve usar SSL ( https)
fonte
Uma das razões pelas quais o POST é pior para a segurança é que GET é registrado por padrão, parâmetros e todos os dados são quase universalmente registrados pelo seu servidor da web.
O POST é o contrário , quase universalmente não é registrado , levando a atividades de invasor muito difíceis.
Eu não compro o argumento "é grande demais", não há razão para não registrar nada , pelo menos 1 KB, seria um longo caminho para as pessoas identificarem os invasores que trabalham em um ponto de entrada fraco até que ele apareça, e o POST um serviço duplo, permitindo que qualquer porta traseira baseada em HTTP passe silenciosamente quantidades ilimitadas de dados.
fonte
A diferença é que o GET envia dados abertos e POST ocultos (no cabeçalho http).
Portanto, get é melhor para dados não seguros, como cadeias de consulta no Google. Os dados de autenticação nunca serão enviados via GET - portanto, use POST aqui. Claro que o tema todo é um pouco mais complicado. Se você quiser ler mais, leia este artigo (em alemão).
fonte
Recentemente, um ataque foi publicado , que permite ao homem revelar um corpo de solicitações de HTTPS compactado. Como os cabeçalhos e a URL da solicitação não são compactados pelo HTTP, as solicitações GET ficam mais protegidas contra esse ataque específico.
Existem modos em que as solicitações GET também são vulneráveis, o SPDY compacta os cabeçalhos das solicitações, o TLS também fornece uma compactação opcional (raramente usada). Nesses cenários, o ataque é mais fácil de evitar (os fornecedores de navegadores já forneceram correções). A compactação no nível HTTP é um recurso mais fundamental, é improvável que os fornecedores o desabilitem.
É apenas um exemplo que mostra um cenário em que GET é mais seguro que POST, mas não acho que seria uma boa ideia escolher GET sobre POST por esse motivo de ataque. O ataque é bastante sofisticado e requer pré-requisitos não triviais (o Attacker precisa poder controlar parte do conteúdo da solicitação). É melhor desativar a compactação HTTP em cenários onde o ataque seria prejudicial.
fonte
Isenção de responsabilidade: os pontos a seguir são aplicáveis apenas a chamadas de API e não aos URLs do site.
Segurança na rede : você deve usar HTTPS. GET e POST são igualmente seguros neste caso.
Histórico do Navegador : para aplicativos de front-end, como Angular JS, React JS, etc, as chamadas de API são chamadas AJAX feitas pelo front-end. Isso não se torna parte do histórico do navegador. Portanto, POST e GET são igualmente seguros.
Logs do servidor : Com o uso do conjunto de gravação de máscara de dados e do formato de logs de acesso, é possível ocultar todos ou apenas dados confidenciais da URL de solicitação.
Visibilidade dos dados no console do navegador: para alguém com intenções mal-intencionadas, são quase os mesmos esforços para exibir dados POST tanto quanto GET.
Portanto, com práticas corretas de registro em log, a API GET é tão segura quanto a API POST. Seguir o POST em todos os lugares, força definições de API ruins e deve ser evitado.
fonte
A postagem é a mais segura junto com o SSL instalado porque é transmitida no corpo da mensagem.
Mas todos esses métodos são inseguros porque o protocolo de 7 bits que ele usa embaixo dele é passível de hackers com escape. Mesmo através de um firewall de aplicativo da web nível 4.
Soquetes também não são garantia ... Embora seja mais seguro de certas maneiras.
fonte
Este é um post antigo, mas eu gostaria de contestar algumas das respostas. Se estiver transferindo dados confidenciais, convém usar SSL. Se você usar SSL com um parâmetro GET (por exemplo,? Userid = 123), esses dados serão enviados em texto sem formatação! Se você enviar usando um POST, os valores serão colocados no corpo criptografado da mensagem e, portanto, não serão legíveis para a maioria dos ataques MITM.
A grande distinção é onde os dados são passados. Só faz sentido que, se os dados forem colocados em uma URL, não puderem ser criptografados, caso contrário você não poderá rotear para o servidor, pois somente você poderá ler a URL. É assim que um GET funciona.
Em resumo, você pode transmitir dados com segurança em um POST sobre SSL, mas não pode fazê-lo com um GET, usando SSL ou não.
fonte
Até o POST aceita solicitações GET. Suponha que você tenha um formulário com entradas como user.name e user.passwd, que devem suportar nome de usuário e senha. Se simplesmente adicionarmos? User.name = "meu usuário & user.passwd =" minha senha ", a solicitação será aceita por" ignorando a página de logon ".
Uma solução para isso é implementar filtros (filtros java como e) no lado do servidor e detectar que nenhuma consulta de string seja passada como argumento GET.
fonte