Eita mania de misturar POST com GET

Já repararam que a primeira coisa que 90% dos web frameworks Java faz é botar um Front Controller que não dá a mínima para qual método está sendo usado? Quem mais se incomoda com as implicações de segurança que isso causa?

Só pra dar um exemplo, eu poderia colocar uma imagem com a URL do botão de logout, e só de ver esse post, você seria deslogado.* Incomoda? Um pouco. Poderia tornar inconveniente responder ao meu post, mas não ia causar nenhum dano sério. E esse foi um exemplo bem básico. Agora imagine uma falha dessas num site de comércio eletrônico. “Você não comprou um Personal Abdomen Strength Booster 3000? Eu tenho o pedido aqui no meu log com o seu IP!”

Ok, você pode criar uma chave para cada requisição para fechar essa brecha, mas essa solução cria seus próprios problemas. (por exemplo, quebrar o back button) Eu gostaria de ver um framework que permitisse que eu especificasse via anotação quais métodos são válidos caso a caso. (dá pra fazer algo nesse estilo criando regras de segurança que bloqueiem GETs para certos URL patterns, mas isso já é um workaround, vulgo gambi)

  • Crianças, não façam isso em casa! Nós somos profissionais altamente treinados e tomamos todas as precauções de segurança necessárias.

Frameworks que seguem o modelo REST permitem configurar resources e os metodos que eles suportam, inclusive usando anotacoes. Em relacao ao problema do logout é preciso muito cuidado com codigo html malicioso fornecido pelo usuario.

Eu acho que o acanalhamento já começa quando as pessoas vêem esses tutoriais de Servlets onde o “autor” demonstra que sobrescrever o método service() é uma boa idéia, nessa hora a pobre vítima do tutorial já começa a achar que os métodos do HTTP são todos uma coisa só e que ele não precisa entender a diferença entre eles.

Mas sabe o que é o pior?

Quando os formulários de busca são feitos com POST, acho que essa é uma das piores cagadas que um site que ignora os métodos do HTTP pode fazer.

Fala cara, gostei do seu ‘rant’ porque você levanta umas questões interessantes…

O meu forte não é frameworks web então gostaria de ver o que o resto do pessoal tem a dizer!

isso me incomoda bastante tambem de nao diferenciar GET e POST.
o vraptor eh um framework como os 90% que vc citou e nao diferencia isso por default. a gente aqui na caelum chegou a fazer um plugin pro vraptor que permitia configurar o metodo http por logica.

agora a verdade é que nem o POST está a salvo de problemas de seguranca como esse que voce falou de colocar url em uma imagem. da mto bem pra fazer uma pg html que invoca um POST pra outro site e o problema continua. é que com GET é muito mais facil disso acontecer pq povo pode postar no orkut/forum/email/etc uma “imagem” com a url (e no orkut nao da pra postar html pra fazer post).

a solucao tosca e preguicosa eh sempre verificar o referrer antes de aceitar algo que cause efeitos colaterais graves. mas nem isso eh 100% garantido.

a melhor solucao de todas eh mesmo os famosos tokens por request q, como vc falou, dao um trabalho do inferno e ninguem faz. quer dizer, quase ninguem - gmail, delicious, wordpress e muitos outros fazem isso. o rails tem suporte a isso por exemplo.

Pelo menos pra mim é fundamental a diferença entre POST e GET para qualquer aplicação web.

Alguns frameworks, principalmente os component-based, ignoram essa funcionalidade básica.

No Mentawai se a sua action herda de BaseAction, ela pode usar o método isPost().

Se ela não herda (é um POJO) vc pode injetar um boolean através do filtro PostOrGetFilter.

Eu uso bastante o método para diferenciar uma action. Se for POST o cara está submetendo o formulário. Se for GET ele está querendo exibi-lo.

Muito interessante isso. Como se escapa desse problema? Não acho legal ter que forçar o logout a ser um post, até porque ele é um link. Dá para fazer um href ser um post? Sei que dá para construir um form pra isso, mas é meio pentelho ter que fazer isso para todo link que vc quer transformar em post. Há outra solução que nao seja essa ou desabilitar o tag de imagem no forum por exemplo?

a unica solucao certa é fazer o token de requisicao mesmo. o problema eh q da um trabalhao isso.
desabilitar imagem nao resolve pq teria q desabilitar imagem de tudo quanto eh coisa! (email/forum/orkut…)

verificar o referrer resolve quando o seu proprio site nao aceita postagens dentro dele. no guj por exemplo nao funcionaria verificar o referrer pq poderiamos postar uma img na nossa assinatura por exemplo e ela teria referrer do proprio guj.

PS. aos desavisados de plantao: dá pra zuar o guj com o q estamos discutindo aqui? sim. quem tentar brincar dessas coisas por aqui vai ser banido pela moderacao.

