GET 또는 POST가 다른 것보다 더 안전합니까?


282

HTTP GET을 HTTP POST와 비교할 때 보안 관점과 다른 점은 무엇입니까? 선택 중 하나가 본질적으로 다른 것보다 안전합니까? 그렇다면 왜 그렇습니까?

POST가 URL에 정보를 노출 시키지는 않지만 실제 가치가 있습니까? 아니면 모호함을 통한 보안입니까? 보안이 중요 할 때 POST를 선호해야하는 이유가 있습니까?

편집 :
HTTPS를 통해 POST 데이터가 인코딩되지만 타사에서 URL을 스니핑 할 수 있습니까? 또한 JSP를 다루고 있습니다. JSP 또는 이와 유사한 프레임 워크를 사용할 때 가장 좋은 방법은 민감한 데이터를 POST 또는 GET에 배치하지 않고 서버 측 코드를 사용하여 중요한 정보를 대신 처리하는 것입니다.


1
Jeff의 블로그 Coding Horror : Cross-Site Request Forgeries and You 에 관한 멋진 블로그 항목이 있습니다.
fhe

대부분의 경우 POST를 사용하지 않습니까? 예를 들어 API의 경우 DB에서 데이터를 가져와야하지만 서버가 데이터를 반환하기 전에 먼저 인증을 받아야한다고 가정 해보십시오. post를 사용하면 세션 ID와 요청에 필요한 모든 매개 변수를 전달하면됩니다. 이를 위해 GET 요청을 사용한 경우 세션 기록은 브라우저 기록 또는 중간 위치에서 쉽게 찾을 수 있습니다.
James111

https가 널리 보급되지 않은 전쟁 (99 '또는 '00 정도) 이전의이 토론을 기억합니다.
David Tonhofer

@DavidTonhofer, 당신은 어느 전쟁을 말하고 있습니까? 브라우저 전쟁?
DeltaFlyer 1

@DeltaFlyer 아니오, 물건에 대한 영원한 전쟁, 일명 GWOT. 우리는 무엇을 했습니까?
David Tonhofer

답변:


206

보안에 있어서는 본질적으로 동일합니다. POST는 URL을 통해 정보를 공개하지 않지만, 클라이언트와 서버 간의 실제 네트워크 통신에서 GET만큼 많은 정보를 공개합니다. 민감한 정보를 전달해야하는 경우 첫 번째 방어선은 보안 HTTP를 사용하여 전달하는 것입니다.

GET 또는 검색어 문자열 게시물은 특정 항목을 북마크하거나 검색 엔진 최적화 및 색인 생성에 도움이되는 정보에 유용합니다.

POST는 일회성 데이터를 제출하는 데 사용되는 표준 양식에 적합합니다. 검색 양식에서 사용자가 쿼리를 책갈피에 저장하거나 해당 행을 따라 무언가를 저장하려는 경우가 아니라면 실제 양식을 게시하는 데 GET을 사용하지 않습니다.


5
경고를 받으면 위치 표시 줄에 표시된 URL이 POST에 숨겨 질 데이터를 노출시킬 수 있습니다.
tvanfosson

93
그것은 단지 가장 순진 의미에서 숨겨진
davetron5000

7
하지만 비밀번호를 입력 할 때 누군가 어깨 너머로보고있을 수 있기 때문에 키보드가 안전하지 않다고 말할 수도 있습니다. 모호함을 통한 보안과 보안이 전혀 없음에는 거의 차이가 없습니다.
stephenbayer

65
URL 및 주소 상자에서 쿼리 문자열의 가시성 (및 캐싱)의 보안 수준 이 명확 하지 않습니다. 절대 보안과 같은 것은 없으므로 보안 수준이 관련됩니다.
pbreitenbach

6
게시물을 사용하면 노출됩니다. 귀하의 경우 게시물이 약간 더 안전합니다. 그러나 진지하게 .. 변수를 얻는 것처럼 쉽게 하루 종일 포스트 변수를 변경할 수 있습니다. 쿠키를보고 수정할 수도 있습니다. 사이트의 정보가 어떤 형태 나 형태로든 전송되는 정보에 의존하지 마십시오. 필요한 보안이 많을수록 더 많은 검증 방법을 갖추어야합니다.
stephenbayer

428

GET 요청은 POST 요청보다 보안 수준이 낮습니다. 그 자체만으로는 진정한 "보안"을 제공하지 않습니다. POST 요청 사용해도 악의적 인 공격으로부터 눈에 띄게 웹 사이트를 안전하게 보호 할 수 는 없습니다 . 그러나 GET 요청 사용하면 안전한 응용 프로그램이 안전하지 않을 수 있습니다 .

"변경을하기 위해 GET 요청을 사용해서는 안된다"는 진언은 여전히 ​​유효하지만 이것은 악의적 인 행동 과는 거의 관련이 없습니다 . 로그인 양식은 잘못된 요청 유형을 사용하여 전송되는 데 가장 민감한 양식입니다.

스파이더 및 웹 가속기 검색

이것이 바로 데이터 변경에 POST 요청을 사용해야하는 이유입니다. 검색 스파이더는 웹 사이트의 모든 링크를 따라 가지만 찾은 임의의 양식은 제출하지 않습니다.

