Là GET hoặc POST an toàn hơn so với cái khác?


282

Khi so sánh HTTP GET với HTTP POST, sự khác biệt từ góc độ bảo mật là gì? Là một trong những lựa chọn vốn đã an toàn hơn so với lựa chọn khác? Nếu vậy, tại sao?

Tôi nhận ra rằng POST không tiết lộ thông tin trên URL, nhưng có bất kỳ giá trị thực sự nào trong đó hay chỉ là bảo mật thông qua che khuất? Có bao giờ một lý do mà tôi nên thích POST khi bảo mật là một mối quan tâm?

Chỉnh sửa:
Trên HTTPS, dữ liệu POST được mã hóa, nhưng URL có thể bị đánh hơi bởi bên thứ 3 không? Ngoài ra, tôi đang làm việc với JSP; khi sử dụng JSP hoặc một khung công tác tương tự, có công bằng không khi nói cách tốt nhất là tránh đặt dữ liệu nhạy cảm trong POST hoặc GET hoàn toàn và sử dụng mã phía máy chủ để xử lý thông tin nhạy cảm thay thế?


1
Có một mục blog rất hay về điều này trên blog của Jeff Coding Horror: Cross-Site Request Forgeries and You .
fhe

Bạn sẽ không sử dụng POST cho hầu hết mọi thứ. Ví dụ: đối với API, giả sử bạn cần NHẬN dữ liệu từ DB, nhưng trước khi máy chủ trả lại dữ liệu, bạn sẽ phải xác thực trước? Sử dụng bài đăng, bạn chỉ cần vượt qua ID phiên của mình + tất cả các tham số bạn cần cho yêu cầu. Nếu bạn đã sử dụng req GET cho việc này thì ID phiên của bạn có thể dễ dàng được tìm thấy trong lịch sử trình duyệt của bạn hoặc ở đâu đó ở giữa.
James111

Tôi nhớ cuộc thảo luận này từ trước chiến tranh (99 'hoặc '00 hoặc hơn) khi https không phổ biến.
David Tonhofer

@DavidTonhofer, bạn đang đề cập đến cuộc chiến nào? Cuộc chiến trình duyệt?
DeltaFlyer

@DeltaFlyer Không, Cuộc chiến muôn thuở, hay còn gọi là GWOT. Chúng ta đã làm gì
David Tonhofer

Câu trả lời:


206

Về bảo mật, chúng vốn dĩ giống nhau. Mặc dù đúng là POST không tiết lộ thông tin qua URL, nhưng nó chỉ hiển thị nhiều thông tin như một GET trong giao tiếp mạng thực tế giữa máy khách và máy chủ. Nếu bạn cần truyền thông tin nhạy cảm, tuyến phòng thủ đầu tiên của bạn sẽ là truyền thông tin đó bằng Secure HTTP.

NHẬN hoặc các bài đăng chuỗi truy vấn thực sự tốt cho thông tin cần thiết để đánh dấu một mục cụ thể hoặc để hỗ trợ tối ưu hóa công cụ tìm kiếm và lập chỉ mục các mục.

POST là tốt cho các hình thức tiêu chuẩn được sử dụng để gửi dữ liệu một lần. Tôi sẽ không sử dụng GET để đăng các biểu mẫu thực tế, trừ khi có thể trong một biểu mẫu tìm kiếm nơi bạn muốn cho phép người dùng lưu truy vấn trong dấu trang hoặc một cái gì đó dọc theo các dòng đó.


5
Với lời cảnh báo rằng để NHẬN URL, được hiển thị trên thanh vị trí có thể hiển thị dữ liệu sẽ bị ẩn trong POST.
tvanfosson

93
Nó chỉ ẩn trong ý nghĩa ngây thơ nhất
davetron5000

7
đúng, nhưng bạn cũng có thể nói rằng bàn phím không an toàn vì ai đó có thể nhìn qua vai bạn khi bạn nhập mật khẩu. Có rất ít sự khác biệt giữa bảo mật thông qua che khuất và không có bảo mật nào cả.
stephenbayer

65
Khả năng hiển thị (và bộ đệm) của các truy vấn trong URL và do đó hộp địa chỉ rõ ràng kém an toàn hơn. Không có thứ gọi là bảo mật tuyệt đối nên mức độ bảo mật có liên quan.
poustitenbach

6
nó thậm chí còn bị lộ nếu bạn sử dụng một bài viết. trong trường hợp của bạn, bài viết sẽ an toàn hơn một chút. Nhưng nghiêm túc .. tôi có thể thay đổi các biến bài đăng cả ngày, dễ dàng như nhận các biến. Cookies thậm chí có thể được xem và sửa đổi .. không bao giờ dựa vào thông tin mà trang web của bạn đang gửi dưới bất kỳ hình dạng hoặc hình thức nào. Bạn càng cần bảo mật, bạn càng có nhiều phương thức xác minh.
stephenbayer

428

Yêu cầu GET không an toàn hơn một chút so với yêu cầu POST. Không cung cấp "bảo mật" thực sự của chính nó; sử dụng các yêu cầu POST sẽ không làm cho trang web của bạn an toàn trước các cuộc tấn công độc hại với số lượng đáng chú ý. Tuy nhiên, sử dụng các yêu cầu GET có thể làm cho ứng dụng an toàn không an toàn.

Câu thần chú mà bạn "không được sử dụng các yêu cầu GET để thực hiện thay đổi" vẫn còn rất nhiều giá trị, nhưng điều này ít liên quan đến hành vi độc hại . Các hình thức đăng nhập là những hình thức nhạy cảm nhất để được gửi bằng cách sử dụng loại yêu cầu sai.