Realmente. Paginação com POST também, outro crime contra o HTTP.

[quote=Sergio Lopes]isso me incomoda bastante tambem de nao diferenciar GET e POST.
o vraptor eh um framework como os 90% que vc citou e nao diferencia isso por default. a gente aqui na caelum chegou a fazer um plugin pro vraptor que permitia configurar o metodo http por logica.

agora a verdade é que nem o POST está a salvo de problemas de seguranca como esse que voce falou de colocar url em uma imagem. da mto bem pra fazer uma pg html que invoca um POST pra outro site e o problema continua. é que com GET é muito mais facil disso acontecer pq povo pode postar no orkut/forum/email/etc uma “imagem” com a url (e no orkut nao da pra postar html pra fazer post).[/quote]
É, o problema do GET é que é muito fácil subverter. Uma imagem, um frame escondido, e pronto. A vítima nem fica sabendo o que aconteceu. Aliás, o que motivou esse rant foi justamente que eu comecei a estudar o vRaptor pra fazer um site de bookmarks, e vi que se não tomasse esse cuidado ia deixar meus futuros usuários expostos. Já pensou se logar um dia e descobrir que seus bookmarks foram todos apagados, e pior ainda, seu perfil público só tem link pra sites de remedinho? :slight_smile:

Eu ainda planejo usar o vRaptor – vocês tomaram várias das decisões que eu tomaria se fosse escrever um do zero – mas que eu gostaria de já ter uma annotation @PostOnly, não posso negar. Esse negócio de open source deixa a gente mal acostumado. :wink:

Já ajuda. Na verdade, se você tem acesso ao request, pode chamar getMethod, mas acho que fica parecendo uma coisa tão baixo nível que ninguém faz.

Boa aula, Sergio.

O token de requisição funciona como uma session id. Então eu só vou aceitar requisições daquela session id, ou seja, o cara só poderia zoar ele mesmo. É isso?

O referer nunca resolve, porque uma imagem postada terá o referrer do site, certo? Só se o cara postasse a imagem num site externo. É isso?

[quote=saoj]Boa aula, Sergio.

O token de requisição funciona como uma session id. Então eu só vou aceitar requisições daquela session id, ou seja, o cara só poderia zoar ele mesmo. É isso?[/quote]

A única coisa a adicionar é que o token é re-gerado a cada requisição, então com isso você também resolve o famigerado problema do double-click.

Implementar seguranca é dificil, ao inves de fazer de novo frameworks deveriam confiar na solucao que existe na camada de transferencia (HTTP). O problema é que estes frameworks dito ‘pra web’ acham legal serem MVC_Compliant e incorrem no erro daqueles que ignoram a rede na iteracao entre componentes. Enquanto nao reconhecem o erro precisam contar com a boa indole dos usuarios.

[quote=cmoscoso]Implementar seguranca é dificil, ao inves de fazer de novo frameworks deveriam confiar na solucao que existe na camada de transferencia (HTTP).
[/quote]

Acho que vc não entendeu. Não existe solucao na camada http para isso.

[quote=rubinelli][quote=saoj]Boa aula, Sergio.

O token de requisição funciona como uma session id. Então eu só vou aceitar requisições daquela session id, ou seja, o cara só poderia zoar ele mesmo. É isso?[/quote]

A única coisa a adicionar é que o token é re-gerado a cada requisição, então com isso você também resolve o famigerado problema do double-click.[/quote]

Ao custo do botao de voltar? HTTP nos ensina que GET, PUT e DELETE sao idempotentes portanto double-click nao sao um problema nestes casos.

[quote=saoj][quote=cmoscoso]Implementar seguranca é dificil, ao inves de fazer de novo frameworks deveriam confiar na solucao que existe na camada de transferencia (HTTP).
[/quote]

Acho que vc não entendeu. Não existe solucao na camada http para isso.[/quote]

Bom, em relacao ao problema levantado pelo Sergio (cross-site request forgery) vc tem razao, estava me refrindo a questoes mais essenciais levantadas pelo autor do topico.

isso, como o carlos falou, o nome tecnico da brincadeira é CSRF (cross-site request forgery).

saoj, a solucao eh mesmo gerar um token por request (por isso eh chato de fazer). e de brinde vc ganha solucao por duplo clique.

o wordpress eu acho q tem uma solucao bem bacana pra isso. se vc for dar um delete num post la, ele passa o token e o delete eh bem sucedido. mas se vc nao passar o token, ao inves de dar um erro, ele mostra uma tela de confirmacao (vc tem certeza de q quer apagar?). isso mata totalmente possibilidade de CSRF sem matar usabilidade.

rubinelli, sobre sua critica do @Post no vrapto. é mto facil implementar um interceptor que faca isso pra vc (de limitar ao metodo POST apenas)