Articlesusam.net·2026년 5월 9일·0

I Will Not Add Query Strings to Your URLs - Susam Pal

Quick Summary

Susam Pal은 Wander Console에 넣었던 via= 추천 출처 쿼리 문자열 기능이 URL을 깨뜨리고 웹의 referrer 통제와 사용자 의도를 우회한다는 이유로 제거했으며, 앞으로는 다른 사람의 URL을 그대로 로드하겠다고 결론낸다.

I Will Not Add Query Strings to Your URLs - Susam Pal 관련 대표 이미지

🖼️ 인포그래픽

I Will Not Add Query Strings to Your URLs - Susam Pal 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

I Will Not Add Query Strings to Your URLs - Susam Pal 내용을 설명하는 본문 이미지

💡 한 줄 요약

Susam Pal은 Wander Console에 넣었던 via= 추천 출처 쿼리 문자열 기능이 URL을 깨뜨리고 웹의 referrer 통제와 사용자 의도를 우회한다는 이유로 제거했으며, 앞으로는 다른 사람의 URL을 그대로 로드하겠다고 결론낸다.

📌 핵심 요약

  • 글은 Chris Morgan의 ‘쿼리 문자열 금지’ 취지의 글을 계기로, 저자가 자신의 프로젝트 Wander Console에 추가했던 referral query string 기능을 되돌아보는 흐름으로 전개된다.
  • Wander Console은 개인 웹사이트들이 서로 추천 페이지를 공유하도록 만든 분산형·자가호스팅 웹 콘솔이며, 한때 방문 URL에 via= 쿼리 파라미터를 붙여 어느 콘솔에서 유입됐는지 알 수 있게 했다.
  • 저자는 처음부터 이 기능에 확신이 없었지만, 기능 요청과 피로한 상태, 연구 일정에 쫓기는 상황 속에서 충분히 숙고하지 못한 채 기본 활성화 기능으로 구현했다.
  • 실제로 어떤 웹사이트는 쿼리 문자열을 자체 리소스 선택에 사용하고 있었기 때문에, 임의의 via= 값을 붙이자 정상 URL이 HTTP 404로 깨지는 문제가 발생했다.
  • 저자는 URL을 바꾸면 더 이상 같은 URL이 아니며, referrer 정보는 이미 HTTP Referer 헤더와 Referrer-Policy로 다뤄지는 영역이므로 도구가 임의로 목적지 URL에 추적성 정보를 삽입해서는 안 된다고 결론짓는다.

🧩 주요 포인트

  1. 글은 Chris Morgan의 ‘쿼리 문자열 금지’ 취지의 글을 계기로, 저자가 자신의 프로젝트 Wander Console에 추가했던 referral query string 기능을 되돌아보는 흐름으로 전개된다.
  2. Wander Console은 개인 웹사이트들이 서로 추천 페이지를 공유하도록 만든 분산형·자가호스팅 웹 콘솔이며, 한때 방문 URL에 via= 쿼리 파라미터를 붙여 어느 콘솔에서 유입됐는지 알 수 있게 했다.
  3. 저자는 처음부터 이 기능에 확신이 없었지만, 기능 요청과 피로한 상태, 연구 일정에 쫓기는 상황 속에서 충분히 숙고하지 못한 채 기본 활성화 기능으로 구현했다.
  4. 실제로 어떤 웹사이트는 쿼리 문자열을 자체 리소스 선택에 사용하고 있었기 때문에, 임의의 via= 값을 붙이자 정상 URL이 HTTP 404로 깨지는 문제가 발생했다.
  5. 저자는 URL을 바꾸면 더 이상 같은 URL이 아니며, referrer 정보는 이미 HTTP Referer 헤더와 Referrer-Policy로 다뤄지는 영역이므로 도구가 임의로 목적지 URL에 추적성 정보를 삽입해서는 안 된다고 결론짓는다.

🧠 상세 정리

1. Chris Morgan의 글이 던진 계기

글은 저자가 전날 피드 리더에서 Chris Morgan의 글을 읽고 강하게 공감했다는 이야기로 시작한다. 저자는 Chris의 웹 관련 의견과 댓글을 약 5년 동안 읽어 왔고, 과거 자신이 공유한 CSS 보일러플레이트에 대해 받은 상세한 피드백도 기억하고 있다. 본업은 C와 C++ 중심의 시스템 프로그래밍이지만, 웹사이트와 작은 HTML 도구를 만드는 일은 오래된 취미였다고 설명한다. 그래서 유행하는 관행을 무심코 따라 하기 쉬운 취미 학습자에게 Chris의 지적은 웹을 더 올바르게 다루는 기준을 제공해 주었다.