웹 가속기는 검색 스파이더보다 나쁩니다. 웹 스파이더는 클라이언트의 컴퓨터에서 실행되며 로그인 한 사용자의 컨텍스트에서 모든 링크 "클릭" 하기 때문 입니다. 따라서 관리자가 필요하더라도 GET 요청을 사용하여 물건을 삭제하는 응용 프로그램은 (악의적이지 않은!) 웹 가속기의 명령을 행복하게 따르고 모든 것을 삭제합니다 .

혼란스런 대리 공격

혼란 대리인 공격 (대리인이 브라우저)이다 상관없이 당신이 GET 또는 POST 요청을 사용하는지 여부 가능 .

공격자 제어 웹 사이트에서 GET 및 POST는 사용자 상호 작용없이 제출하기가 쉽습니다 .

POST가 약간 덜 민감한 유일한 시나리오는 공격자가 제어하지 않는 많은 웹 사이트 (예 : 타사 포럼)가 ​​임의의 이미지를 포함 할 수 있지만 (공격자가 임의의 GET 요청을 주입 할 수 있음) 자동이든 수동이든간에 임의의 POST 요청을 주입하는 방법

웹 액셀러레이터가 혼란스런 대리 공격의 한 예라고 주장 할 수도 있지만 이는 정의의 문제 일뿐입니다. 악의적 인 공격자는이를 제어 할 수 없으므로 대리자 혼란스러워 도 공격 이 아닙니다 .

프록시 로그

프록시 서버는 쿼리 문자열을 제거하지 않고 GET URL을 전체적으로 기록 할 수 있습니다. POST 요청 매개 변수는 정상적으로 기록되지 않습니다. 두 경우 모두 쿠키가 기록되지 않을 수 있습니다. (예)

이것은 POST에 유리한 매우 약한 주장입니다. 첫째, 암호화되지 않은 트래픽은 전체적으로 기록 될 수 있습니다. 악의적 인 프록시는 이미 필요한 모든 것을 갖추고 있습니다. 둘째, 요청 매개 변수는 공격자에게 제한적으로 사용됩니다. 실제로 필요한 것은 쿠키뿐이므로 프록시 로그 만있는 경우 GET 또는 POST URL을 공격 할 수 없습니다.

로그인 요청에는 한 가지 예외가 있습니다. 여기에는 사용자의 비밀번호가 포함되어 있습니다. 이것을 프록시 로그에 저장하면 POST의 경우에는없는 공격 벡터가 열립니다. 그러나 일반 HTTP를 통한 로그인은 본질적으로 안전하지 않습니다.

프록시 캐시

캐싱 프록시는 GET 응답을 보유하지만 POST 응답은 보유하지 않을 수 있습니다. 그러나 URL을 POST 처리기로 변환하는 것보다 적은 노력으로 GET 응답을 캐시 할 수 없게 만들 수 있습니다.

HTTP "참조 자"

사용자가 GET 요청에 대한 응답으로 제공된 페이지에서 타사 웹 사이트로 이동 한 경우 해당 타사 웹 사이트는 모든 GET 요청 매개 변수를 볼 수 있습니다.

"요청 매개 변수를 제 3 자에게 공개"범주에 속하며, 해당 매개 변수에있는 항목에 따라 심각도가 달라집니다. POST 요청은 당연히 이것에 영향을받지 않지만 GET 요청을 이용하려면 해커가 자신의 웹 사이트에 대한 링크를 서버의 응답에 삽입해야합니다.

브라우저 기록

이것은 "프록시 로그"인수와 매우 유사합니다. GET 요청은 매개 변수와 함께 브라우저 히스토리에 저장됩니다. 공격자는 시스템에 물리적으로 액세스 할 수 있으면 쉽게 얻을 수 있습니다.

브라우저 새로 고침 작업

사용자가 "새로 고침"을 누르면 브라우저가 GET 요청을 다시 시도합니다. 종료 후 탭을 복원 할 때 그렇게 할 수 있습니다. 따라서 모든 조치 (예 : 지불)는 경고없이 반복됩니다.

브라우저는 경고없이 POST 요청을 재 시도하지 않습니다.

이는 데이터 변경에 POST 요청 만 사용하는 것이 좋은 이유이지만 악의적 인 동작 및 보안과는 아무런 관련이 없습니다.

그래서 내가 무엇을해야하니?

  • 주로 비보안 관련 이유로 POST 요청 만 사용하여 데이터를 변경하십시오.
  • 로그인 양식에는 POST 요청 만 사용하십시오. 그렇지 않으면 공격 벡터가 발생합니다.
  • 귀하의 사이트가 민감한 작업을 수행하는 경우, 단일 답변으로 다룰 수 없기 때문에 자신이하는 일을 아는 사람이 필요합니다. HTTPS, HSTS, CSP, SQL 주입 완화, 스크립트 주입 (XSS) , CSRF 및 플랫폼과 관련된 다양한 요소 (예 : 다양한 프레임 워크의 대량 할당 취약성 : ASP.NET MVC )를 사용해야합니다. Ruby on Rails 등). "보안"(악용 불가능)과 "안전하지 않음"의 차이를 만드는 것은 없습니다.

HTTPS를 통해 POST 데이터가 인코딩되지만 타사에서 URL을 스니핑 할 수 있습니까?

아니요, 스니핑 할 수 없습니다. 그러나 URL은 브라우저 기록에 저장됩니다.

모범 사례가 POST 또는 GET에 민감한 데이터를 모두 배치하지 않고 대신 서버 측 코드를 사용하여 민감한 정보를 처리하는 것이 바람직하지 않습니까?

