HTTP URL Redirection(30x)과 Authorization Header

Development / HTTP

HTTP 서버에서 301(Moved permanently), 302(Found), 303(See other), 307(Temporary redirect), 308(Permanent redirect) 응답 코드를 통해 클라이언트에게 Redirect를 지시하는 경우, 본래의 request의 Header에 존재하던 Authorization 항목이, 새로이 redirect된 request에는 사라지게 되는 문제가 발생하였다. 일반적으로 301, 302, 303은 그 특성에 따라 request의 method가 변경될 수도 있는 등, 본래의 request의 변조가 일어날 수 있다고 치더라도, 307, 308의 경우에는 그 특성이 원 request를 redirect된 서버에 그대로 재현하는 것이기 때문에 헤더가 조작되는 것은 도무지 이해할 수 없는 일이었다.1 2 3

더불어, 웹 개발에서 유용하게 사용되는 도구인 Postman에서는 위의 현상이 전혀 일어나지 않는데, (발견된 바로는) iOS 내부에 구현된 Web Client인 WKWebView나, 특정 Web Client 구현체(가령 Python Requests)에서만 문제가 발생해서, 개발 및 테스트 환경에서는 이 문제를 전혀 발견하지 못하고 있다가, 실제 배포 환경에서만 문제가 나타나는 등 매우 짜증..이 솟구치는 상황이 발생하고 말았다. 문제가 발생하면 일단 남 부터 의심하게 되는 안좋은 습관이 발동하여 이 놈들이 RFC 표준도 안지키고 웹 클라이언트를 만들었단 말이야? 부들부들.. 하는 상태까지 이르렀다.

하지만 '컴퓨터는 거짓말을 하지 않는다. 언제나 잘못은 나에게 있다.'는 진리(?)에 의거하여 해당 이슈를 적당히 구글링 해보니, CVE-2014-1829 취약점이라는 것이 있어서, 모던한(?) 웹 클라이언트에서는 다른 host로 redirected request시에 자동으로 Authorization 헤더를 제거하고 요청을 보내는 것이 맞다고 한다. 세상에! 누가 이걸 알았겠는가! 허허. (생각해보니 target host가 다른데, 당연히 이랬어야 했던거구나.. 싶기도 하고. 허허허.)

여튼, 해결책으로는 클라이언트 내부에서 30x를 받았을 때, 리다이렉트를 지시 받은 location을 믿을 수 있는 host인지 검증하고, Authorization 헤더를 다시 재정립 해준 뒤 리퀘스트를 보내는 방법과, (보안 정책에는 위배되겠지만)HTTPS와 세상을 믿고 토큰을 query string으로 던져주는 방법을 사용할 수 있을 듯 하다. 참고로 나는 NGINX Reserse Proxy를 통해 이 문제를 해결했다.

Share on : Twitter, Facebook or Google+