Eu bani strings de consulta
(chrismorgan.info)- Chris Morgan decidiu bloquear completamente strings de consulta não autorizadas em seu site, e a implementação atual está no Caddyfile
- Ele não quer que parâmetros de rastreamento como
?ref=example.comsejam anexados às URLs, e considera que, se necessário, basta olhar o cabeçalho Referer - Ele considera que UTM parameters como
?utm_source=example&utm_*&c.*são para uso do proprietário do site, e não para serem anexados por terceiros - Atualmente o site não usa strings de consulta de forma alguma, e, se passar a usar no futuro, pretende permitir apenas parâmetros conhecidos
- A URL final escolhida foi
/no-query-strings, e/%3Fnão foi adotada por causa de problemas com a reescritatry_filesdo Caddy
Bloqueio de strings de consulta não autorizadas
- Chris Morgan decidiu bloquear completamente strings de consulta não autorizadas em seu site
- Ele não quer que parâmetros de rastreamento como
?ref=example.comsejam anexados às suas URLs, e considera que, se necessário, basta olhar o cabeçalhoReferer - Ele considera que UTM parameters como
?utm_source=example&utm_*&c.*são para uso do proprietário do site, e não para serem anexados por terceiros - Atualmente este site não usa strings de consulta de forma alguma, e, se passar a usar no futuro, pretende permitir apenas parâmetros conhecidos
- No passado, ele usava URLs de invalidação de cache como
?t=…e?h=…na URL da folha de estilo, mas concluiu que tudo bem se esse tipo de requisição quebrar - Esse bloqueio está atualmente implementado no Caddyfile
Processo de escolha da URL
-
Plano de usar
/?- No início, a tentação de publicar esta página em
https://chrismorgan.info/?era grande - Por ser a forma de caminho vazio e consulta vazia, ela quebraria várias suposições comuns porém equivocadas e poderia colocar algumas ferramentas em dificuldade
- O
curlparecia remover indevidamente o ponto de interrogação final na linha de comando, e ele não testou o uso por bibliotecas - No fim, decidiu respeitar o conceito de caminho e ser mais generoso com as pessoas, especialmente porque já considerava estar forçando o Caddy em direções desconfortáveis o suficiente
- No início, a tentação de publicar esta página em
-
Plano de usar
/%3F- O plano seguinte era publicar em
/%3F, onde o caminho seria?e não haveria consulta - Porém, havia um problema no Caddy que o impedia de lidar com isso quando a reescrita
try_filesestava envolvida - A issue relacionada é
try_filesquebra caminhos contendo caracteres como?e%
- O plano seguinte era publicar em
-
Escolha final
- A URL final foi definida como
/no-query-strings /?ou/%3Ftalvez ainda venham a ser usados depois para algum outro propósito relacionado a strings de consulta
- A URL final foi definida como
1 comentários
Comentários do Hacker News
Fiquei curioso com isso e fui reler os padrões W3C de HTML e URL; para minha surpresa, o formato de query string não tem uma definição específica além de percent-encoding
Dá para confundir query string com query string “form-urlencoded”[0], mas isso é apenas um dos formatos interoperáveis. Em geral, query string é uma string arbitrária com percent-encoding[1] que vem depois do
?na URL, e é mais uma propriedade do objetoURLdo HTML que pode ser usada para gerar a respostaO objeto
URLSearchParamsé o resultado de analisar a query string com um parser form-urlencoded, mas isso é só uma camada de interoperabilidade para JavaScriptSinceramente, antes de olhar o padrão eu estava pronto para discordar, mas o padrão é bem claro. Responder com 404 a uma query string inesperada também pode ser apropriado. A query string faz parte da API de URL tanto quanto o caminho, e a maioria concordaria que acrescentar uma string arbitrária ao caminho não é uma boa ideia e é um comportamento indefinido
[0]: https://url.spec.whatwg.org/#application/x-www-form-urlencod...
[1]: https://url.spec.whatwg.org/#url-class
index.phpe fazerem todo o roteamento pela query stringClaro, era no formato form-urlencoded, as pessoas também não eram bárbaras. Então apareciam URLs como
index.php?p=home,index.php?p=shopouindex.php?action=showthread&forum=42&thread=17976. Numa estrutura dessas, fica imediatamente óbvio que 404 é a resposta certa para parâmetros de query desconhecidosNa prática, muitos sites ainda funcionam assim, só que escondidos atrás de algumas regras de reescrita do Apache/nginx por causa de SEO
No fim, URL é só uma string que o servidor decide como processar
O mais engraçado nessa discussão é se preocupar com os efeitos colaterais de responder com 404 enquanto se esquece completamente por quanto tempo os caminhos foram sem sentido na história da web. Agora o caminho venceu. Quase ninguém mais começa do zero com URLs tipo
/item?id=…. Que bom!A leitura é “corrija a requisição e tente de novo”, e é assim que eu uso nas APIs que ofereço. Prefiro isso a 406 porque não é um problema que eu não consiga processar. Se alguém tentou quebrar a coisa acrescentando algo na query string ou não montou a requisição como manda a documentação, a responsabilidade é de quem fez a requisição
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/...
Por exemplo, do ponto de vista de cache,
url?a=b&c=dpode ser considerado equivalente aurl?c=d&a=bHá muitas convenções que nunca foram documentadas como padrão formal, mas que quebram um monte de coisa se você não seguir, e também há muitos “padrões” que, se levados ao pé da letra, fazem você parecer bobo
No caso do texto original, quem quebra é só quem está tentando visitar aquele site, e provavelmente a pessoa vai apertar voltar no navegador e seguir a vida. Cabe ao autor decidir se aceita esse nível de dano. Só que o fato de algum padrão não proibir algo não significa que isso seja permitido por definição, e o contrário também vale: se o padrão proíbe, isso não se torna automaticamente inadmissível
Pelo que entendi, o autor parece irritado porque outros sites colocam uma query string como
?ref=origin.comnos links para o site deleNão entendo que benefício isso traz para o site de origem nem que prejuízo causa ao site do autor
Os dois lados desse comportamento me parecem completamente confusos
Quando se roda uma campanha de anúncios, entendo que o Google queira anexar query strings UTM para rastrear de qual campanha o usuário veio. Aí há uma relação de cooperação entre origem e destino. Mas aqui a origem está acrescentando algo sem motivo aparente. Por quê?
refque um tráfego considerável está vindo dexyz.come pode pensar em anunciar lá ou fazer alguma parceriaSinceramente, isso é bem útil para sites de nicho/startups. Já estive dos dois lados de conversas iniciadas por esse tipo de dado em analytics: uma vez eu entrei em contato ao ver o tráfego de referência, em outra um site para o qual eu havia linkado entrou em contato comigo. Nas duas situações terminou em parcerias benéficas para ambos
Entendo até certo ponto a discussão sobre privacidade, mas isso não fornece mais informação do que o cabeçalho padrão
Referer. Só fica muito mais visível se você usa ferramentas de analytics como Simple Analytics ou PlausibleAcrescentar query string é algo frequentemente usado para rastreamento. Só o fato de existirem recursos como “copy clean link” do Firefox ou a Enhanced Tracking Protection, que remove preventivamente alguns parâmetros UTM, já mostra que muita gente não quer isso
Alguns sites participam de bom grado do sistema que eu chamaria casualmente de “economia do rastreamento”, porque o destinatário pode ver nos logs que muita gente veio daquele site e agir de uma forma que beneficie esse site
Rejeitar query strings é um protesto simples contra esse sistema
Pela descrição, “um pequeno console web descentralizado, auto-hospedado, que permite aos visitantes explorar sites e páginas interessantes recomendados por uma comunidade de operadores de sites pessoais independentes”, antigamente isso era chamado de Webring. Só que não era tão pomposo
Um dos problemas que tive ao desenvolver um framework de aplicações open source foi que hospedagens usando FastCGI não respeitavam o cabeçalho
Auth, então eu era forçado a passar o token pela query. Era péssimo, porque ao copiar e colar o endereço da web o token frequentemente ia junto. Talvez isso já tenha sido corrigido hojeEm backends sob meu controle e que não precisam ser públicos para todo mundo, eu uso cabeçalhos
Auth?Fiquei curioso se você pode explicar melhor essa parte. Tecnicamente, parece que você está dizendo que o registro
PARAMnão entregava o valor esperadoEle disse: “Então neste site decidi tentar uma proibição abrangente: nada de query strings não aprovadas”, mas o site dele aparentemente retorna 414 quando a requisição inclui query string, e acho que essa foi uma escolha errada
Se esse protesto é para defender o usuário, por que punir justamente o usuário, que em princípio não tinha controle sobre aquela string?
Não seria melhor usar isso como um sinal para mostrar ao usuário como ele mesmo pode tomar essa decisão, por exemplo com ferramentas do navegador?
400 Bad Request, um código genérico de erro do cliente, correto, mas sem graça
402 Payment Required, sinceramente eu estaria aberto a aceitar pagamento para fazer uma determinada URL com query string funcionar
404 Not Found, mas isso gera efeitos colaterais com muita facilidade e não transmite a sensação de ‘o formato da requisição está errado’ que eu quero
303 See Other sem cabeçalho
Location. Hoje é extremamente raro, mas é legítimo. Pelo menos no RFC 2616 era (“The different URI SHOULD be given by the Location field in the response”). Mas no 7231 e no 9110 isso mudou para uma formulação que pressupõe a presença do cabeçalhoLocation(“… as indicated by a URI in the Location header field”). Já 301, 302, 307 e 308 dizem que “the server SHOULD generate a Location header field”. De qualquer forma, ainda considero um See Other sem cabeçalhoLocationperfeitamente aceitável. Mas URI Too Long era mais engraçado”https://chrismorgan.info/no-query-strings?foo
Quando ele diz “Você pode alegar que estou abusando de 414 URI Too Long. Minha resposta é: assim fica mais engraçado. As outras opções que considerei…” dá para considerar outra opção: 418 I'm a teapot. Bules normalmente também não suportam query strings
Há várias opções que parecem adequadas, mas olhando de perto não são: 406 “Not Acceptable” é baseada em cabeçalhos de negociação de conteúdo; 409 “Conflict” é em grande parte voltada a requisições WebDAV; 411, 422 e 431 também são para condições específicas que não têm relação com isso
Erros da faixa 300 ou 500 também são inadequados. Isso não é realocação nem falha do lado do servidor, e sim problema na requisição do cliente
O bule ou o URI longo demais parecem os melhores candidatos
Pelo tom deste texto e do texto do Chris, parece que incluir esses parâmetros de query é algo prejudicial, mas eu não entendo como exatamente isso prejudica
Entendo que pode quebrar algumas URLs, e só isso já é motivo suficiente para não fazer. Ainda assim parece um incômodo pequeno. Alguém pode explicar?
Pela ótica do purismo técnico, modificar uma URL é tecnicamente incorreto, mesmo que por convenção isso seja aceito. URL deve ser tratada basicamente como um valor opaco
Pela ótica social, é rastreamento, e as threads irmãs de comentários já explicam bem isso, então não vou repetir
Pela ótica do ruído, isso contribui para esconder aquilo com que o usuário deveria se importar e torna a URL tão difícil e complexa que pessoas comuns deixam de prestar atenção nela
Refererajuda a entender por que as pessoas não gostam disso: https://en.wikipedia.org/wiki/HTTP_refererHá muitos motivos para você não querer que um site saiba onde você estava antes de chegar até ele. Na prática, é compartilhar seu histórico de navegação com o site que você está visitando
Por isso o cabeçalho HTTP
Refererrecebeu muitas atualizações, incluindo restrições sobre quando ele é enviado e recursos para desativá-lo completamenteAcrescentar a mesma informação como parâmetro de URL contorna essas regras existentes e os mecanismos de recusa. Basta usar o padrão
É uma postura absurdamente extrema, e não explica direito como isso levaria a uma web melhor
O segundo ponto pode ser mais difícil de entender, mas no meu caso eu nunca quero que meus logs tenham informações que possam prejudicar os usuários
Pessoalmente, odeio quando vou copiar um link para mandar por mensagem e ele vem com um código de rastreamento duas vezes maior que a URL original. Aí eu tenho que apagar tudo manualmente ou deixar a pessoa que recebeu se perguntando o que são aqueles caracteres aleatórios ocupando a tela inteira
Isso viola a privacidade do usuário, piora a experiência de uso e, acima de tudo, ninguém pediu por isso
Como a fonte original ainda não tinha sido discutida no HN, coloquei esse link (https://chrismorgan.info/no-query-strings) no topo e movi o link para o texto-resposta (https://susam.net/no-query-strings.html) para a descrição superior
Os dois são bons, mas me parece justo dar prioridade ao original
Por aqui, a maioria dos sites que ainda usa queries GET é operada por governos locais, em sites de arrecadação de impostos, e eles vão passando variáveis de um lado para o outro depois do login
Na verdade, me irrita muito mais um parser de roteamento que faz exatamente a mesma coisa que uma requisição GET, mas finge ser uma URL de verdade
Query strings são úteis. É o caso de busca de arquivos ou outros tipos de arquivos dinâmicos, mas não deveriam ser anexadas a URLs que não esperam query strings
Por isso acho correto rejeitar requisições com coisas como UTM anexadas
Se a query string não era esperada mas está presente, 404 parece a resposta mais sensata, e 400 também pode ser apropriado