그것이 얼마나 민감한 지 또는 더 구체적으로 어떤 방식으로 달려 있는지에 달려 있습니다. 분명히 클라이언트는 그것을 볼 것입니다. 클라이언트 컴퓨터에 물리적으로 액세스 할 수있는 사람이면 누구나 볼 수 있습니다. 클라이언트는 사용자에게 다시 보낼 때 스푸핑 할 수 있습니다. 그렇다면 중요한 데이터는 서버에 보관하고 그대로 두십시오.


29
CSRF는 POST로 가능합니다.
AviD December

5
@Lotus Notes, 그것은 조금 더 어렵지만 XSS는 필요하지 않습니다. POST 요청은 언제 어디서나 전송되며 CSRF는 XSS는 포함되지 않은 모든 웹 사이트 에서 제공 될 수 있습니다 .
AviD

18
브라우저에서 자동으로 가져 오는 GET과 달리 다른 사람이 입력 할 수있는 권한을 가지지 않아야합니다. 모든 POST 양식을 검증 가능한 소스 해시로 보호해야하며 GET 링크에 대한 그러한 수단이 없기 때문에 요점은 어리 석습니다.
kibitzer

7
글쎄, POST 양식에 추가하는 것과 같은 방식으로 모든 GET 요청에 해시를 추가 할 수 있습니다. 그러나 데이터를 수정하는 작업에는 GET을 사용해서는 안됩니다.
Eli

13
POST over GET을 사용해도 CSRF를 막을 수는 없습니다. 사람들이 URL을 통해 이미지를 허용하는 임의의 웹 사이트로 이동하는 것보다 사용자가 제어하는 ​​웹 사이트로 이동하는 것이 더 쉽습니다 (자바 스크립트가 있어야 함). 이렇게는 <body onload="document.getElementById('a').submit()"><form id="a" action="http://example.com/delete.php" action="post"><input type="hidden" name="id" value="12"></form>하드 링크를 클릭하여 어딘가에 자동으로 게시물을 제출 정말 아니다 (포함하는 HTML이)
FryGuy

175

변수가 HTTP GET을 통해 전송 된 변수보다 HTTP POST를 통해 전송되므로 더 큰 보안이 제공되지 않습니다.

HTTP / 1.1은 요청을 보내는 많은 메소드를 제공합니다 .

  • 옵션
  • 가져 오기
  • 머리
  • 게시하다
  • 놓다
  • 지우다
  • 자취
  • 잇다

GET을 사용하여 다음 HTML 문서가 있다고 가정 해 봅시다.

<html>
<body>
<form action="http://example.com" method="get">
    User: <input type="text" name="username" /><br/>
    Password: <input type="password" name="password" /><br/>
    <input type="hidden" name="extra" value="lolcatz" />
    <input type="submit"/>
</form>
</body>
</html>

브라우저는 무엇을 요구합니까? 다음과 같이 묻습니다.

 GET /?username=swordfish&password=hunter2&extra=lolcatz HTTP/1.1
 Host: example.com
 Connection: keep-alive
 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/ [...truncated]
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) [...truncated]
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

이제 요청 메소드를 POST로 변경했다고 가정 해 봅시다.

 POST / HTTP/1.1
 Host: example.com
 Connection: keep-alive
 Content-Length: 49
 Cache-Control: max-age=0
 Origin: null
 Content-Type: application/x-www-form-urlencoded
 Accept: application/xml,application/xhtml+xml,text/ [...truncated]
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; [...truncated]
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

 username=swordfish&password=hunter2&extra=lolcatz

BOTH 이 HTTP 요청은 다음과 같습니다 :

  • 암호화되지 않음
  • 두 예 모두에 포함
  • 전복 될 수 있으며 MITM 공격을받을 수 있습니다.
  • 타사 및 스크립트 봇으로 쉽게 재현 할 수 있습니다.

많은 브라우저 가 POST / GET 이외의 HTTP 메소드를 지원하지 않습니다.

많은 브라우저 비헤이비어가 페이지 주소를 저장하지만 이것이 다른 문제를 무시할 수있는 것은 아닙니다.

구체적으로 말하면 :

하나는 본질적으로 다른 것보다 더 안전합니까? POST는 URL에 정보를 노출시키지 않지만 그 안에 실제 가치가 있습니까? 아니면 모호함을 통한 보안입니까? 가장 좋은 방법은 무엇입니까?

HTTP를 사용하기 위해 사용하는 소프트웨어는 한 가지 방법으로 요청 변수를 저장하는 경향이 있지만 다른 방법은 아니지만 다른 사람이 브라우저 기록 또는 h4x0r1ng를 이해한다고 생각하는 10 세의 다른 순진한 공격을 보지 못하기 때문입니다. 또는 기록 저장소를 확인하는 스크립트입니다. 히스토리 저장소를 확인할 수있는 스크립트가있는 경우 네트워크 트래픽을 확인하는 스크립트를 쉽게 가질 수 있으므로 모호성을 통한이 전체 보안은 스크립트 키즈 및 질투하는 여자 친구에게만 모호함을 제공합니다.

https를 통해 POST 데이터는 인코딩되지만 타사에서 URL을 스니핑 할 수 있습니까?

SSL 작동 방식은 다음과 같습니다. 위에서 보낸 두 요청을 기억하십니까? SSL에서 다음과 같이 표시 됩니다. example.com이 SSL에서 응답하지 않으므로 페이지를 https://encrypted.google.com/ 으로 변경했습니다 .