2. 취미 웹 개발자로서 배운 기준

저자는 자신의 웹 개발 지식이 정규적인 교육보다는 다른 사람들의 웹사이트 소스를 살펴보고, 필요한 기능이 생길 때 MDN 문서를 찾아 구현하는 방식으로 쌓였다고 말한다. 이런 방식은 실용적이지만, 동시에 그때그때 유행하는 방식이나 충분히 검증되지 않은 습관도 함께 받아들일 위험이 있다. Chris의 과거 피드백은 그런 위험을 줄여 주는 역할을 했고, 특히 링크 밑줄을 유지하고 방문한 링크를 보라색으로 남겨 두라는 교훈이 오래 남았다고 한다. 이 배경은 이후 저자가 URL을 임의로 바꾸는 기능을 왜 다시 판단하게 됐는지를 설명하는 토대가 된다.

3. Wander Console의 목적과 구조

저자는 몇 달 전 Wander Console이라는 프로젝트를 만들었다고 소개한다. 이 도구는 개인 웹사이트 운영자들이 추천하는 흥미로운 웹페이지를 방문자가 탐색할 수 있게 해 주는 작고 분산된 자가호스팅 웹 콘솔이다. 구현은 콘솔을 담당하는 HTML 파일 하나와, 이웃 콘솔 및 추천 페이지 목록을 정의하는 JavaScript 파일 하나로 구성된다. 웹서버에 두 파일을 복사하기만 하면 동작하며, 별도 서버 사이드 로직 없이 Codeberg Pages나 GitHub Pages 같은 제한적인 환경에서도 운영할 수 있다는 점이 특징이다.

4. 분산형 추천 네트워크로서의 작동 방식

Wander Console에서 사용자가 ‘Wander’ 버튼을 누르면, 콘솔은 다른 원격 콘솔들에 접속해 추천 웹페이지 목록을 가져오고 그중 하나를 무작위로 선택해 브라우저에 로드한다. 저자는 이를 사라진 StumbleUpon과 약간 비슷하지만 완전히 분산된 방식이라고 설명한다. 또 웹링과도 닮았지만, 네트워크가 반드시 순환 구조일 필요 없이 어떤 형태의 그래프도 될 수 있다는 점에서 다르다고 말한다. 현재 이 도구를 호스팅하는 웹사이트는 50곳이 넘고, 함께 추천하는 페이지는 1500개가 넘는다고 제시한다.

5. via= 쿼리 파라미터라는 미심쩍은 기능

문제의 핵심은 Wander Console 0.4.0에서 추가한 via= 쿼리 파라미터 지원이다. 예를 들어 사용자가 저자의 콘솔에서 midnight.pub 같은 페이지를 만나면, 콘솔은 목적지 URL 뒤에 via=https://susam.net/wander/ 같은 값을 붙여 로드했다. 이 기능의 의도는 추천된 웹사이트 운영자가 접근 로그를 통해 방문이 Wander Console에서 왔다는 사실을 알 수 있게 하는 것이었다. 그러나 Chris Morgan의 글은 이런 식으로 URL에 추적성 정보를 덧붙이는 관행을 비판했고, 저자도 본래 이 기능에 확신이 없었다고 고백한다.

6. 충분히 생각하지 못한 구현 결정

저자는 이 기능 요청을 처음 봤을 때부터 좋은 기능인지 확신하지 못했지만, 당시 대수적 그래프 이론 연구와 마감에 쫓겨 깊이 생각할 여유가 없었다고 설명한다. Wander Console 자체도 연구 중 짧은 휴식 시간에 만든 프로젝트였고, 첫 버전은 피곤한 새벽에 약 한 시간 반 만에 만들어졌다고 한다. 평소에는 작은 취미 프로젝트의 범위를 제한하고, 필수 요건을 만족하면 기능 완성 상태로 두는 방식을 선호하지만 이번에는 피로와 압박 속에서 예외가 생겼다. 그는 결국 자신의 직감이 좋지 않다고 말하고 있었음에도 이유를 명확히 설명하지 못해 기능을 구현했고, 기본 비활성화가 아니라 opt-out 설정으로 둔 것도 실수였다고 평가한다.

7. URL을 조금 바꾸는 것만으로도 리소스가 달라진다