Tìm kiếm nhện và trình tăng tốc web

Đây là lý do thực sự bạn nên sử dụng các yêu cầu POST để thay đổi dữ liệu. Nhện tìm kiếm sẽ theo mọi liên kết trên trang web của bạn, nhưng sẽ không gửi biểu mẫu ngẫu nhiên mà chúng tìm thấy.

Trình tăng tốc web tệ hơn trình tìm kiếm, vì chúng chạy trên máy của khách hàng và "nhấp" tất cả các liên kết trong ngữ cảnh của người dùng đã đăng nhập . Do đó, một ứng dụng sử dụng yêu cầu GET để xóa nội dung, ngay cả khi yêu cầu quản trị viên, sẽ vui vẻ tuân theo các lệnh của trình tăng tốc web (không độc hại!) Và xóa mọi thứ mà nó nhìn thấy .

Phó tấn công bối rối

Một cuộc tấn công phó nhầm lẫn (trong đó phó là trình duyệt) có thể xảy ra bất kể bạn sử dụng yêu cầu GET hay POST .

Trên các trang web do kẻ tấn công kiểm soát, GET và POST đều dễ gửi như nhau mà không cần tương tác của người dùng .

Kịch bản duy nhất mà POST ít nhạy cảm hơn là nhiều trang web không thuộc quyền kiểm soát của kẻ tấn công (giả sử diễn đàn bên thứ ba) cho phép nhúng hình ảnh tùy ý (cho phép kẻ tấn công thực hiện yêu cầu GET tùy ý), nhưng ngăn chặn tất cả cách tiêm một yêu cầu POST tùy tiện, cho dù là tự động hay thủ công.

Người ta có thể lập luận rằng các trình tăng tốc web là một ví dụ về tấn công phó nhầm lẫn, nhưng đó chỉ là vấn đề định nghĩa. Nếu bất cứ điều gì, một âm mưu tấn công không kiểm soát này, vì vậy nó hầu như không một cuộc tấn công , ngay cả khi phó được nhầm lẫn.

Nhật ký proxy

Các máy chủ proxy có thể ghi nhật ký toàn bộ URL NHẬN, mà không tước chuỗi truy vấn. Các tham số yêu cầu POST không được ghi lại bình thường. Cookies không có khả năng được đăng nhập trong cả hai trường hợp. (thí dụ)

Đây là một lập luận rất yếu ủng hộ POST. Thứ nhất, lưu lượng chưa được mã hóa có thể được ghi lại toàn bộ; một proxy độc hại đã có mọi thứ nó cần. Thứ hai, các tham số yêu cầu được sử dụng hạn chế cho kẻ tấn công: thứ chúng thực sự cần là cookie, vì vậy nếu thứ duy nhất chúng có là nhật ký proxy, chúng không có khả năng tấn công URL GET hoặc POST.

Có một ngoại lệ cho các yêu cầu đăng nhập: những yêu cầu này có xu hướng chứa mật khẩu của người dùng. Lưu cái này trong nhật ký proxy sẽ mở ra một vectơ tấn công không có trong trường hợp POST. Tuy nhiên, dù sao thì việc đăng nhập qua HTTP đơn giản là không an toàn.

Bộ đệm proxy

Proxy lưu trữ có thể giữ lại phản hồi GET, nhưng không phản hồi POST. Phải nói rằng, các phản hồi GET có thể được thực hiện không lưu trong bộ nhớ cache với ít nỗ lực hơn so với chuyển đổi URL sang trình xử lý POST.

"Người giới thiệu" HTTP

Nếu người dùng điều hướng đến trang web của bên thứ ba từ trang được cung cấp để đáp ứng yêu cầu GET, trang web của bên thứ ba đó sẽ thấy tất cả các tham số yêu cầu GET.

Thuộc danh mục "tiết lộ các tham số yêu cầu cho bên thứ ba", mức độ nghiêm trọng phụ thuộc vào những gì có trong các tham số đó. Các yêu cầu POST hoàn toàn miễn dịch với điều này, tuy nhiên để khai thác yêu cầu GET, hacker sẽ cần chèn một liên kết đến trang web của riêng họ vào phản hồi của máy chủ.

Lịch sử trình duyệt

Điều này rất giống với đối số "nhật ký proxy": Yêu cầu GET được lưu trữ trong lịch sử trình duyệt cùng với các tham số của chúng. Kẻ tấn công có thể dễ dàng có được những thứ này nếu chúng có quyền truy cập vật lý vào máy.

Hành động làm mới trình duyệt

Trình duyệt sẽ thử lại yêu cầu GET ngay khi người dùng nhấn "refresh". Nó có thể làm điều đó khi khôi phục các tab sau khi tắt máy. Bất kỳ hành động nào (giả sử, một khoản thanh toán) do đó sẽ được lặp lại mà không có cảnh báo.

Trình duyệt sẽ không thử lại yêu cầu POST mà không có cảnh báo.

Đây là một lý do chính đáng để chỉ sử dụng các yêu cầu POST để thay đổi dữ liệu, nhưng không liên quan gì đến hành vi độc hại và do đó, bảo mật.