SSL을 통한 POST

q5XQP%RWCd2u#o/T9oiOyR2_YO?yo/3#tR_G7 2_RO8w?FoaObi)
oXpB_y?oO4q?`2o?O4G5D12Aovo?C@?/P/oOEQC5v?vai /%0Odo
QVw#6eoGXBF_o?/u0_F!_1a0A?Q b%TFyS@Or1SR/O/o/_@5o&_o
9q1/?q$7yOAXOD5sc$H`BECo1w/`4?)f!%geOOF/!/#Of_f&AEI#
yvv/wu_b5?/o d9O?VOVOFHwRO/pO/OSv_/8/9o6b0FGOH61O?ti
/i7b?!_o8u%RS/Doai%/Be/d4$0sv_%YD2_/EOAO/C?vv/%X!T?R
_o_2yoBP)orw7H_yQsXOhoVUo49itare#cA?/c)I7R?YCsg ??c'
(_!(0u)o4eIis/S8Oo8_BDueC?1uUO%ooOI_o8WaoO/ x?B?oO@&
Pw?os9Od!c?/$3bWWeIrd_?( `P_C?7_g5O(ob(go?&/ooRxR'u/
T/yO3dS&??hIOB/?/OI?$oH2_?c_?OsD//0/_s%r

SSL을 통한 GET

rV/O8ow1pc`?058/8OS_Qy/$7oSsU'qoo#vCbOO`vt?yFo_?EYif)
43`I/WOP_8oH0%3OqP_h/cBO&24?'?o_4`scooPSOVWYSV?H?pV!i
?78cU!_b5h'/b2coWD?/43Tu?153pI/9?R8!_Od"(//O_a#t8x?__
bb3D?05Dh/PrS6_/&5p@V f $)/xvxfgO'q@y&e&S0rB3D/Y_/fO?
_'woRbOV?_!yxSOdwo1G1?8d_p?4fo81VS3sAOvO/Db/br)f4fOxt
_Qs3EO/?2O/TOo_8p82FOt/hO?X_P3o"OVQO_?Ww_dr"'DxHwo//P
oEfGtt/_o)5RgoGqui&AXEq/oXv&//?%/6_?/x_OTgOEE%v (u(?/
t7DX1O8oD?fVObiooi'8)so?o??`o"FyVOByY_ Supo? /'i?Oi"4
tr'9/o_7too7q?c2Pv

(참고 : HEX를 ASCII로 변환했는데 그중 일부는 표시 할 수 없어야합니다)

전체 HTTP 대화는 암호화되며 통신에서 유일하게 보이는 부분은 TCP / IP 계층에 있습니다 (IP 주소 및 연결 포트 정보를 의미 함).

여기서 큰 대담한 진술을하겠습니다. 귀하의 웹 사이트는 다른 HTTP 방법보다 하나의 HTTP 방법에 비해 더 큰 보안을 제공하지 않으며 전 세계의 해커와 신입생은 내가 방금 시연 한 방법을 정확히 알고 있습니다. 보안을 원하면 SSL을 사용하십시오. 브라우저는 히스토리를 저장하는 경향이 있습니다. RFC2616 9.1.1에서는 GET을 사용하여 조치를 수행하지 말 것을 권장하지만 POST가 보안을 제공한다고 생각하는 것은 옳지 않다고 생각합니다.

POST가 유일하게 보안 대책은 무엇입니까? 브라우저 기록을 넘나 드는 질투심에 대한 보호. 그게 다야. 나머지 세계는 당신을 비웃는 당신의 계정에 로그인되어 있습니다.

POST가 안전하지 않은 이유를 추가로 보여주기 위해 Facebook은 POST 요청을 모든 곳에서 사용하므로 FireSheep 와 같은 소프트웨어는 어떻게 존재할 수 있습니까?

HTTPS를 사용하고 사이트에 XSS 취약점 이없는 경우에도 CSRF 로 공격을받을 수 있습니다 . 요컨대,이 공격 시나리오는 피해자 (사이트 또는 서비스의 사용자)가 이미 로그인하여 적절한 쿠키를 가지고 있다고 가정하고 피해자의 브라우저는 귀하의 (아마도 안전한) 사이트에 무언가를하도록 요청됩니다. CSRF에 대한 보호 기능이없는 경우에도 공격자는 피해자 자격 증명으로 작업을 계속 실행할 수 있습니다. 공격자는 서버의 응답이 피해자의 브라우저로 전송되기 때문에 서버 응답을 볼 수 없지만 일반적으로 그 시점에서 피해는 이미 이루어졌습니다.


1
CSRF에 대해 이야기하지 않은 부끄러운 일 :-). 연락 할 방법이 있습니까?
Florian Margaine

@FlorianMargaine 트위터에 나를 추가하고 내가 당신에게 내 이메일을 DM하겠습니다. twitter.com/#!/BrianJGraham
시크릿

누가 페이스 북이 안전하다고 했습니까? 그래도 좋은 대답입니다. +1.
Amal Murali

1
"[...] 그래서 모호함을 통한이 전체적인 보안은 어린이들과 질투심 많은 여자 친구들에게만 모호함을 제공합니다. [...]". 이것은 전적으로 질투하는 gf의 기술에 달려 있습니다. 또한, gf / bf는 브라우저 히스토리를 방문 할 수 없습니다. 이제까지. lol.
turkishweb

