RFC 10008: 새로운 HTTP QUERY 메서드
요약
새로운 HTTP QUERY 메서드(RFC 10008) 도입에 대한 기술적 논쟁을 다룹니다. 요청 본문을 포함하는 QUERY 메서드의 캐싱 문제, 보안 취약점, 그리고 기존 GET/POST 방식과의 차이점 및 실무적 효용성을 분석합니다.
핵심 포인트
- QUERY 메서드는 멱등성을 보장하여 폼 재제출 경고를 방지할 수 있음
- 요청 본문을 캐시 키로 사용할 때 발생하는 보안 및 캐시 무효화 문제 제기
- GET에 본문을 붙이는 방식 대신 별도 메서드를 만든 IETF의 결정 배경
- 데이터베이스 MCP 서버 등 특정 도구 개발 시 안전 계층 분리에 유용할 가능성
강한 동기 부여 예시가 있었다면 설득력이 더 컸을 텐데, 너무 쉽게 GET으로 표현할 수 있는 예시를 써서 오히려 산만해짐
큰 JSON 필터 구조나 이미지 입력을 요청 본문으로 넣는 QUERY를 상상해도, 요청 본문이 캐시 키의 일부가 된다는 건 매우 이상하게 느껴짐. 사용자 제어의 무한한 캐시 키가 생기고, 일반적인 캐싱 전략은 사실상 요청 본문을 비트 단위로 비교하거나 해시하는 것뿐이라 악의적 상황에서는 캐시 무효화가 아주 쉬워짐
복잡한 필터링이나 이미지 같은 복잡한 입력이 필요한 서비스를 만든다면, 캐싱은 HTTP 계층에서 멀리 떨어진 곳에 있을 가능성이 큼. 예를 들어 조인의 개별 데이터 컬럼이나, 디코딩된 이미지 입력의 지각 해시로 키를 잡은 임베딩처럼, 와이어상의 정확한 비트 표현과는 무관할 것임
이런 걸 왜 굳이 범용 방식으로 포착하려는지 모르겠음. 차라리 POST에 "Vary: request-body" 같은 새 헤더로 캐싱 의미론을 표현하는 편이 훨씬 낫다고 봄. 완전한 하위 호환이 되고, 이 동작이 유용할지도 모르는 0.1%의 CDN 용례 외에는 무시해도 됨
GET의 URI에 있는 쿼리 부분도 현실적으로는 거의 제한이 없고 사용자 제어이며, URI의 일부라 캐시 키에도 들어감. 그래서 이 반대가 왜 특별히 제기되는지 잘 모르겠음
브라우저가 더 작은 캐시 키를 원한다면 본문의 충돌 저항 해시를 저장하면 됨. 예를 들어 SHA-256을 쓰면 됨
캐싱 관련 공격 중 쿼리 매개변수에도 똑같이 적용되지 않는 건 딱히 떠오르지 않음. 캐시를 넘치게 만들고 싶다면 고유한 30자 쿼리 매개변수를 만드는 것도 30MB 요청 본문을 만드는 것만큼 쉬움
모든 사용 시나리오가 공개 인터넷인 건 아니고, 공개 인터넷에서 유용하지 않다고 해서 표준화할 수 없는 것도 아님
현실적으로 공개 인터넷용 시스템은 보안 해시를 캐시 키로 써서 항상 같은 크기로 만들 것임. 캐시 키에는 이미 아주 길 수 있는 URL과 임의의 헤더 값 집합도 포함됨
이미지도 요청 본문으로 보낼 수 있지만, 이미 base64 쿼리 매개변수로도 할 수 있음. 마음먹고 이상하게 쓰면 어떤 제안 표준이든 나쁘게 사용할 수 있음
쿼리 매개변수가 있는 GET도 이미 불투명하고 캐시 무효화를 쉽게 만듦
예를 들면 지금 작업 중인 데이터베이스용 MCP 서버를 만들고 있음. ChatGPT에서는 커밋 전에 롤백되는 dry-run POST를 먼저 하고 싶은데, 둘 다 속성 하나만 다른 POST 요청이라 도구의 안전 계층을 자주 건드림. 여러 이유로 정확한 원인을 디버깅하기도 어려움
하지만 QUERY 뒤에 POST를 두면 더 나아질 것 같음. 단순히 안전 플래그가 붙은 같은 요청이 아니라 서로 다른 요청 유형이 되기 때문임
HTML 폼이 QUERY 지원을 추가할지 궁금함
QUERY는 멱등이어야 하므로, POST 폼 제출 결과 페이지를 새로고침할 때 뜨는 성가신 재제출 경고를 피할 수 있음
폼의 이상한 점 하나는, 폼 POST의 결과가 위치(URL)를 가진 페이지이면서도 그 위치로는 로드할 수 없다는 것임. 아는 한 그 페이지가 GET이 아니라 POST라는 사실은 사용자나 JS가 볼 수 있는 곳에 저장되지 않고, 새로고침도 이상하게 동작함 method=QUERY가 추가되면 이런 이상함이 새 변종으로 하나 더 생김
이런 길고 완전한 일반 텍스트 문서는 영원히 좋아할 듯함. 어릴 때 비디오 게임 FAQ를 보던 좋은 시절이 떠오름. 여러 면에서 정말 우월한 정보 형식임
서식이 아름다움. 내부 업무 메모용 스타일 템플릿으로 베껴 써야겠음. 시대를 타지 않음
“GET 요청에 본문을 붙이는 방안은 IETF 작업반에서 깊이 검토됐지만, 결국 새 QUERY 메서드를 만드는 쪽으로 결정됐다. 별도 메서드를 만든 결정은 역사적 상호운용성 문제와 HTTP의 핵심 아키텍처 정의에 대한 엄격한 준수 때문이었다”
그런데 몇 년째 GET 메서드에 요청 본문을 붙여 보내고 있음
HTTP 질의에서 검색 결과를 질의하려면 QUERY 메서드를 쓰고, 쿼리 매개변수는 추가하지 말라는 식이 됨
이름이 헷갈림. query라는 용어가 이미 HTTP 요청 일반을 가리키는 데 쓰이기 때문임
RFC 제목만 봐도 혼란스러웠음
query라는 용어가 HTTP 요청 일반을 가리키는 건 어떤 분야에서 그런가? 구어적으로 GET 요청을 질의라고 부를 때는 있지만, POST, PUT, DELETE에는 절대 그렇게 부르지 않음
맞음. 게다가 꼭 질의일 필요도 없고 멱등 효과일 수도 있음. 차라리 IPOST, 즉 멱등 POST라고 부르는 편이 나았을 듯함
수정: 아, 캐시 가능성을 위해 QUERY를 부작용 없는 “안전한” 메서드로 선언했구나. 착각했음
이게 실제로 쿼리 문자열이 붙은 GET 요청을 야생에서 대체하게 된다면, 브라우저 북마크가 요청 매개변수 보존을 지원하길 정말 바람
아마 그렇지는 않을 듯함. 현재 질의 용도로 POST를 쓰는 곳을 대체할 가능성이 큼
이 RFC의 범위 밖인 건 알지만, 이걸 쉽게 확장하면 JS EventSource가 스트리밍 AI 질의에도 동작하게 만들 수 있다는 점이 좋음
요청에 본문이 필요하다 보니 모두 POST를 쓰고, 스트리밍 결과는 응답에 text/event-stream 프로토콜을 자주 씀. 하지만 실제로 상태가 바뀌는 건 아니라 기술적으로는 잘 맞지 않고, EventSource는 고집스럽게도 GET만 쓸 수 있음. 그래서 많은 API가 자체 파서로 같은 기능을 다시 구현함
GET: Content (body) "no defined semantics"를 보면, GET 메서드에 본문을 허용해도 나쁘지 않겠다고 생각했지만 원래 명세상 GET 본문은 완전히 무시되어야 함
또한 요청의 중요한 부분이 제거된 본문에 들어가면 캐싱도 깨질 수 있음
URI만 있는 GET은 리소스의 현재 표현을 가져온다는 의미론을 가짐. 이것이 하이퍼링크의 가장 기본 형태이고 웹이 동작하는 방식에 꽤 중요함
GET에 본문 매개변수를 추가하면, 같은 URI를 쓰는 두 요청을 같은 것을 가리킨다고 취급할 수 없게 되어 이 메서드의 제약을 깨뜨림
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기