Vậy tôi phải làm sao?

  • Chỉ sử dụng các yêu cầu POST để thay đổi dữ liệu, chủ yếu vì các lý do không liên quan đến bảo mật.
  • Chỉ sử dụng các yêu cầu POST cho các hình thức đăng nhập; làm khác giới thiệu các vectơ tấn công.
  • Nếu trang web của bạn thực hiện các hoạt động nhạy cảm, bạn thực sự cần một người biết họ đang làm gì, bởi vì điều này không thể được đề cập trong một câu trả lời. Bạn cần sử dụng HTTPS, HSTS, CSP, giảm thiểu SQL SQL, tiêm script (XSS) , CSRF và một số thứ khác có thể dành riêng cho nền tảng của bạn (như lỗ hổng gán khối lượng lớn trong các khung khác nhau: ASP.NET MVC , Ruby trên Rails , v.v.). Không có điều gì duy nhất tạo ra sự khác biệt giữa "an toàn" (không thể khai thác) và "không an toàn".

Qua HTTPS, dữ liệu POST được mã hóa, nhưng URL có thể bị đánh hơi bởi bên thứ 3 không?

Không, họ không thể đánh hơi được. Nhưng các URL sẽ được lưu trữ trong lịch sử trình duyệt.

Sẽ là công bằng khi nói cách thực hành tốt nhất là tránh có thể đặt dữ liệu nhạy cảm vào POST hoặc GET hoàn toàn và sử dụng mã phía máy chủ để xử lý thông tin nhạy cảm thay thế?

Phụ thuộc vào mức độ nhạy cảm của nó, hoặc cụ thể hơn, theo cách nào. Rõ ràng là khách hàng sẽ nhìn thấy nó. Bất cứ ai có quyền truy cập vật lý vào máy tính của khách hàng đều sẽ thấy nó. Khách hàng có thể giả mạo nó khi gửi lại cho bạn. Nếu có vấn đề thì có, hãy giữ dữ liệu nhạy cảm trên máy chủ và đừng để nó rời đi.


29
ahem, CSRF hoàn toàn có thể với POST.
AviD

5
@Lotus Ghi chú, nó hơi khó hơn một chút, nhưng bạn không cần bất kỳ loại XSS nào. Các yêu cầu POST đang được gửi mọi lúc mọi nơi và đừng quên CSRF có thể được lấy từ bất kỳ trang web nào , không bao gồm XSS.
AviD

18
không, bạn phải tạo cho người khác những đặc quyền để gõ nó, trái ngược với một GET sẽ được trình duyệt âm thầm tìm nạp. xem xét rằng mọi hình thức POST phải được bảo vệ bằng hàm băm nguồn có thể kiểm chứng và không có phương tiện nào cho liên kết GET, quan điểm của bạn là ngớ ngẩn.
kibitzer

7
Chà, bạn có thể thêm một hàm băm vào tất cả các yêu cầu GET của mình chính xác giống như cách bạn thêm chúng vào các biểu mẫu POST ... Nhưng bạn vẫn không nên sử dụng GET cho bất cứ điều gì làm thay đổi dữ liệu.
Eli

13
Sử dụng POST trên GET không ngăn chặn bất kỳ loại CSRF nào. Nó chỉ làm cho chúng dễ thực hiện hơn một chút, vì việc đưa mọi người đến một trang web ngẫu nhiên cho phép hình ảnh từ url dễ dàng hơn là vào một trang web mà bạn kiểm soát (đủ để có javascript). Thực <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>sự không khó để gửi bài đăng ở đâu đó một cách tự động bằng cách nhấp vào một liên kết (có chứa html đó)
FryGuy

175

Bạn không có bảo mật lớn hơn được cung cấp vì các biến được gửi qua HTTP POST so với các biến được gửi qua HTTP GET.

HTTP / 1.1 cung cấp cho chúng tôi một loạt các phương thức để gửi yêu cầu :

  • LỰA CHỌN
  • ĐƯỢC
  • CÁI ĐẦU
  • BÀI ĐĂNG
  • ĐẶT
  • XÓA BỎ
  • TRACE
  • KẾT NỐI

Giả sử bạn có tài liệu HTML sau bằng GET:

<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>

Trình duyệt của bạn yêu cầu gì? Nó hỏi điều này:

 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

Bây giờ hãy giả vờ rằng chúng tôi đã thay đổi phương thức yêu cầu đó thành 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

Cả hai yêu cầu HTTP này là:

  • Không được mã hóa
  • Bao gồm trong cả hai ví dụ
  • Có thể bị báo trước và bị tấn công MITM.
  • Dễ dàng sao chép bởi bên thứ ba và bot chương trình.

Nhiều trình duyệt không hỗ trợ các phương thức HTTP ngoài POST / GET.

Nhiều trình duyệt hành vi lưu trữ địa chỉ trang, nhưng điều này không có nghĩa là bạn có thể bỏ qua bất kỳ vấn đề nào khác.

Vì vậy, để được cụ thể:

Là một vốn có an toàn hơn sau đó khác? Tôi nhận ra rằng POST không tiết lộ thông tin trên URL nhưng có bất kỳ giá trị thực nào trong đó hay chỉ là bảo mật thông qua che khuất? Thực hành tốt nhất ở đây là gì?

Điều này là chính xác, bởi vì phần mềm bạn đang sử dụng để nói HTTP có xu hướng lưu trữ các biến yêu cầu bằng một phương thức nhưng không phải là phương pháp khác chỉ ngăn người khác nhìn vào lịch sử trình duyệt của bạn hoặc một cuộc tấn công ngây thơ khác từ một đứa trẻ 10 tuổi nghĩ rằng họ hiểu h4x0r1ng hoặc tập lệnh kiểm tra cửa hàng lịch sử của bạn. Nếu bạn có một tập lệnh có thể kiểm tra kho lưu trữ lịch sử của mình, bạn có thể dễ dàng có một tập lệnh kiểm tra lưu lượng mạng của mình, vì vậy toàn bộ bảo mật thông qua che khuất này chỉ cung cấp sự tối nghĩa cho những đứa trẻ kịch bản và những cô bạn gái ghen tuông.