34

추가 보안이 없습니다.

게시물 데이터는 기록 및 / 또는 로그 파일에 표시되지 않지만 데이터를 안전하게 유지하려면 SSL이 필요합니다.
그렇지 않으면, 와이어를 스니핑하는 사람은 어쨌든 데이터를 읽을 수 있습니다.


2
SSL을 통해 URL을 얻는 경우 타사에서 URL을 볼 수 없으므로 보안은 동일합니다.
davetron5000

7
GET 정보는 SSL 터널의 시작과 끝에서만 볼 수 있습니다
Jacco

1
그리고 sys 관리자는 로그 파일을 통해 grep 할 때.
Tomalak

1
나는이 말을 어떤 POST 데이터가 사용자의 브라우저 기록에 저장되지 않습니다에 추가 보안이 있지만, 데이터 것 GET.
Kip

3
SSL / TLS를 통한 HTTP (정확하게 구현 됨)를 통해 공격자는 스니핑 (또는 적극적으로 변조)을 통해 대상의 IP 주소와 양방향으로 전송되는 데이터 양의 두 가지만 볼 수 있습니다.
Aaron

29

로그인 양식 또는 상대적으로 민감한 정보가있는 다른 양식의 경우와 비교하여 POST실질적인 보안 혜택을 제공하지 않더라도 GET다음과 같이 사용하십시오 POST.

  1. POSTed 정보 는 사용자 기록에 저장되지 않습니다.
  2. 양식으로 전송 된 중요한 정보 (암호 등)는 나중에 URL 표시 줄에 표시되지 않습니다 (를 사용 GET하면 기록 및 URL 표시 줄에 표시됨).

또한 GET이론적 인 데이터 제한이 있습니다. POST하지 않습니다.

실제 민감한 정보의 경우 SSL( HTTPS)


기본 설정에서 firefox / IE에 사용자 이름과 비밀번호를 입력 할 때 마다이 정보를 저장할 것인지 묻습니다. 특히 나중에 입력 할 필요가 없습니다.
Kibbee

Andrew 나는 사용자 입력 필드에서 자동 완성을 의미한다고 생각합니다. 예를 들어 Firefox는 웹 사이트에 입력 한 모든 데이터를 기억하므로 검색 창에 텍스트를 입력하기 시작하면 이전 검색으로 텍스트를 완성하는 기능을 제공합니다.
James McMahon

그렇습니다. 그것이 자동 완성의 요점입니다. 그렇지 않습니다. 내가 의미하는 것은 자동 완성이 아니라 실제로 역사였습니다.
Andrew Moore

공격자가 전체 브라우저 기록에 액세스 할 수 있으면 전체 브라우저 자동 완성 데이터에도 액세스 할 수 있습니다.
Mikko Rantalainen

19

팩스와 전화 중 어느 것도 다른 것보다 "보다 안전"한 것처럼 GET과 POST 중 어느 것도 본질적으로 다른 것보다 "안전"하지 않습니다. 해결하려는 문제에 가장 적합한 방법을 선택할 수 있도록 다양한 HTTP 방법이 제공됩니다. POST는 "조치"쿼리에 더 적합한 반면 GET은 dem 등성 쿼리에 더 적합하지만 유지 관리하는 응용 프로그램의 보안 아키텍처를 이해하지 못하는 경우 POST와 마찬가지로 쉽게 발을 딛을 수 있습니다.

제 9 장 : HTTP / 1.1 RFC메소드 정의 를 읽으면 GET 및 POST가 원래 의도했던 의미에 대한 전반적인 아이디어를 얻는 것이 가장 좋습니다.


16

GET과 POST의 차이점은 보안 측면에서가 아니라 서버에 대한 의도에서 볼 수 있습니다. GET은 최소한 로그 이외의 서버에서 데이터를 변경해서는 안되지만 POST는 새로운 리소스를 생성 할 수 있습니다.

좋은 프록시는 POST 데이터를 캐시하지 않지만 URL에서 GET 데이터를 캐시 할 수 있으므로 POST가 더 안전하다고 가정 할 수 있습니다. 그러나 잘 작동하지 않는 프록시는 여전히 POST 데이터를 사용할 수 있습니다.

많은 답변에서 언급했듯이 유일한 확실한 방법은 SSL을 통한 것입니다.

그러나 GET 메소드가 데이터베이스 행 삭제 등과 같은 변경 사항을 커미트하지 않도록하십시오.


1
동의합니다. 문제는 보안이 아니라 POST와 GET이 수행하도록 설계된 것입니다.
pbreitenbach 5

6

선택하는 일반적인 방법은 다음과 같습니다.

  • 나중에 URL 로 검색 할 항목에 대한 GET
    • 예를 들어 검색은 GET이어야합니다.
  • 발송 될 품목에 대한 POST
    • 이것은 상대적으로 보이지 않는 GET에 비해 전송하기 어렵지만 데이터는 여전히 cURL을 통해 전송 될 수 있습니다.

그러나 GET보다 POST를 수행하는 것이 더 어렵습니다. GET은 주소 상자의 URL 일뿐입니다. POST에는 HTML 페이지 또는 cURL에 <form>이 필요합니다.
pbreitenbach

2
따라서 가짜 게시물에는 메모장과 5 분의 시간이 걸립니다. 메모장을 사용하여 존재하지 않는 전화 시스템에 기능을 추가했습니다. 시스템에 대한 관리자 양식의 사본을 만들어서 공급 업체에 관한 한 "불가능한"버튼에 명령을 할당 할 수있었습니다.
Matthew Whited