기능을 넣은 뒤 저자의 직감이 맞았다는 사실이 곧 드러났다. 그가 좋아하는 한 웹사이트의 페이지가 Wander Console 안에서 로드되지 않았는데, 원인은 그 사이트가 쿼리 문자열을 여러 글꼴 컬렉션 중 무엇을 보여 줄지 결정하는 식별자로 사용하고 있었기 때문이다. 따라서 임의로 via= 값을 추가하자 사이트는 그것을 글꼴 컬렉션 식별자로 해석했고, 결과적으로 HTTP 404 오류가 발생했다. 저자는 이 경험을 통해 URL을 수정하면 그것은 더 이상 같은 URL이 아니며, 아주 사소해 보이는 쿼리 문자열 추가만으로도 전혀 다른 리소스나 존재하지 않는 리소스를 가리킬 수 있다고 정리한다.

8. Referer와 Referrer-Policy를 우회하지 말아야 한다는 결론

저자는 웹 브라우저에는 이미 유입 정보를 다루기 위한 HTTP Referer 헤더와 Referrer-Policy라는 표준 메커니즘이 있다고 지적한다. 이 정책은 서버, 문서, 개별 링크 수준에서 설정할 수 있고, 어느 정도의 referrer 정보를 보낼지 의도적으로 제어하게 해 준다. 그런데 URL에 referral query string을 붙이면 이런 통제 장치를 우회해, 개인정보와 출처 표시의 문제를 목적지 URL 자체에 박아 넣게 된다. 저자는 HTML 도구가 사용자를 대신해 주어진 URL을 바꾸어 referral 정보를 삽입하는 것은 옳지 않다고 판단했고, Wander Console에서 해당 기능을 완전히 제거했다.

9. 기능 제거와 앞으로의 원칙

저자는 이 기능을 opt-in으로 남겨 둘 수도 있었지만, 일단 잘못된 기능이라고 판단한 뒤에는 자신의 소프트웨어 안에 어떤 형태로도 남기고 싶지 않았다고 말한다. Wander Console은 아직 0.x 릴리스 단계였기 때문에 기능을 제거하기에 좋은 시점이기도 했다. 다만 연구 일정 때문에 미루고 있었는데, Chris Morgan의 글이 마지막 계기가 되어 시간을 내어 제거 작업을 진행했다. 그 결과 최신 0.6.0 릴리스에는 해당 기능이 더 이상 없으며, 저자는 앞으로 URL을 로드해야 한다면 웹사이트 작성자가 의도한 그대로 로드하고 절대 쿼리 문자열을 덧붙이지 않겠다고 다짐한다.

🧾 핵심 주장 / 시사점

  • URL은 단순한 문자열이 아니라 리소스를 식별하는 계약이므로, 도구가 선의로 붙인 작은 파라미터도 목적지의 의미를 바꾸거나 접근을 깨뜨릴 수 있다.
  • 출처 정보와 추적성은 목적지 URL에 임의로 삽입하기보다, 브라우저와 웹 표준이 제공하는 Referer 및 Referrer-Policy의 통제 안에서 다뤄져야 한다.
  • 확신이 없는 기능은 기본 활성화로 넣기보다 구현하지 않거나 최소한 opt-in으로 다뤄야 하며, 작은 취미 프로젝트일수록 기능 범위를 지키는 판단이 중요하다.

✅ 액션 아이템

  • Wander Console에서 via= 출처 쿼리 문자열을 기본 비활성화하고, 다른 콘솔의 원본 URL은 변경 없이 그대로 로드하도록 동작한다.
  • URL이 바뀌면 같은 링크가 아니게 되므로 방문 경로 보존 원칙을 정의하고, 임의 파라미터 주입으로 경로가 변형되지 않도록 제한한다.
  • referrer 관련 처리는 HTTP Referer 헤더와 Referrer-Policy에 맡기고, 도구가 목적지 URL에 추적성 정보를 추가해 의도를 우회하지 않게 정한다.

❓ 열린 질문

  • via= 없이 유입 출처를 추적하려면 어떤 대체 신호를 수집해 보존할 것인지, 그리고 누가 기준을 정할 것인가?
  • 어떤 웹사이트의 자원 선택 규칙이 쿼리 문자열 의존적이라서 via= 추가 시 HTTP 404를 유발하는지, 사전 점검 범위를 어디까지 둘 것인가?
  • 목적지 URL을 변경하지 않는 원칙을 유지할 때도 추적 요구가 생기면 어떤 기준으로 기능 범위를 축소하거나 포기할 것인가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.