Qua https, dữ liệu POST được mã hóa, nhưng các url có thể bị đánh hơi bởi bên thứ 3 không?

Đây là cách SSL hoạt động. Ghi nhớ hai yêu cầu tôi đã gửi ở trên? Đây là giao diện của chúng trong SSL: (Tôi đã thay đổi trang thành https://encrypted.google.com/ vì example.com không phản hồi trên SSL).

POST qua SSL

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

NHẬN qua SSL

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

(lưu ý: Tôi đã chuyển đổi HEX thành ASCII, một số trong đó rõ ràng là không thể hiển thị)

Toàn bộ cuộc hội thoại HTTP được mã hóa, phần giao tiếp hiển thị duy nhất nằm trên lớp TCP / IP (nghĩa là địa chỉ IP và thông tin cổng kết nối).

Vì vậy, hãy để tôi thực hiện một tuyên bố táo bạo lớn ở đây. Trang web của bạn không được cung cấp bảo mật cao hơn một phương thức HTTP so với phương thức khác, tin tặc và người mới trên toàn thế giới biết chính xác cách thực hiện những gì tôi vừa trình bày ở đây. Nếu bạn muốn bảo mật, hãy sử dụng SSL. Các trình duyệt có xu hướng lưu trữ lịch sử, được RFC2616 9.1.1 khuyến nghị KHÔNG sử dụng GET để thực hiện một hành động, nhưng nghĩ rằng POST cung cấp bảo mật là hoàn toàn sai.

Điều duy nhất mà POST là một biện pháp bảo mật đối với? Bảo vệ chống lại sự ghen tuông của bạn lướt qua lịch sử trình duyệt của bạn. Đó là nó. Phần còn lại của thế giới đăng nhập vào tài khoản của bạn cười nhạo bạn.

Để giải thích thêm tại sao POST không an toàn, Facebook sử dụng các yêu cầu POST ở mọi nơi, vậy làm thế nào để phần mềm như FireSheep tồn tại?

Lưu ý rằng bạn có thể bị tấn công bằng CSRF ngay cả khi bạn sử dụng HTTPS và trang web của bạn không chứa lỗ hổng XSS . Nói tóm lại, kịch bản tấn công này giả định rằng nạn nhân (người dùng trang web hoặc dịch vụ của bạn) đã đăng nhập và có cookie thích hợp và sau đó trình duyệt của nạn nhân được yêu cầu làm gì đó với trang web (được cho là an toàn) của bạn. Nếu bạn không có bảo vệ chống lại CSRF, kẻ tấn công vẫn có thể thực hiện các hành động với thông tin xác thực nạn nhân. Kẻ tấn công không thể thấy phản hồi của máy chủ vì nó sẽ được chuyển đến trình duyệt của nạn nhân nhưng thiệt hại thường được thực hiện tại thời điểm đó.


1
Một sự xấu hổ mà bạn đã không nói về CSRF :-). Có cách nào để liên lạc với bạn?
Florian Margaine

@FlorianMargaine Thêm tôi trên twitter và tôi sẽ gửi email cho bạn. twitter.com/#!/BrianJGraham
Ẩn danh

Ai nói Facebook là an toàn? Câu trả lời tốt mặc dù. +1.
Amal Murali

1
"[...] Vì vậy, toàn bộ bảo mật thông qua che khuất này chỉ cung cấp sự tối nghĩa cho những đứa trẻ kịch bản và những cô bạn gái ghen tuông. [...]". điều này hoàn toàn phụ thuộc vào các kỹ năng của gf ghen. hơn nữa, không được phép gf / bf truy cập vào lịch sử trình duyệt của bạn. không bao giờ. cười lớn.
Thổ Nhĩ Kỳ

34

Không có bảo mật bổ sung.

Dữ liệu bài đăng không hiển thị trong lịch sử và / hoặc tệp nhật ký nhưng nếu dữ liệu cần được giữ an toàn, bạn cần SSL.
Nếu không, bất cứ ai đánh hơi dây có thể đọc dữ liệu của bạn nào.


2
nếu bạn NHẬN URL qua SSL, bên thứ ba sẽ không thể thấy URL, vì vậy bảo mật là như nhau
davetron5000

7
Thông tin NHẬN chỉ có thể được nhìn thấy ở đầu và cuối đường hầm SSL
Jacco

1
Và các quản trị viên hệ thống khi họ grep máng các tệp nhật ký.
Tomalak

1
Tôi có thể nói rằng có một số bảo mật được thêm vào trong dữ liệu POST sẽ không được lưu trữ trong lịch sử trình duyệt của người dùng, nhưng dữ liệu GET sẽ.
Kip

3
HTTP qua SSL / TLS (được triển khai chính xác) cho phép kẻ tấn công đánh hơi dây (hoặc chủ động giả mạo) chỉ nhìn thấy hai điều - địa chỉ IP của đích và lượng dữ liệu đi cả hai chiều.
Aaron

29

Ngay cả khi POSTkhông mang lại lợi ích bảo mật thực sự so với GET, đối với các biểu mẫu đăng nhập hoặc bất kỳ hình thức nào khác có thông tin tương đối nhạy cảm, hãy đảm bảo bạn đang sử dụng POSTnhư:

  1. Thông tin POSTed sẽ không được lưu trong lịch sử của người dùng.
  2. Thông tin nhạy cảm (mật khẩu, v.v.) được gửi trong biểu mẫu sẽ không hiển thị sau này trong thanh URL (bằng cách sử dụng GET, nó sẽ hiển thị trong lịch sử và thanh URL).