6

어느 쪽도 마술처럼 요청에 보안을 부여하지는 않지만 GET은 일반적으로 보안을 방해하는 부작용을 의미합니다.

GET URL은 브라우저 기록 및 웹 서버 로그에 표시됩니다. 따라서 로그인 양식 및 신용 카드 번호와 같은 용도로 사용해서는 안됩니다.

그러나 해당 데이터를 POST하는 것만으로는 안전하지 않습니다. 이를 위해 SSL이 필요합니다. GET과 POST는 모두 HTTP를 통해 사용될 때 유선으로 데이터를 일반 텍스트로 보냅니다.

무제한 데이터 양을 제출하거나 일반 사용자로부터 매개 변수를 숨기는 기능과 같이 데이터를 POST해야하는 다른 이유도 있습니다.

단점은 사용자가 POST를 통해 전송 된 쿼리 결과를 북마크 할 수 없다는 것입니다. 이를 위해서는 GET이 필요합니다.


5

다음과 같은 상황을 고려하십시오. 조잡한 API는 다음과 같은 GET 요청을 승인합니다.

http://www.example.com/api?apikey=abcdef123456&action=deleteCategory&id=1

일부 설정에서이 URL을 요청할 때 요청과 관련된 오류 / 경고가 있으면이 전체 행이 로그 파일에 기록됩니다. 최악의 경우 : 프로덕션 서버에서 오류 메시지를 비활성화하는 것을 잊어 버린 경우이 정보는 브라우저에 일반으로 표시됩니다! 이제 API 키를 모두에게 제공했습니다.

불행히도 실제 API는 이런 식으로 작동합니다.

로그에 민감한 정보가 있거나 브라우저에 표시하는 아이디어가 마음에 들지 않습니다. POST와 GET은 동일하지 않습니다. 적절한 곳에 각각 사용하십시오.


3
  1. 데이터의 안전성으로서의 보안 전송 중 : POST와 GET간에 차이가 없습니다.

  2. 컴퓨터의 데이터 안전성으로서의 보안 성 : POST가 더 안전합니다 (URL 기록 없음).


2

보안 개념은 사용자가 보안하려는 대상을 정의하지 않는 한 의미가 없습니다.

저장된 브라우저 기록, 일부 유형의 로깅 및 URL을 보는 사람들로부터 보호하려면 POST가 더 안전합니다.

누군가가 네트워크 활동을 스니핑하는 것을 막고 싶다면 아무런 차이가 없습니다.


1

많은 사람들이 GET 요청이 데이터를 검색 만하고 서버의 데이터를 수정하지 않고 POST 요청이 모든 데이터 수정에 사용된다는 규칙 (Ros에 의해 암시 됨)을 채택합니다. 하나 더 본질적으로 다른 것보다 보안이 경우 아니지만 어떻게 이 규칙을 따르 크로스 커팅 보안 로직을 적용 할 수 있습니다 (계정을 가진 예를 들어 사람들 만이 데이터를 수정할 수 있도록 인증되지 않은 게시물 거부됩니다).


4
실제로 그것은 "협약"이 아니며 HTTP 표준의 일부입니다. RFC는 다른 방법에서 기대할 수있는 내용에 대해 매우 명시 적입니다.
John Nilsson

실제로 GET 요청이 상태를 수정하도록 허용하면 방문 페이지가 프리 페치중인 브라우저에서 실수로 원하지 않는 작업을 수행 할 수 있습니다.
Jessta

1

POST 요청을 변경하는 것이 더 어렵습니다 (쿼리 문자열을 편집하는 것보다 더 많은 노력이 필요합니다). 편집 : 다른 말로하면, 그것은 모호한 보안 일뿐입니다.


3
Firefox의 몇 가지 애드온을 사용하여 쿼리 문자열 요청처럼 쉽게 POST 요청을 변경할 수 있습니다. 쿠키 데이터를 내 마음의 내용으로 수정할 수도 있습니다.
stephenbayer

스크립트 키드 속도를 늦추지 않으며 스크립트 키드가 항상 시도하는 유형입니다. 문제는 그들이 때때로 성공한다는 것입니다.
Jacco

2
어 Firefox 용 애드온 사용 = 쿼리 문자열보다 더 많은 노력.
eyelidlessness

귀하의 답변은 게시물을 사용할 때, 실제로는 그렇지 않을 때 더 안전하다는 사람들에게 잘못된 의미를 줄 것입니다. 나쁜 대답, 나쁜 사람
Chris Marasti-Georg

내 대답의 의도를 더 명확하게하기 위해 편집했습니다. 잘하면 그것은 도움이됩니다.
eyelidlessness

1

나는 다른 모든 대답을 반복하지는 않지만 아직 언급하지 않은 한 가지 측면이 있습니다. 그것은 데이터가 사라지는 이야기입니다. 어디서 찾아야할지 모르겠지만 ...

기본적으로 그것은 매일 밤 신비롭게 모든 데이터를 잃어 버렸고 아무도 이유를 알지 못하는 웹 응용 프로그램에 관한 것입니다. 로그를 조사한 결과, Google 또는 다른 임의의 스파이더가 사이트를 찾았으며 "이 항목 삭제"및 "확인 하시겠습니까?"를 포함하여 사이트에서 찾은 모든 링크를 행복하게 GET (읽기 : GOT)했음을 알 수있었습니다. 연결.

