RFC7231 4장과 9장에서는 요청 메서드(request methods) 구분을 설명합니다.
GET 메서드는 참조에만 사용한다.
GET 메서드는 부작용이 발생하지 않음을 기대한다.
중요 정보를 전송할 때는 POST 메서드를 사용한다.
GET은 요청을 해도 원본 데이터의 변화를 가져오지 않아야 합니다. 반면 POST는 요청을 통해 데이터 CRUD가 이뤄질 수 있습니다. 이와 같이 원본 데이터의 변화를 부작용(취득 이외의 행위)라고 할 수 있습니다. GET 메서드는 URL을 통해 질의 문자열로 데이터가 전달됩니다. 브라우저 및 서버는 최대 URL 길이 제한이 있기 때문에 큰 데이터는 GET을 통해 전달할 수 없습니다.(RFC2616, RFC1738, RFC3986에서는 URL 길이 제한이 없습니다만 브라우저마다 제한이 있습니다.)
간단히 예를 들어보겠습니다.
https://example.com/login?id=abc&content=longlonglonglonglonglong...
GET 메소드를 통해 사용자가 올린 글을 업로드할 때 특정 길이 이상을 전송하지 못할 것입니다. 또한 위와같이 GET은 요청 내용이 URL에 노출되므로 중요한 데이터를 담으면 심각한 보안 문제를 야기할 수 있습니다.
URL에 이렇게 민감한 정보가 담기게 되면 상상할 수 있는 시나리오는 다양합니다. 가장 눈에 띄는 문제는 URL 자체가 보안되지 않았다는 점, 두번재는 URL에 저장된 데이터가 접근 로그에 남는 점, 세번째는 Referrer을 통해 외부에 유출될수 있다는 점, 네번째는 사용자가 매개변수가 포함된 URL을 소셜 서비스 등으로 공유할 수 있습니다.
이 중에서 Referrer은 다양한 방법으로 웹에서 수집됩니다. Google Analytics만 봐도 Direct, Social, Email, Organic 등 사용자가 어떤 곳에서 해당 사이트로 방문이 이뤄졌는지 추적합니다. 추적 자체는 Google Analytics를 사용하지 않는 사이트에서도 Referrer 획득은 쉽습니다. 바로 document.referrer을 통해서 얻을 수 있습니다.
브라우저 개발자 도구 -> 콘솔에서 document.referrer을 입력하면 어떤 링크를 통해 현재 위치에 오게 됐는지 확인할 수 있습니다. 만약 아무것도 안뜬다면 direct로 진입된 것이라 할 수 있고, 구글이나 네이버 등으로 들어왔다면 검색 엔진의 주소가 나타날 것입니다. 그런데 이전 사이트가 개인정보를 담고있는 URL을 가지고 있었다면 Referrer 추적이 이뤄지는 사이트로 이동시 해당 사이트 로그에 URL을 저장시켜주게 됩니다.
그렇기 때문에 아래 중 한가지의 사안이라도 걸리는 경우 GET보다 POST를 사용하는게 적합합니다.
데이터 생성, 변경 등 원본 파일의 수정이 발생하는 경우
중요한 정보를 전달할 때
전송 데이터의 양이 많을 때
POST는 전송 길이에 제한이 없고, body에 데이터를 담아 전달하므로 기본적인 보안이 이뤄집니다. 그렇다면 POST로 전송되는 데이터는 보안에 안전할까요?
POST로 전달되는 데이터도 URL에 노출만 안될 뿐 똑같이 쉽게 확인할 수 있습니다. 개발자 도구만 켜서 Network 탭에서 클릭해보면 body 데이터를 확인할 수 있기 때문입니다. 그렇기 때문에 POST로 전달할 때 많은 데이터들이 암호화된 상태로 전송됩니다.
몇몇의 사이트들은 암호화를 일부만 적용하고 있지만 페이스북을 들어가서 POST 요청의 body를 살펴보면 알아볼 수 없도록 암호화된 내용만 전달됩니다. 이렇게 암호화된 데이터는 클라이언트 사이드에서 decrypt해줍니다. 반대로 서버로 전달할 때도 클라이언트 사이드에서 encrypt한 후 보내면 POST 로그를 통해 데이터가 누출되는 일을 막을 수 있습니다.