Ngoài ra, GETcó một giới hạn lý thuyết của dữ liệu. POSTkhông.

Để biết thông tin nhạy cảm thực sự, hãy đảm bảo sử dụng SSL( HTTPS)


Trong cài đặt mặc định, mỗi lần tôi nhập tên người dùng và mật khẩu trong firefox / IE, nó sẽ hỏi tôi có muốn lưu thông tin này không, vì vậy tôi sẽ không phải nhập nó sau.
Kibbee

Andrew Tôi nghĩ rằng anh ấy có nghĩa là tự động hoàn thành trên các trường nhập của người dùng. Chẳng hạn, Firefox ghi nhớ tất cả dữ liệu tôi nhập vào trang web của mình, vì vậy khi tôi bắt đầu nhập văn bản vào hộp tìm kiếm, nó sẽ cung cấp để hoàn thành văn bản với các tìm kiếm trước đó của tôi.
James McMahon

Vâng, đó là điểm tự động hoàn thành, phải không. Ý tôi là lịch sử thực sự, không tự động hoàn thành.
Andrew Moore

Nếu kẻ tấn công có thể truy cập toàn bộ lịch sử trình duyệt, anh ta cũng có quyền truy cập vào dữ liệu hoàn thành tự động của trình duyệt.
Mikko Rantalainen

19

Cả GET và POST đều không "an toàn" hơn cái kia, giống như cả fax và điện thoại đều "an toàn" hơn cái kia. Các phương thức HTTP khác nhau được cung cấp để bạn có thể chọn phương thức phù hợp nhất cho vấn đề bạn đang cố gắng giải quyết. GET là hơn thích hợp cho idempotent truy vấn trong khi POST là hơn thích hợp cho các truy vấn "hành động", nhưng bạn có thể chụp mình trong bàn chân cũng giống như dễ dàng với bất kỳ trong số họ nếu bạn không hiểu được kiến trúc an ninh cho các ứng dụng mà bạn đang duy trì.

Có lẽ tốt nhất nếu bạn đọc Chương 9: Các định nghĩa phương thức của RFC HTTP / 1.1 để có được ý tưởng tổng thể về ý nghĩa ban đầu của GET và POST.


16

Sự khác biệt giữa GET và POST không nên được xem xét về mặt bảo mật, mà là trong ý định của chúng đối với máy chủ. GET không bao giờ nên thay đổi dữ liệu trên máy chủ - ít nhất là ngoài nhật ký - nhưng POST có thể tạo tài nguyên mới.

Các proxy đẹp sẽ không lưu trữ dữ liệu POST, nhưng chúng có thể lưu trữ dữ liệu GET từ URL, vì vậy bạn có thể nói rằng POST được cho là an toàn hơn. Nhưng dữ liệu POST vẫn sẽ có sẵn cho các proxy không chơi tốt.

Như đã đề cập trong nhiều câu trả lời, đặt cược chắc chắn duy nhất là thông qua SSL.

Nhưng hãy đảm bảo rằng các phương thức GET không cam kết bất kỳ thay đổi nào, chẳng hạn như xóa các hàng cơ sở dữ liệu, v.v.


1
Tôi đồng ý với điều này. Câu hỏi không phải là bảo mật, đó là những gì POST và GET được thiết kế để làm.
poustitenbach

6

Phương pháp thông thường của tôi để chọn là một cái gì đó như:

  • NHẬN các mục sẽ được truy xuất sau bằng URL
    • Ví dụ: Tìm kiếm phải là GET để bạn có thể thực hiện search.php? S = XXX sau này
  • POST cho các mục sẽ được gửi
    • Điều này tương đối vô hình được chuyển thành GET và khó gửi hơn, nhưng dữ liệu vẫn có thể được gửi qua cURL.

Nhưng nó khó khăn hơn để làm một POST hơn một GET. GET chỉ là một URL trong hộp địa chỉ. POST yêu cầu <form> trong trang HTML hoặc cURL.
poustitenbach

2
Vì vậy, một bài đăng giả mạo mất notepad và 5 phút thời gian ... không thực sự khó hơn nhiều. Tôi đã sử dụng notepad để thêm các tính năng cho hệ thống điện thoại không tồn tại. Tôi đã có thể tạo một bản sao của các biểu mẫu quản trị viên cho hệ thống cho phép tôi gán các lệnh cho các nút "không thể thực hiện được" theo như nhà cung cấp quan tâm.
Matthew Whited

6

Điều này không liên quan đến bảo mật nhưng ... trình duyệt không lưu các yêu cầu POST .


6

Không ai có thể bảo mật một cách kỳ diệu cho một yêu cầu, tuy nhiên GET ngụ ý một số tác dụng phụ thường khiến nó không được bảo mật.

NHẬN URL hiển thị trong lịch sử trình duyệt và nhật ký máy chủ web. Vì lý do này, chúng không bao giờ được sử dụng cho những thứ như biểu mẫu đăng nhập và số thẻ tín dụng.

Tuy nhiên, chỉ cần POST dữ liệu đó cũng không làm cho nó an toàn. Cho rằng bạn muốn SSL. Cả GET và POST đều gửi dữ liệu trong văn bản gốc qua dây khi được sử dụng qua HTTP.

Cũng có những lý do tốt khác để POST dữ liệu - như khả năng gửi số lượng dữ liệu không giới hạn hoặc ẩn tham số khỏi người dùng thông thường.

Nhược điểm là người dùng không thể đánh dấu kết quả của một truy vấn được gửi qua POST. Đối với điều đó, bạn cần NHẬN.