실제로-이것의 일부가 언급되었습니다. 이것은 "GET에서 데이터를 변경하지 말고 POST에서만"변경 한 내용입니다. 크롤러는 GET을 따라 가며 POST를하지 않습니다. robots.txt조차도 크롤러 오작동에 도움이되지 않습니다.


1

또한 사이트에 다른 외부 사이트에 대한 링크가 포함 된 경우 GET을 사용하여 제어하지 않으면 외부 사이트의 링크를 누를 때 해당 데이터를 외부 사이트의 refeerer 헤더에 넣습니다. 따라서 GET 메소드를 통해 로그인 데이터를 전송하는 것은 항상 큰 문제입니다. 로그를 확인하거나 Google 웹 로그 분석 (또는 유사한)을 살펴보면 쉽게 액세스 할 수 있도록 로그인 자격 증명이 노출 될 수 있습니다.


1

RFC7231 :

"URI는 보안 자원을 식별 할 때도 보안되지 않고 공유되도록 고안되었습니다. URI는 종종 디스플레이에 표시되고, 페이지가 인쇄 될 때 템플리트에 추가되고, 다양한 비보호 책갈피 목록에 저장됩니다. 따라서 포함하지 않는 것이 좋습니다 민감한 개인 식별 정보 또는 공개 위험이있는 URI 내의 정보

서비스 작성자는 중요한 데이터를 제출할 때 GET 기반 양식을 사용하지 않아야합니다. 그 데이터는 요청 대상에 배치되기 때문입니다. 기존의 많은 서버, 프록시 및 사용자 에이전트는 요청 대상을 제 3자가 볼 수있는 위치에 기록하거나 표시합니다. 이러한 서비스는 대신 POST 기반 양식 제출을 사용해야합니다. "

이 RFC는 GET을 사용하여 민감한 데이터를 제출해서는 안된다는 것을 분명히 밝힙니다. 이 설명 때문에 일부 구현자는 동일한주의를 기울여 GET 요청의 쿼리 부분에서 얻은 데이터를 처리하지 못할 수 있습니다. 데이터 무결성을 보장하는 프로토콜을 직접 연구하고 있습니다. 이 사양에 따르면 GET 데이터의 무결성을 보장 할 필요는 없습니다 (아무도 이러한 사양을 준수하지 않기 때문에)


1

이전에 일부 사람들이 말했듯이 HTTPS는 보안을 제공합니다.

그러나 POST는 GET이 기록에 저장 될 수 있기 때문에 GET보다 약간 안전합니다.

그러나 슬프게도 POST 또는 GET의 선택은 개발자에게 달려 있지 않습니다. 예를 들어 하이퍼 링크는 항상 GET에 의해 전송됩니다 (자바 스크립트를 사용하여 포스트 형식으로 변환되지 않는 한).


0

GET은 누구나 볼 수 있으며 (지금 어깨에있는 것조차도) 캐시에 저장되므로 post를 사용하는 것이 안전하지 않으며, 일부 암호화 루틴을 사용하지 않는 btw post는 확실하지 않습니다. https)


0

POST가 보안 상 나쁜 이유 중 하나 기본적으로 GET 이 기록되고 매개 변수와 모든 데이터가 웹 서버에 의해 거의 보편적으로 기록되기 때문입니다.

POST 는 그 반대 이며, 거의 보편적으로 기록되지 않으므로 공격자 활동을 파악하기가 매우 어렵습니다.

나는 "너무 큽니다"라는 말을 사지 않습니다. 아무 것도 기록하지 않을 이유가 없습니다 . 적어도 1KB는 사람들이 약한 진입 점에서 도망쳐 공격자가 팝이 나올 때까지 식별하는 데 먼 길을 갈 것입니다. HTTP 기반 백도어가 무제한의 데이터를 자동으로 전달할 수 있도록함으로써 이중 서비스 중단.


0

차이점은 GET이 데이터를 열고 POST를 숨긴다는 것입니다 (http-header에서).

따라서 get은 Google의 쿼리 문자열과 같은 비보안 데이터에 더 좋습니다. 인증 데이터는 절대 GET을 통해 전송되지 않으므로 POST를 사용하십시오. 물론 전체 테마는 조금 더 복잡합니다. 자세한 내용을 보려면 이 기사를 읽으십시오 (독일어).


0

최근 에는 중간에있는 사람이 압축 된 HTTPS 요청의 요청 본문을 공개 할 수 있는 공격 이 게시되었습니다. 요청 헤더와 URL은 HTTP에 의해 압축되지 않기 때문에 GET 요청은이 특정 공격에 대해보다 안전하게 보호됩니다.

GET 요청도 취약한 모드 가 있으며 SPDY는 요청 헤더를 압축하며 TLS는 옵션 (드물게 사용되는) 압축도 제공합니다. 이러한 시나리오에서는 공격을 쉽게 예방할 수 있습니다 (브라우저 공급 업체는 이미 수정 사항을 제공했습니다). HTTP 수준 압축은보다 기본적인 기능이며 공급 업체가이를 비활성화하지는 않습니다.

POST보다 GET이 더 안전한 시나리오를 보여주는 예일 뿐이지 만이 공격 이유에서 POST 대신 GET을 선택하는 것은 좋은 생각이 아닙니다. 공격은 매우 정교하며 사소한 전제 조건이 필요합니다 (공격자는 요청 내용의 일부를 제어 할 수 있어야 함). 공격이 유해한 시나리오에서는 HTTP 압축을 비활성화하는 것이 좋습니다.