5

Xem xét tình huống này: API cẩu thả chấp nhận các yêu cầu GET như:

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

Trong một số cài đặt, khi bạn yêu cầu URL này và nếu có lỗi / cảnh báo liên quan đến yêu cầu, toàn bộ dòng này sẽ được ghi vào tệp nhật ký. Tệ hơn nữa: nếu bạn quên tắt thông báo lỗi trong máy chủ sản xuất, thông tin này chỉ được hiển thị rõ ràng trong trình duyệt! Bây giờ bạn vừa đưa khóa API của mình cho mọi người.

Thật không may, có API thực sự hoạt động theo cách này.

Tôi không thích ý tưởng có một số thông tin nhạy cảm trong nhật ký hoặc hiển thị chúng trong trình duyệt. POST và GET không giống nhau. Sử dụng mỗi nơi thích hợp.


3
  1. BẢO MẬT là an toàn của dữ liệu TRÊN CHUYỂN: không có sự khác biệt giữa POST và GET.

  2. BẢO MẬT là an toàn của dữ liệu TRÊN MÁY TÍNH: POST an toàn hơn (không có lịch sử URL)


2

Khái niệm bảo mật là vô nghĩa trừ khi bạn xác định những gì bạn muốn được bảo mật chống lại.

Nếu bạn muốn bảo mật với lịch sử trình duyệt được lưu trữ, một số loại ghi nhật ký và mọi người nhìn vào URL của bạn, thì POST sẽ an toàn hơn.

Nếu bạn muốn an toàn trước ai đó đánh hơi hoạt động mạng của mình, thì không có gì khác biệt.


1

Nhiều người chấp nhận một quy ước (được Ross ám chỉ) rằng các yêu cầu GET chỉ lấy dữ liệu và không sửa đổi bất kỳ dữ liệu nào trên máy chủ và các yêu cầu POST được sử dụng cho tất cả các sửa đổi dữ liệu. Trong khi người ta không phải là vốn an toàn hơn so với khác, nếu bạn làm theo Công ước này, bạn có thể áp dụng logic an ninh xuyên suốt (ví dụ chỉ những người có tài khoản có thể sửa đổi dữ liệu, bài nên không được thẩm định bị từ chối).


4
Trên thực tế, đây không phải là một "quy ước", nó là một phần của tiêu chuẩn HTTP. RFC rất rõ ràng về những gì mong đợi từ các phương pháp khác nhau.
John Nilsson

Trong thực tế, nếu bạn cho phép các yêu cầu GET sửa đổi trạng thái thì có thể trình duyệt đang tìm nạp trước các trang mà nó nghĩ rằng bạn có thể truy cập sẽ vô tình thực hiện các hành động mà bạn không muốn.
Jessta

1

Việc thay đổi yêu cầu POST khó hơn (đòi hỏi nhiều nỗ lực hơn so với chỉnh sửa chuỗi truy vấn). Chỉnh sửa: Nói cách khác, đó chỉ là bảo mật bằng cách tối nghĩa và hầu như không có.


3
Tôi có thể thay đổi các yêu cầu POST dễ dàng như các yêu cầu chuỗi truy vấn, sử dụng một vài tiện ích bổ sung cho Firefox. tôi thậm chí có thể sửa đổi dữ liệu cookie thành nội dung trái tim của tôi.
stephenbayer

Nó sẽ không làm chậm các kiddies script, nó chính xác là loại điều mà các kiddies script luôn cố gắng. Vấn đề là đôi khi họ thành công.
Jacco

2
Ừm Sử dụng addons cho Firefox = nhiều nỗ lực hơn chuỗi truy vấn.
mí mắt

Câu trả lời của bạn sẽ mang lại cho mọi người cảm giác sai lầm rằng họ đang an toàn hơn khi sử dụng một bài đăng, trong khi thực tế, họ thì không. Câu trả lời tồi, người đàn ông xấu.
Chris Marasti-Georg

Tôi chỉnh sửa để làm cho ý định trả lời của tôi rõ ràng hơn. Hy vọng rằng sẽ giúp.
mí mắt

1

Tôi sẽ không lặp lại tất cả các câu trả lời khác, nhưng có một khía cạnh mà tôi chưa thấy đề cập - đó là câu chuyện về dữ liệu biến mất. Tôi không biết tìm nó ở đâu, nhưng ...

Về cơ bản, đó là về một ứng dụng web mà cứ sau vài đêm lại mất hết dữ liệu và không ai biết tại sao. Kiểm tra Nhật ký sau đó tiết lộ rằng trang web được tìm thấy bởi google hoặc một con nhện tùy ý khác, vui vẻ NHẬN (đọc: GOT) tất cả các liên kết tìm thấy trên trang web - bao gồm cả "xóa mục này" và "bạn có chắc không?" liên kết.

Trên thực tế - một phần của điều này đã được đề cập. Đây là câu chuyện đằng sau "không thay đổi dữ liệu trên GET mà chỉ trên POST". Trình thu thập thông tin sẽ vui vẻ theo dõi GET, không bao giờ POST. Ngay cả robot.txt cũng không giúp chống lại các trình thu thập dữ liệu sai.


1

Bạn cũng nên lưu ý rằng nếu các trang web của bạn chứa liên kết đến các trang web bên ngoài khác mà bạn không kiểm soát bằng GET sẽ đưa dữ liệu đó vào tiêu đề của trình giới thiệu trên các trang web bên ngoài khi họ nhấn các liên kết trên trang web của bạn. Vì vậy, chuyển dữ liệu đăng nhập thông qua các phương thức GET luôn luôn là một vấn đề lớn. Vì điều đó có thể làm lộ thông tin đăng nhập để dễ dàng truy cập bằng cách chỉ cần kiểm tra nhật ký hoặc tìm kiếm trong Google Analytics (hoặc tương tự).


1

RFC7231:

"Các URI được dự định chia sẻ, không được bảo mật, ngay cả khi chúng xác định các tài nguyên an toàn. Các URI thường được hiển thị trên màn hình, được thêm vào các mẫu khi một trang được in và được lưu trữ trong một loạt các danh sách đánh dấu không được bảo vệ. thông tin trong một URI nhạy cảm, có thể nhận dạng cá nhân hoặc có nguy cơ bị tiết lộ.

Tác giả của các dịch vụ nên tránh các biểu mẫu dựa trên GET để gửi dữ liệu nhạy cảm vì dữ liệu đó sẽ được đặt trong mục tiêu yêu cầu. Nhiều máy chủ, proxy và tác nhân người dùng hiện có đăng nhập hoặc hiển thị mục tiêu yêu cầu ở những nơi mà bên thứ ba có thể nhìn thấy. Các dịch vụ như vậy phải sử dụng đệ trình biểu mẫu dựa trên POST thay thế. "

RFC này nêu rõ rằng dữ liệu nhạy cảm không nên được gửi bằng GET. Do nhận xét này, một số người triển khai có thể không xử lý dữ liệu thu được từ phần truy vấn của yêu cầu GET với cùng một sự chăm sóc. Tôi đang làm việc trên một giao thức tự đảm bảo tính toàn vẹn của dữ liệu. Theo thông số kỹ thuật này, tôi không cần phải đảm bảo tính toàn vẹn của dữ liệu GET (điều này tôi sẽ làm vì không ai tuân thủ các thông số kỹ thuật này)


1

Như trước đây một số người đã nói, HTTPS mang lại bảo mật.

Tuy nhiên, POST an toàn hơn một chút so với GET vì GET có thể được lưu trữ trong lịch sử.

Nhưng thậm chí nhiều hơn, đáng buồn thay, đôi khi việc bầu chọn POST hoặc GET không phụ thuộc vào nhà phát triển. Ví dụ: một siêu liên kết luôn được gửi bằng GET (trừ khi nó được chuyển thành dạng bài đăng bằng cách sử dụng javascript).


0

GET có thể hiển thị cho bất kỳ ai (ngay cả người trên vai bạn bây giờ) và được lưu trên bộ đệm, do đó không an toàn khi sử dụng bài đăng, btw đăng mà không có một số thói quen mã hóa không chắc chắn, vì một chút bảo mật bạn đã sử dụng SSL ( https)


0

Một lý do POST tệ hơn để bảo mật là GET được ghi theo mặc định, các tham số và tất cả dữ liệu hầu như được ghi lại bởi máy chủ web của bạn.

POST thì ngược lại , nó hầu như không được đăng nhập , dẫn đến rất khó phát hiện ra hoạt động của kẻ tấn công.

Tôi không mua đối số "nó quá lớn", không có lý do gì để không đăng nhập bất cứ thứ gì , ít nhất là 1KB, sẽ đi một chặng đường dài để mọi người xác định những kẻ tấn công làm việc tại một điểm vào yếu cho đến khi nó xuất hiện, sau đó POST một dịch vụ kép, bằng cách cho phép bất kỳ cửa sau dựa trên HTTP nào âm thầm truyền lượng dữ liệu không giới hạn.


0

Sự khác biệt là GET gửi dữ liệu mở và POST ẩn (trong tiêu đề http).

Vì vậy, get là tốt hơn cho dữ liệu không an toàn, như chuỗi truy vấn trong Google. Dữ liệu xác thực sẽ không bao giờ được gửi qua GET - vì vậy hãy sử dụng POST tại đây. Tất nhiên toàn bộ chủ đề phức tạp hơn một chút. Nếu bạn muốn đọc thêm, hãy đọc bài viết này (bằng tiếng Đức).


0

Gần đây, một cuộc tấn công đã được công bố, cho phép người đàn ông ở giữa tiết lộ cơ thể yêu cầu của các yêu cầu HTTPS được nén. Vì các tiêu đề yêu cầu và URL không được nén bởi HTTP, nên các yêu cầu GET được bảo mật tốt hơn trước cuộc tấn công cụ thể này.

Có các chế độ trong đó các yêu cầu GET cũng dễ bị tổn thương, SPDY nén các tiêu đề yêu cầu, TLS cũng cung cấp một nén tùy chọn (hiếm khi được sử dụng). Trong các trường hợp này, cuộc tấn công dễ dàng hơn để ngăn chặn (các nhà cung cấp trình duyệt đã cung cấp các bản sửa lỗi). Nén mức HTTP là một tính năng cơ bản hơn, không chắc là các nhà cung cấp sẽ vô hiệu hóa nó.

Đây chỉ là một ví dụ cho thấy một kịch bản trong đó GET an toàn hơn POST, nhưng tôi không nghĩ nên chọn GET qua POST từ lý do tấn công này. Cuộc tấn công khá tinh vi và đòi hỏi những điều kiện tiên quyết không tầm thường (Attacker cần có khả năng kiểm soát một phần nội dung yêu cầu). Tốt hơn là vô hiệu hóa nén HTTP trong các tình huống mà cuộc tấn công sẽ có hại.


0

Tuyên bố miễn trừ trách nhiệm: Các điểm sau chỉ được áp dụng cho các lệnh gọi API và không áp dụng cho các URL của trang web.