0

면책 조항 : 다음 사항은 웹 사이트 URL이 아닌 API 호출에만 적용됩니다.

네트워크를 통한 보안 : HTTPS를 사용해야합니다. 이 경우 GET과 POST는 동일하게 안전합니다.

브라우저 히스토리 : Angular JS, React JS 등과 같은 프론트 엔드 애플리케이션의 경우 API 호출은 프론트 엔드에서 작성된 AJAX 호출입니다. 이들은 브라우저 히스토리의 일부가되지 않습니다. 따라서 POST와 GET은 동일하게 안전합니다.

서버 측 로그 : 데이터 마스킹 및 액세스 로그 형식의 쓰기 세트를 사용하면 요청 URL에서 민감한 데이터를 모두 또는 숨길 수 있습니다.

브라우저 콘솔의 데이터 가시성 : 악의적 인 의도를 가진 사람의 경우 POST 데이터를 GET만큼 보는 것이 거의 동일합니다.

따라서 올바른 로깅 방법을 사용하면 GET API는 POST API만큼 안전합니다. 어디서나 POST를 수행하면 API 정의가 열악 해 지므로 피해야합니다.


-2

Post는 메시지 본문에서 전송되기 때문에 설치된 SSL과 함께 가장 안전합니다.

그러나 아래에서 사용하는 7 비트 프로토콜은 이스케이프 처리 할 수 ​​있기 때문에 이러한 모든 방법은 안전하지 않습니다. 레벨 4 웹 애플리케이션 방화벽을 통해서도.

소켓은 어떤 방법 으로든 더 안전하지만 보장 할 수는 없습니다.


-3

이것은 오래된 게시물이지만 일부 답변에 반대하고 싶습니다. 민감한 데이터를 전송하는 경우 SSL을 사용하고 싶을 것입니다. GET 매개 변수와 함께 SSL을 사용하면 (예 :? userid = 123) 해당 데이터가 일반 텍스트로 전송됩니다! POST를 사용하여 전송하면 값이 메시지의 암호화 된 본문에 저장되므로 대부분의 MITM 공격에서 읽을 수 없습니다.

큰 차이점은 데이터가 전달되는 위치입니다. 데이터가 URL에 있으면 데이터를 암호화 할 수 없으며, 그렇지 않으면 URL 만 읽을 수 있기 때문에 서버로 라우팅 할 수 없습니다. 그것이 GET이 작동하는 방식입니다.

간단히 말해 SSL을 통해 POST로 데이터를 안전하게 전송할 수 있지만 SSL을 사용하여 GET을 사용하여 전송하지는 않습니다.


4
이것은 사실이 아닙니다. SSL은 전송 계층 프로토콜입니다. 서버 FIRST에 연결 한 다음 모든 응용 프로그램 데이터를 암호화 된 이진 데이터 스트림으로 보냅니다. 이 스레드를 확인하십시오. answers.google.com/answers/threadview/id/758002.html
Simeon G

TCPDump를 수행하면 이것이 100 % 사실임을 알 수 있습니다. 서버에 연결하려면 요청을 암호화되지 않은 상태로 보내야합니다. 이를 GET으로 수행하면 인수가 초기 요청에 추가되므로 암호화되지 않습니다. 연결 한 게시물에 표시되는 내용에 관계없이 TCPDump (또는 이와 유사한)로이를 테스트 할 수 있습니다.
LVM

1
끝난! 내 Mac에서 tcpdump를 실행했습니다. 그리고 당신의 대답은 100 % 잘못되었습니다. 내가 사용한 명령은 다음과 같습니다. sudo tcpdump -w ssl.data -A -i en1 -n dst 포트 443 그런 다음 ssl.data를 살펴보면 gobly gook을 보았습니다. 모든 HTTP 데이터가 암호화되었습니다. 그리고 일반 비 SSL 호출이 작동하는지 확인하기 위해 다음을 사용했습니다. sudo tcpdump -w clear.data -A -i en1 -n dst port 80 그리고 clear.data 내부에는 모든 헤더와 URI가 일반으로 표시되어 있습니다. . 내 Gmail 및 Google 플러스 (HTTPS 인 경우)와 google.com과 같은 SSL 이외의 페이지에서 이것을 테스트했습니다.
Simeon G

나는 네트워크 전문가가 아니기 때문에 tcpdump에서 잘못된 명령을 사용했다고 생각되면 언제든지 수정하십시오.
Simeon G

나는 명령을 내리지 않았지만 Wireshark / Ethereal에서 확인할 수도 있습니다.
LVM

-3

POST조차도 GET 요청을 수락합니다. user.name 및 user.passwd와 같은 입력을 가진 양식이 있다고 가정하면 사용자 이름과 비밀번호를 지원해야합니다. 단순히 "user.name ="my user & user.passwd = "my password"를 추가하면 "로그온 페이지 우회"를 통해 요청이 수락됩니다.

이를위한 해결책은 서버 측에서 필터 (Java 필터는 e)를 구현하고 문자열 조회가 GET 인수로 전달되지 않는 것을 감지하는 것입니다.


2
사실이 아니다! POST를 허용하는 코드가 GET을 허용하는지 여부는 전적으로 백엔드에 달려 있습니다.
Colin 't Hart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.