Bảo mật qua mạng : Bạn phải sử dụng HTTPS. GET và POST đều an toàn như nhau trong trường hợp này.

Lịch sử trình duyệt : Đối với các ứng dụng front-end như, Angular JS, React JS, vv Các lệnh gọi API là các cuộc gọi AJAX được thực hiện bởi front-end. Đây không phải là một phần của lịch sử trình duyệt. Do đó, POST và GET đều an toàn như nhau.

Nhật ký phía máy chủ : Với việc sử dụng bộ ghi dữ liệu che dấu dữ liệu và định dạng nhật ký truy cập, có thể ẩn tất cả hoặc chỉ dữ liệu nhạy cảm khỏi URL yêu cầu.

Khả năng hiển thị dữ liệu trong bảng điều khiển trình duyệt: Đối với người có ý định hay ho, gần như cùng nỗ lực để xem dữ liệu POST nhiều như GET.

Do đó, với thực tiễn ghi nhật ký đúng, GET API an toàn như POST API. Theo dõi POST ở mọi nơi, buộc các định nghĩa API kém và nên tránh.


-2

Bài đăng được bảo mật nhất cùng với SSL được cài đặt vì nó được truyền trong phần thân thông điệp.

Nhưng tất cả các phương thức này đều không an toàn vì giao thức 7 bit mà nó sử dụng bên dưới nó có khả năng hack với sự thoát. Thậm chí thông qua một tường lửa ứng dụng web cấp 4.

Ổ cắm cũng không đảm bảo ... Mặc dù nó an toàn hơn theo những cách nhất định.


-3

Đây là một bài viết cũ, nhưng tôi muốn phản đối một số câu trả lời. Nếu bạn đang chuyển dữ liệu nhạy cảm, bạn sẽ muốn sử dụng SSL. Nếu bạn sử dụng SSL với tham số GET (ví dụ: userid = 123), dữ liệu đó sẽ được gửi bằng văn bản thuần túy! Nếu bạn gửi bằng POST, các giá trị sẽ được đặt trong phần thân được mã hóa của tin nhắn và do đó không thể đọc được đối với hầu hết các cuộc tấn công MITM.

Sự khác biệt lớn là nơi dữ liệu được thông qua. Điều này chỉ có nghĩa là nếu dữ liệu được đặt trong một URL, nó không thể được mã hóa nếu không bạn sẽ không thể định tuyến đến máy chủ vì chỉ bạn mới có thể đọc URL. Đó là cách một GET hoạt động.

Nói tóm lại, bạn có thể truyền dữ liệu một cách an toàn trong POST qua SSL, nhưng bạn không thể làm như vậy với GET, sử dụng SSL hay không.


4
Điều này là hoàn toàn sai sự thật. SSL là một giao thức lớp vận chuyển. Nó kết nối với máy chủ FIRST, sau đó gửi TẤT CẢ dữ liệu Ứng dụng dưới dạng luồng dữ liệu nhị phân được mã hóa. Kiểm tra chủ đề này: answer.google.com/answers/threadview/id/758002.html
Simeon G

Thực hiện TCPDump và bạn sẽ thấy điều này đúng 100%. Để kết nối với máy chủ, bạn phải gửi yêu cầu của mình không được mã hóa. Nếu bạn làm điều đó như một GET, các đối số của bạn sẽ được thêm vào yêu cầu ban đầu và do đó không được mã hóa. Bất kể những gì bạn thấy trong bài đăng bạn đã liên kết, bạn có thể kiểm tra điều này với TCPDump (hoặc tương tự).
LVM

1
Làm xong! Chỉ cần chạy tcpdump trên máy Mac của tôi. Và câu trả lời của bạn đã đưa ra 100% sai. Đây là lệnh tôi đã sử dụng: sudo tcpdump -w ssl.data -A -i en1 -n dst port 443 Sau đó, khi tôi nhìn vào ssl.data, dĩ nhiên tôi thấy gookly gookly. Tất cả dữ liệu HTTP đã được mã hóa. Và để đảm bảo một cuộc gọi không ssl bình thường hoạt động, tôi đã sử dụng: sudo tcpdump -w clear.data -A -i en1 -n dst port 80 Và chắc chắn, bên trong Clear.data tôi có tất cả các tiêu đề và URI hiển thị rõ ràng . Tôi đã thử nghiệm điều này trên gmail và google plus (là HTTPS) và trên một số trang không phải SSL như google.com.
Simeon G

Tôi không phải là chuyên gia mạng vì vậy nếu bạn nghĩ rằng tôi đã sử dụng các lệnh sai trên tcpdump, vui lòng sửa cho tôi.
Simeon G

Tôi không có lệnh trực tiếp, nhưng bạn cũng có thể kiểm tra nó bằng Wireshark / Ethereal.
LVM

-3

Ngay cả POST cũng chấp nhận các yêu cầu GET. Giả sử bạn có một biểu mẫu có đầu vào như user.name và user.passwd, những biểu mẫu được cho là hỗ trợ tên người dùng và mật khẩu. Nếu chúng ta chỉ cần thêm một? User.name = "user & user.passwd =" mật khẩu của tôi ", thì yêu cầu sẽ được chấp nhận bằng cách" bỏ qua trang đăng nhập ".

Một giải pháp cho việc này là triển khai các bộ lọc (bộ lọc java dưới dạng e) ở phía máy chủ và phát hiện không có truy vấn chuỗi nào được chuyển dưới dạng đối số GET.


2
Không đúng! Điều này phụ thuộc hoàn toàn vào phần phụ trợ của bạn về việc liệu mã chấp nhận POST cũng chấp nhận GET.
Colin 't Hart
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.