Apakah GET atau POST lebih aman daripada yang lain?

282

Ketika membandingkan GET HTTP dengan POST HTTP, apa perbedaan dari perspektif keamanan? Apakah salah satu pilihan secara inheren lebih aman daripada yang lain? Jika demikian, mengapa?

Saya menyadari bahwa POST tidak mengekspos informasi pada URL, tetapi apakah ada nilai nyata dalam hal itu atau itu hanya keamanan melalui ketidakjelasan? Adakah alasan mengapa saya harus memilih POST ketika keamanan menjadi perhatian?

Sunting:
Lebih dari HTTPS, data POST disandikan, tetapi bisakah URL diendus oleh pihak ketiga? Selain itu, saya berurusan dengan JSP; ketika menggunakan JSP atau kerangka kerja serupa, apakah adil untuk mengatakan praktik terbaik adalah menghindari menempatkan data sensitif dalam POST atau GET sama sekali dan menggunakan kode sisi server untuk menangani informasi sensitif?

James McMahon
sumber
1
Ada entri blog yang bagus tentang ini di blog Jeff Coding Horror: Cross-Site Request Forgeries and You .
fhe
Bukankah Anda menggunakan POST untuk sebagian besar hal. Misalnya untuk API, katakan Anda perlu MENDAPATKAN data dari DB, tetapi sebelum server mengembalikan data Anda harus diautentikasi terlebih dahulu? Dengan menggunakan pos, Anda hanya akan melewatkan ID sesi Anda + semua parameter yang Anda butuhkan untuk permintaan tersebut. Jika Anda menggunakan GET req untuk ini maka ID sesi Anda dapat dengan mudah ditemukan di riwayat peramban Anda atau di suatu tempat di tengah.
James111
Saya ingat diskusi ini dari sebelum perang (99 'atau '00 atau lebih) ketika https tidak lazim.
David Tonhofer
@ DavidTonhofer, perang apa yang Anda maksud? Perang browser?
DeltaFlyer
@DeltaFlyer Tidak, the Forever War on Stuff, alias GWOT. Apa yang telah kita lakukan.
David Tonhofer

Jawaban:

206

Sejauh keamanan, mereka secara inheren sama. Meskipun benar bahwa POST tidak mengekspos informasi melalui URL, POST memaparkan informasi sebanyak GET dalam komunikasi jaringan aktual antara klien dan server. Jika Anda perlu menyampaikan informasi yang sensitif, garis pertahanan pertama Anda adalah meneruskannya menggunakan Secure HTTP.

DAPATKAN atau posting string kueri benar-benar bagus untuk informasi yang diperlukan baik untuk penunjuk item tertentu, atau untuk membantu dalam optimasi mesin pencari dan pengindeksan item.

POST baik untuk formulir standar yang digunakan untuk mengirim data satu kali. Saya tidak akan menggunakan GET untuk memposting formulir yang sebenarnya, kecuali mungkin dalam bentuk pencarian di mana Anda ingin mengizinkan pengguna untuk menyimpan kueri di bookmark, atau sesuatu di sepanjang baris itu.

stephenbayer
sumber
5
Dengan peringatan bahwa untuk GET, URL yang ditampilkan di bilah lokasi dapat memaparkan data yang akan disembunyikan dalam POST.
tvanfosson
93
Ini disembunyikan hanya dalam arti yang paling naif
davetron5000
7
benar, tetapi Anda juga dapat mengatakan bahwa keyboard tidak aman karena seseorang dapat melihat dari balik bahu Anda saat Anda mengetik kata sandi. Ada sangat sedikit perbedaan antara keamanan melalui ketidakjelasan dan tidak ada keamanan sama sekali.
stephenbayer
65
Visibilitas (dan caching) dari querystrings di URL dan dengan demikian kotak alamat jelas kurang aman. Tidak ada yang namanya keamanan absolut sehingga tingkat keamanan relevan.
pbreitenbach
6
bahkan terpapar jika Anda menggunakan pos. dalam kasus Anda, pos akan sedikit lebih aman. Tapi serius .. Saya bisa mengubah variabel posting sepanjang hari, semudah mendapatkan variabel. Cookie bahkan dapat dilihat dan dimodifikasi .. tidak pernah bergantung pada informasi yang dikirim situs Anda dengan cara atau bentuk apa pun. Semakin banyak keamanan yang Anda butuhkan, semakin banyak metode verifikasi yang harus Anda miliki.
stephenbayer
428

Permintaan GET sedikit kurang aman dibandingkan permintaan POST. Tidak ada yang menawarkan "keamanan" sejati dengan sendirinya; menggunakan permintaan POST tidak akan secara ajaib membuat situs web Anda aman terhadap serangan jahat dengan jumlah yang nyata. Namun, menggunakan permintaan GET dapat membuat aplikasi yang tidak aman menjadi tidak aman.

Mantra yang Anda "tidak boleh menggunakan permintaan GET untuk melakukan perubahan" masih sangat valid, tetapi ini tidak ada hubungannya dengan perilaku jahat . Formulir login adalah yang paling sensitif untuk dikirim menggunakan jenis permintaan yang salah.

Cari spider dan akselerator web

Inilah alasan sebenarnya Anda harus menggunakan permintaan POST untuk mengubah data. Laba-laba pencarian akan mengikuti setiap tautan di situs web Anda, tetapi tidak akan mengirimkan formulir acak yang mereka temukan.

Akselerator web lebih buruk daripada laba-laba pencarian, karena dijalankan pada mesin klien, dan "klik" semua tautan dalam konteks pengguna yang masuk . Dengan demikian, aplikasi yang menggunakan permintaan GET untuk menghapus hal-hal, bahkan jika itu memerlukan administrator, dengan senang hati akan mematuhi perintah akselerator web (tidak berbahaya!) Dan menghapus semua yang dilihatnya .

Deputi serangan bingung

Sebuah wakil serangan bingung (di mana wakil adalah browser) adalah mungkin terlepas dari apakah Anda menggunakan GET atau permintaan POST .

Di situs web yang dikontrol oleh penyerang, GET dan POST sama mudah dikirim tanpa interaksi pengguna .

Satu-satunya skenario di mana POST sedikit kurang rentan adalah bahwa banyak situs web yang tidak di bawah kendali penyerang (katakanlah, forum pihak ketiga) memungkinkan penyisipan gambar sewenang-wenang (memungkinkan penyerang untuk menyuntikkan permintaan GET sewenang-wenang), tetapi mencegah semua cara menyuntikkan permintaan POST arbiter, baik otomatis atau manual.

Orang mungkin berpendapat bahwa akselerator web adalah contoh serangan wakil bingung, tapi itu hanya masalah definisi. Jika ada, penyerang berbahaya tidak memiliki kontrol atas ini, sehingga hampir tidak serangan , bahkan jika wakil yang bingung.

Log proxy

Server proxy cenderung mencatat URL GET secara keseluruhan, tanpa menghapus string kueri. Parameter permintaan POST biasanya tidak dicatat. Cookie tidak mungkin masuk dalam kedua kasus ini. (contoh)

Ini adalah argumen yang sangat lemah dalam mendukung POST. Pertama, lalu lintas yang tidak dienkripsi dapat dicatat secara keseluruhan; proxy jahat sudah memiliki semua yang dibutuhkannya. Kedua, parameter permintaan terbatas digunakan untuk penyerang: apa yang sebenarnya mereka butuhkan adalah cookie, jadi jika satu-satunya yang mereka miliki adalah log proxy, mereka tidak mungkin dapat menyerang URL GET atau POST.

Ada satu pengecualian untuk permintaan login: ini cenderung mengandung kata sandi pengguna. Menyimpan ini di log proksi membuka vektor serangan yang tidak ada dalam kasus POST. Namun, login melalui HTTP biasa secara inheren tidak aman.

Cache proksi

Caching proxy mungkin menyimpan respons GET, tetapi bukan respons POST. Karena itu, respons GET dapat dibuat non-cacheable dengan sedikit usaha daripada mengonversi URL ke POST handler.

HTTP "Referer"

Jika pengguna menavigasi ke situs web pihak ketiga dari halaman yang disajikan sebagai tanggapan terhadap permintaan GET, situs web pihak ketiga tersebut dapat melihat semua parameter permintaan GET.

Milik kategori "mengungkapkan parameter permintaan ke pihak ketiga", yang tingkat keparahannya tergantung pada apa yang ada pada parameter tersebut. Permintaan POST secara alami kebal terhadap ini, namun untuk mengeksploitasi permintaan GET, peretas perlu memasukkan tautan ke situs web mereka sendiri ke dalam respons server.

Riwayat peramban

Ini sangat mirip dengan argumen "log proksi": Permintaan GET disimpan dalam riwayat peramban beserta parameternya. Penyerang dapat dengan mudah memperoleh ini jika mereka memiliki akses fisik ke mesin.

Tindakan menyegarkan peramban

Peramban akan mencoba kembali permintaan GET segera setelah pengguna menekan "menyegarkan". Mungkin melakukannya ketika mengembalikan tab setelah dimatikan. Tindakan apa pun (katakanlah, pembayaran) dengan demikian akan diulang tanpa peringatan.

Browser tidak akan mencoba lagi permintaan POST tanpa peringatan.

Ini adalah alasan yang baik untuk menggunakan hanya permintaan POST untuk mengubah data, tetapi tidak ada hubungannya dengan perilaku jahat dan, karenanya, keamanan.

Jadi apa yang harus aku lakukan?

  • Gunakan hanya permintaan POST untuk mengubah data, terutama karena alasan yang tidak terkait keamanan.
  • Gunakan hanya permintaan POST untuk formulir login; melakukan sebaliknya memperkenalkan vektor serangan.
  • Jika situs Anda melakukan operasi sensitif, Anda benar-benar membutuhkan seseorang yang tahu apa yang mereka lakukan, karena ini tidak dapat dicakup dalam satu jawaban. Anda perlu menggunakan HTTPS, HSTS, CSP, mitigasi injeksi SQL, injeksi skrip (XSS) , CSRF , dan banyak hal lain yang mungkin spesifik untuk platform Anda (seperti kerentanan penugasan massal dalam berbagai kerangka kerja: ASP.NET MVC , Ruby on Rails , dll.) Tidak ada satu hal pun yang akan membuat perbedaan antara "aman" (tidak dapat dieksploitasi) dan "tidak aman".

Lebih dari HTTPS, data POST disandikan, tetapi bisakah URL diendus oleh pihak ketiga?

Tidak, mereka tidak bisa diendus. Tetapi URL akan disimpan dalam riwayat browser.

Apakah adil untuk mengatakan praktik terbaik adalah menghindari kemungkinan menempatkan data sensitif dalam POST atau GET sama sekali dan menggunakan kode sisi server untuk menangani informasi sensitif?

Bergantung pada seberapa sensitifnya itu, atau lebih khusus lagi, dengan cara apa. Jelas klien akan melihatnya. Siapa pun yang memiliki akses fisik ke komputer klien akan melihatnya. Klien dapat menipu itu ketika mengirimkannya kembali kepada Anda. Jika itu penting maka ya, simpan data sensitif di server dan jangan biarkan itu pergi.

Roman Starkov
sumber
29
ahem, CSRF hanya mungkin dengan POST.
AviD
5
@Lotus Notes, ini sedikit lebih sulit, tetapi Anda tidak memerlukan XSS apa pun. Permintaan POST dikirim sepanjang waktu di semua tempat, dan jangan lupa bahwa CSRF dapat diambil dari situs web mana pun , XSS tidak termasuk.
AviD
18
tidak, Anda harus membuat orang lain dengan hak istimewa untuk mengetiknya, sebagai lawan dari GET yang akan diambil secara diam-diam oleh browser. mengingat bahwa setiap formulir POST harus dilindungi dengan hash sumber yang dapat diverifikasi, dan tidak ada sarana untuk tautan GET, maksud Anda konyol.
Kibitzer
7
Nah, Anda bisa menambahkan hash ke semua permintaan GET Anda persis dengan cara yang sama Anda menambahkannya ke formulir POST ... Tapi Anda tetap tidak boleh menggunakan GET untuk apa pun yang memodifikasi data.
Eli
13
Menggunakan POST melalui GET tidak mencegah CSRF apa pun. Itu hanya membuat mereka sedikit lebih mudah untuk dilakukan, karena lebih mudah untuk membuat orang pergi ke situs web acak yang memungkinkan gambar dari url, daripada pergi ke situs web yang Anda kontrol (cukup untuk memiliki javascript). Melakukannya <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>tidak terlalu sulit untuk mengirim kiriman di suatu tempat secara otomatis dengan mengklik tautan (yang berisi html itu)
FryGuy
175

Anda tidak memiliki keamanan yang lebih besar yang disediakan karena variabel dikirim melalui HTTP POST daripada Anda dengan variabel yang dikirim melalui HTTP GET.

HTTP / 1.1 memberi kami banyak metode untuk mengirim permintaan :

  • PILIHAN
  • DAPATKAN
  • KEPALA
  • POS
  • TARUH
  • MENGHAPUS
  • JEJAK
  • MENGHUBUNG

Mari kita anggap Anda memiliki dokumen HTML berikut menggunakan 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>

Apa yang ditanyakan browser Anda? Ia menanyakan ini:

 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

Sekarang mari kita berpura-pura kita mengubah metode permintaan itu menjadi 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

KEDUA dari permintaan HTTP ini adalah:

  • Tidak dienkripsi
  • Termasuk dalam kedua contoh
  • Dapat diganggu, dan menjadi sasaran serangan MITM.
  • Mudah direproduksi oleh pihak ketiga, dan skrip bot.

Banyak browser yang tidak mendukung metode HTTP selain POST / GET.

Banyak perilaku browser menyimpan alamat halaman, tetapi ini tidak berarti Anda dapat mengabaikan salah satu dari masalah lain ini.

Jadi lebih spesifik:

Apakah satu secara inheren lebih aman daripada yang lain? Saya menyadari bahwa POST tidak mengekspos informasi pada URL tetapi apakah ada nilai nyata dalam hal itu atau itu hanya keamanan melalui ketidakjelasan? Apa praktik terbaik di sini?

Ini benar, karena perangkat lunak yang Anda gunakan untuk berbicara HTTP cenderung menyimpan variabel permintaan dengan satu metode tetapi tidak yang lain hanya mencegah seseorang untuk melihat riwayat browser Anda atau serangan naif lainnya dari anak berusia 10 tahun yang berpikir mereka mengerti h4x0r1ng , atau skrip yang memeriksa penyimpanan riwayat Anda. Jika Anda memiliki skrip yang dapat memeriksa toko riwayat Anda, Anda bisa dengan mudah memiliki skrip yang memeriksa lalu lintas jaringan Anda, sehingga seluruh keamanan melalui ketidakjelasan ini hanya menyediakan ketidakjelasan untuk skrip kiddies dan pacar yang cemburu.

Lebih dari https, data POST dikodekan, tetapi bisakah url disadap oleh pihak ke-3?

Inilah cara kerja SSL. Ingat dua permintaan yang saya kirim di atas? Begini tampilannya di SSL: (Saya mengubah halaman menjadi https://encrypted.google.com/ sebagai example.com tidak merespons pada SSL).

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

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

(catatan: Saya mengonversi HEX ke ASCII, beberapa di antaranya jelas tidak dapat ditampilkan)

Seluruh percakapan HTTP dienkripsi, satu-satunya bagian komunikasi yang terlihat adalah pada lapisan TCP / IP (artinya alamat IP dan informasi port koneksi).

Jadi izinkan saya membuat pernyataan berani yang besar di sini. Situs web Anda tidak diberikan keamanan yang lebih besar dari satu metode HTTP daripada yang lain, peretas dan pemula di seluruh dunia tahu persis bagaimana melakukan apa yang baru saja saya tunjukkan di sini. Jika Anda menginginkan keamanan, gunakan SSL. Browser cenderung menyimpan histori, disarankan oleh RFC2616 9.1.1 untuk TIDAK menggunakan GET untuk melakukan suatu tindakan, tetapi berpikir bahwa POST memberikan keamanan sama sekali salah.

Satu-satunya hal yang POST lakukan adalah langkah pengamanan? Perlindungan terhadap mantan cemburu Anda yang membalik-balik riwayat peramban Anda. Itu dia. Seluruh dunia login ke akun Anda menertawakan Anda.

Untuk lebih mendemonstrasikan mengapa POST tidak aman, Facebook menggunakan permintaan POST di semua tempat, jadi bagaimana perangkat lunak seperti FireSheep ada?

Perhatikan bahwa Anda mungkin diserang dengan CSRF bahkan jika Anda menggunakan HTTPS dan situs Anda tidak mengandung kerentanan XSS . Singkatnya, skenario serangan ini mengasumsikan bahwa korban (pengguna situs atau layanan Anda) sudah masuk dan memiliki cookie yang tepat dan kemudian browser korban diminta untuk melakukan sesuatu dengan situs Anda (yang seharusnya aman). Jika Anda tidak memiliki perlindungan terhadap CSRF, penyerang masih dapat melakukan tindakan dengan kredensial korban. Penyerang tidak dapat melihat respons server karena itu akan ditransfer ke browser korban tetapi kerusakan biasanya sudah dilakukan pada saat itu.

Incognito
sumber
1
Sayang sekali Anda tidak berbicara tentang CSRF :-). Apakah ada cara untuk menghubungi Anda?
Florian Margaine
@FlorianMargaine Tambahkan saya di twitter dan saya akan memberi Anda email saya. twitter.com/#!/BrianJGraham
Incognito
Siapa bilang Facebook aman? Jawaban yang bagus. +1.
Amal Murali
1
"[...] jadi seluruh keamanan ini melalui ketidakjelasan hanya memberikan ketidakjelasan untuk skrip kiddies dan pacar cemburu. [...]". ini sepenuhnya tergantung pada keterampilan gf yang cemburu. Selain itu, gf / bf tidak boleh diizinkan untuk mengunjungi riwayat browser Anda. pernah. lol.
turkishweb
34

Tidak ada keamanan tambahan.

Data posting tidak muncul dalam riwayat dan / atau file log tetapi jika data harus tetap aman, Anda memerlukan SSL.
Kalau tidak, siapa pun yang menghirup kawat dapat membaca data Anda.

Jacco
sumber
2
jika Anda MENDAPATKAN URL melalui SSL, pihak ketiga tidak akan dapat melihat URL, sehingga keamanannya sama
davetron5000
7
Informasi GET hanya dapat dilihat di awal dan akhir terowongan SSL
Jacco
1
Dan sistem admin ketika mereka melihat file log.
Tomalak
1
Saya akan mengatakan ada beberapa keamanan tambahan bahwa data POST tidak akan disimpan dalam riwayat browser pengguna, tetapi GET data akan.
Kip
3
HTTP over SSL / TLS (diimplementasikan dengan benar) memungkinkan penyerang mengendus kabel (atau secara aktif merusak) untuk melihat hanya dua hal - alamat IP tujuan, dan jumlah data berjalan dua arah.
Aaron
29

Bahkan jika POSTtidak memberikan manfaat keamanan nyata dibandingkan GET, untuk formulir masuk atau bentuk lainnya dengan informasi yang relatif sensitif, pastikan Anda menggunakan POSTsebagai:

  1. Informasi POSTed tidak akan disimpan dalam riwayat pengguna.
  2. Informasi sensitif (kata sandi, dll.) Yang dikirim dalam formulir tidak akan terlihat kemudian di bilah URL (dengan menggunakan GET, itu akan terlihat di riwayat dan bilah URL).

Juga, GETmemiliki batasan data teoritis. POSTtidak.

Untuk info sensitif nyata, pastikan untuk menggunakan SSL( HTTPS)

Andrew Moore
sumber
Dalam pengaturan default, setiap kali saya memasukkan nama pengguna dan kata sandi di firefox / IE, ia bertanya apakah saya ingin menyimpan informasi ini, khususnya sehingga saya tidak perlu mengetiknya nanti.
Kibbee
Andrew Saya pikir maksudnya adalah pelengkapan otomatis pada bidang input pengguna. Misalnya, Firefox mengingat semua data yang saya masukkan di situs web saya, jadi ketika saya mulai mengetik teks ke dalam kotak pencarian, ia akan menawarkan untuk melengkapi teks dengan pencarian saya sebelumnya.
James McMahon
Ya, well, itulah gunanya melengkapi otomatis, bukan. Yang saya maksud adalah sejarah sebenarnya, bukan pelengkapan otomatis.
Andrew Moore
Jika penyerang dapat mengakses riwayat peramban lengkap, ia juga memiliki akses ke data lengkap peramban otomatis.
Mikko Rantalainen
19

Tak satu pun dari GET dan POST secara inheren "lebih aman" daripada yang lain, sama seperti tak satu pun dari faks dan telepon "lebih aman" daripada yang lain. Berbagai metode HTTP disediakan sehingga Anda dapat memilih salah satu yang paling sesuai untuk masalah yang Anda coba selesaikan. GET lebih tepat untuk permintaan idempoten sementara POST lebih cocok untuk permintaan "tindakan", tetapi Anda bisa menembak diri sendiri dengan mudah dengan salah satu dari mereka jika Anda tidak memahami arsitektur keamanan untuk aplikasi yang Anda pertahankan.

Ini mungkin yang terbaik jika Anda membaca Bab 9: Metode Definisi dari HTTP / 1.1 RFC untuk mendapatkan ide keseluruhan dari apa GET dan POST awalnya dibayangkan ot berarti.

Mihai Limbășan
sumber
16

Perbedaan antara GET dan POST seharusnya tidak dilihat dalam hal keamanan, tetapi lebih pada niat mereka terhadap server. GET jangan pernah mengubah data di server - setidaknya selain di log - tetapi POST dapat membuat sumber daya baru.

Proxy yang bagus tidak akan men-cache data POST, tetapi mereka bisa men-cache data GET dari URL, sehingga Anda bisa mengatakan bahwa POST seharusnya lebih aman. Tetapi data POST masih akan tersedia untuk proksi yang tidak bermain dengan baik.

Seperti yang disebutkan dalam banyak jawaban, satu-satunya taruhan pasti adalah melalui SSL.

Tapi JANGAN memastikan bahwa metode GET tidak melakukan perubahan apa pun, seperti menghapus baris basis data, dll.

ruquay
sumber
1
Saya setuju dengan ini. Pertanyaannya bukan keamanan, POST dan GET dirancang untuk melakukan apa.
pbreitenbach
6

Metodologi biasa saya untuk memilih adalah sesuatu seperti:

  • DAPATKAN untuk item yang akan diambil nanti dengan URL
    • Misalnya Pencarian harus DAPATKAN sehingga Anda dapat melakukan search.php? S = XXX nanti
  • POST untuk barang yang akan dikirim
    • Ini relatif tidak terlihat dibuat untuk MENDAPATKAN dan lebih sulit untuk dikirim, tetapi data masih dapat dikirim melalui cURL.
Ross
sumber
Tapi itu adalah sulit untuk melakukan POST dari GET. GET hanyalah sebuah URL di kotak alamat. POST memerlukan <form> di halaman HTML atau cURL.
pbreitenbach
2
Jadi posting palsu membutuhkan notepad dan 5 menit ... tidak terlalu sulit. Saya telah menggunakan notepad untuk menambahkan fitur ke sistem telepon yang tidak ada. Saya dapat membuat salinan formulir admin untuk sistem yang akan memungkinkan saya untuk menetapkan perintah ke tombol yang "tidak mungkin" sejauh menyangkut vendor.
Matthew Whited
6

Ini tidak terkait keamanan tetapi ... browser tidak men-cache permintaan POST .

Daniel Silveira
sumber
6

Tidak ada yang secara ajaib menganugerahkan keamanan pada permintaan, namun GET menyiratkan beberapa efek samping yang umumnya mencegah keamanan.

Dapatkan URL muncul di riwayat browser dan log server web. Untuk alasan ini, mereka tidak boleh digunakan untuk hal-hal seperti formulir masuk dan nomor kartu kredit.

Namun, hanya POSTING bahwa data tidak membuatnya aman juga. Untuk itu Anda menginginkan SSL. Baik GET dan POST mengirim data dalam bentuk plaintext melalui kabel saat digunakan melalui HTTP.

Ada juga alasan bagus lainnya untuk data POST - seperti kemampuan untuk mengirimkan data dalam jumlah tidak terbatas, atau menyembunyikan parameter dari pengguna biasa.

Kelemahannya adalah bahwa pengguna tidak dapat mem-bookmark hasil kueri yang dikirim melalui POST. Untuk itu, Anda perlu DAPATKAN.

edebill
sumber
5

Pertimbangkan situasi ini: API yang ceroboh menerima permintaan GET seperti:

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

Dalam beberapa pengaturan, ketika Anda meminta URL ini dan jika ada kesalahan / peringatan mengenai permintaan tersebut, seluruh baris ini akan dicatat dalam file log. Lebih buruk lagi: jika Anda lupa untuk menonaktifkan pesan kesalahan di server produksi, informasi ini hanya ditampilkan secara sederhana di browser! Sekarang Anda baru saja memberikan kunci API Anda kepada semua orang.

Sayangnya, ada API nyata yang bekerja dengan cara ini.

Saya tidak akan menyukai gagasan memiliki beberapa informasi sensitif di log atau menampilkannya di browser. POST dan GET tidak sama. Gunakan masing-masing yang sesuai.

Halil Özgür
sumber
3
  1. KEAMANAN sebagai keamanan data DI TRANSIT: tidak ada perbedaan antara POST dan GET.

  2. KEAMANAN sebagai keamanan data PADA KOMPUTER: POST lebih aman (tidak ada riwayat URL)

kashmiri
sumber
2

Gagasan keamanan tidak ada artinya kecuali Anda mendefinisikan apa yang ingin Anda amankan.

Jika Anda ingin aman dari riwayat browser yang tersimpan, beberapa jenis pencatatan, dan orang-orang yang melihat URL Anda, maka POST lebih aman.

Jika Anda ingin merasa aman terhadap seseorang yang mengendus aktivitas jaringan Anda, maka tidak ada perbedaan.

Taymon
sumber
1

Banyak orang mengadopsi konvensi (disinggung oleh Ross) bahwa permintaan GET hanya mengambil data, dan tidak memodifikasi data apa pun di server, dan permintaan POST digunakan untuk semua modifikasi data. Sementara satu tidak lebih inheren mengamankan daripada yang lain, jika Anda melakukan mengikuti konvensi ini, Anda dapat menerapkan cross-cutting logika keamanan (misalnya hanya orang dengan account dapat memodifikasi data, POSTS sehingga tidak berkepentingan ditolak).

Eric R. Rath
sumber
4
Sebenarnya ini bukan "konvensi" itu bagian dari standar HTTP. RFC sangat eksplisit dalam hal apa yang diharapkan dari berbagai metode.
John Nilsson
Bahkan jika Anda mengizinkan GET permintaan untuk mengubah keadaan maka mungkin saja browser yang mengambil halaman sebelumnya yang menurutnya akan Anda kunjungi secara tidak sengaja akan mengambil tindakan yang tidak Anda inginkan.
Jessta
1

Lebih sulit untuk mengubah permintaan POST (membutuhkan lebih banyak upaya daripada mengedit string kueri). Sunting: Dengan kata lain, itu hanya keamanan karena ketidakjelasan, dan hampir tidak.

kelopak mata
sumber
3
Saya dapat mengubah permintaan POST semudah permintaan string permintaan, menggunakan beberapa tambahan untuk Firefox. saya bahkan dapat mengubah data cookie ke konten hatiku.
stephenbayer
itu tidak akan memperlambat skrip kiddies, itu persis jenis hal skrip kiddies coba sepanjang waktu. Masalahnya adalah mereka terkadang berhasil.
Jacco
2
Uh. Menggunakan addons untuk Firefox = lebih banyak upaya daripada string kueri.
kelopak mata
Jawaban Anda akan memberi orang perasaan palsu bahwa mereka lebih aman saat menggunakan pos, padahal sebenarnya tidak. Jawaban buruk, orang jahat.
Chris Marasti-Georg
Saya mengedit untuk membuat maksud jawaban saya lebih jelas. Semoga itu bisa membantu.
kelopak mata
1

Saya tidak akan mengulangi semua jawaban lainnya, tetapi ada satu aspek yang belum saya lihat disebutkan - ini adalah kisah hilangnya data. Saya tidak tahu di mana menemukannya, tapi ...

Pada dasarnya ini tentang aplikasi web yang secara misterius setiap beberapa malam kehilangan semua datanya dan tidak ada yang tahu mengapa. Memeriksa Log kemudian mengungkapkan bahwa situs itu ditemukan oleh google atau spider sewenang-wenang, yang dengan senang hati MENDAPATKAN (baca: GOT) semua tautan yang ditemukan di situs - termasuk "hapus entri ini" dan "Anda yakin?" tautan.

Sebenarnya - bagian dari ini telah disebutkan. Ini adalah kisah di balik "jangan ubah data pada GET tetapi hanya pada POST". Crawler akan dengan senang hati mengikuti GET, tidak pernah POST. Bahkan robots.txt tidak membantu mencegah perayapan yang salah.

Olaf Kock
sumber
1

Anda juga harus menyadari bahwa jika situs Anda berisi tautan ke situs eksternal lain yang tidak Anda kontrol menggunakan GET akan memasukkan data itu di header refeerer di situs eksternal ketika mereka menekan tautan di situs Anda. Jadi mentransfer data login melalui metode GET SELALU merupakan masalah besar. Karena itu mungkin mengekspos kredensial login untuk akses mudah dengan hanya memeriksa log atau mencari di Google analytics (atau serupa).

3cho
sumber
1

RFC7231:

"URI dimaksudkan untuk dibagikan, tidak diamankan, bahkan ketika mereka mengidentifikasi sumber daya yang aman. URI sering ditampilkan pada tampilan, ditambahkan ke template ketika halaman dicetak, dan disimpan dalam berbagai daftar bookmark yang tidak dilindungi. Karena itu tidak bijaksana untuk memasukkan informasi dalam URI yang sensitif, dapat diidentifikasi secara pribadi, atau risiko untuk diungkapkan.

Penulis layanan harus menghindari formulir berbasis GET untuk pengajuan data sensitif karena data tersebut akan ditempatkan dalam target-permintaan. Banyak server, proksi, dan agen pengguna yang ada mencatat atau menampilkan target-permintaan di tempat-tempat yang mungkin terlihat oleh pihak ketiga. Layanan seperti itu harus menggunakan pengiriman formulir berbasis POST sebagai gantinya. "

RFC ini dengan jelas menyatakan bahwa data sensitif tidak boleh diserahkan menggunakan GET. Karena komentar ini, beberapa pelaksana mungkin tidak menangani data yang diperoleh dari bagian permintaan permintaan GET dengan perhatian yang sama. Saya sedang mengerjakan protokol sendiri yang memastikan integritas data. Menurut spesifikasi ini saya tidak harus menjamin integritas data GET (yang saya akan lakukan karena tidak ada yang mematuhi spesifikasi ini)

Perak
sumber
1

Seperti yang dikatakan beberapa orang sebelumnya, HTTPS menghadirkan keamanan.

Namun, POST sedikit lebih aman daripada GET karena GET dapat disimpan dalam sejarah.

Tetapi bahkan lebih buruk lagi, kadang-kadang pemilihan POST atau GET tidak sampai ke pengembang. Misalnya hyperlink selalu dikirim oleh GET (kecuali jika diubah menjadi bentuk posting menggunakan javascript).

magallanes
sumber
0

GET dapat dilihat oleh siapa saja (bahkan yang ada di bahu Anda sekarang) dan disimpan dalam cache, jadi kurang aman menggunakan pos, tetapi bukan tanpa kriptografi rutin, karena sedikit keamanan Anda harus menggunakan SSL ( https)

kentaromiura
sumber
0

Salah satu alasan POST lebih buruk untuk keamanan adalah bahwa GET dicatat secara default, parameter dan semua data hampir secara universal dicatat oleh server web Anda.

POST adalah kebalikannya , hampir secara universal tidak dicatat , yang menyebabkan sangat sulit untuk menemukan aktivitas penyerang.

Saya tidak membeli argumen "terlalu besar", itu bukan alasan untuk tidak mencatat apa pun , setidaknya 1KB, akan jauh bagi orang untuk mengidentifikasi penyerang bekerja pada titik masuk yang lemah sampai muncul, kemudian POST melakukan layanan ganda, dengan mengaktifkan setiap pintu belakang berbasis HTTP untuk secara diam-diam melewati jumlah data yang tidak terbatas.

RandomNickName42
sumber
0

Perbedaannya adalah bahwa GET mengirim data terbuka dan POST disembunyikan (di header-http).

Jadi dapatkan lebih baik untuk data yang tidak aman, seperti string kueri di Google. Auth-data tidak akan pernah dikirim melalui GET - jadi gunakan POST di sini. Tentu saja keseluruhan tema sedikit lebih rumit. Jika Anda ingin membaca lebih lanjut, baca artikel ini (dalam bahasa Jerman).

Daniel
sumber
0

Baru - baru ini sebuah serangan diterbitkan, yang memungkinkan manusia di tengah untuk mengungkapkan tubuh permintaan dari permintaan HTTPS terkompresi. Karena header permintaan dan URL tidak dikompresi oleh HTTP, permintaan GET lebih aman dari serangan khusus ini.

Ada mode di mana permintaan GET juga rentan, SPDY mengkompres header permintaan, TLS juga menyediakan kompresi opsional (jarang digunakan). Dalam skenario ini serangan lebih mudah dicegah (vendor browser sudah memberikan perbaikan). Kompresi tingkat HTTP adalah fitur yang lebih mendasar, tidak mungkin vendor akan menonaktifkannya.

Ini hanya contoh yang menunjukkan skenario di mana GET lebih aman daripada POST, tapi saya pikir itu bukan ide yang baik untuk memilih GET daripada POST dari alasan serangan ini. Serangannya cukup canggih dan membutuhkan prasyarat non-sepele (Penyerang harus dapat mengendalikan bagian dari konten permintaan). Lebih baik menonaktifkan kompresi HTTP dalam skenario di mana serangan akan berbahaya.

Jan Wrobel
sumber
0

Penafian: Poin berikut hanya berlaku untuk panggilan API dan bukan URL situs web.

Keamanan melalui jaringan : Anda harus menggunakan HTTPS. GET dan POST sama-sama aman dalam hal ini.

Riwayat Peramban : Untuk aplikasi front-end seperti, Angular JS, React JS, dll. Panggilan API adalah panggilan AJAX yang dibuat oleh front-end. Ini tidak menjadi bagian dari riwayat browser. Karenanya, POST dan GET sama-sama aman.

Log sisi server : Dengan menggunakan set penulisan masking data dan format log akses dimungkinkan untuk menyembunyikan semua atau hanya data sensitif dari URL permintaan.

Visibilitas data di konsol browser: Untuk seseorang dengan niat malicious, ini hampir sama dengan upaya untuk melihat data POST sebanyak GET.

Karenanya, dengan praktik logging yang benar, GET API seaman API POST. Mengikuti POST di mana-mana, memaksakan definisi API yang buruk dan harus dihindari.

kishor borate
sumber
-2

Pos adalah yang paling aman bersama dengan SSL yang dipasang karena dikirimkan dalam badan pesan.

Tetapi semua metode ini tidak aman karena protokol 7 bit yang digunakan di bawahnya adalah hack-mampu dengan pelarian. Bahkan melalui firewall aplikasi web level 4.

Soket juga tidak ada jaminan ... Meskipun lebih aman dengan cara tertentu.

drtechno
sumber
-3

Ini adalah pos lama, tetapi saya ingin menolak beberapa jawaban. Jika Anda mentransfer data sensitif, Anda ingin menggunakan SSL. Jika Anda menggunakan SSL dengan parameter GET (mis? Userid = 123), data itu akan dikirim dalam teks biasa! Jika Anda mengirim menggunakan POST, nilainya dimasukkan ke dalam tubuh pesan terenkripsi, dan karenanya tidak dapat dibaca oleh sebagian besar serangan MITM.

Perbedaan besar adalah di mana data dilewatkan. Masuk akal jika data ditempatkan di URL, itu TIDAK BISA dienkripsi kalau tidak Anda tidak akan bisa merutekan ke server karena hanya Anda yang bisa membaca URL. Begitulah cara kerja GET.

Singkatnya, Anda dapat secara aman mengirimkan data dalam POST melalui SSL, tetapi Anda tidak dapat melakukannya dengan GET, menggunakan SSL atau tidak.

LVM
sumber
4
Ini sama sekali tidak benar. SSL adalah protokol lapisan transport. Terhubung ke server PERTAMA, kemudian mengirimkan SEMUA data Aplikasi sebagai aliran data biner terenkripsi. Lihat utas ini: answer.google.com/answers/threadview/id/758002.html
Simeon G
Lakukan TCPDump dan Anda akan melihat bahwa ini 100% benar. Untuk terhubung ke server, Anda harus mengirim permintaan Anda tanpa enkripsi. Jika Anda melakukannya sebagai GET, argumen Anda ditambahkan ke permintaan awal dan karenanya tidak dienkripsi. Terlepas dari apa yang Anda lihat di pos yang Anda tautkan, Anda dapat menguji ini dengan TCPDump (atau serupa).
LVM
1
Selesai! Baru saja menjalankan tcpdump di Mac saya. Dan jawaban Anda muncul 100% salah. Inilah perintah yang saya gunakan: sudo tcpdump -w ssl.data -A -i en1 -n port pertama 443 Lalu ketika saya mencari di ssl.data tentu saja saya melihat gobly gook. Semua data HTTP dienkripsi. Dan untuk memastikan panggilan non-ssl normal berfungsi, saya menggunakan: sudo tcpdump -w clear.data -A -i en1 -n port pertama 80 Dan tentu saja, di dalam clear.data saya memiliki semua header dan URI yang ditampilkan di tempat yang jelas. . Saya menguji ini di gmail saya dan google plus (yang merupakan HTTPS) dan pada beberapa halaman non SSL seperti google.com.
Simeon G
Saya bukan ahli jaringan jadi jika Anda pikir saya menggunakan perintah yang salah pada tcpdump jangan ragu untuk memperbaikinya.
Simeon G
Saya tidak memiliki perintah begitu saja, tetapi Anda juga dapat memeriksanya dengan Wireshark / Ethereal.
LVM
-3

Bahkan POST menerima permintaan GET. Asumsikan Anda memiliki formulir yang memiliki input seperti user.name dan user.passwd, yang seharusnya mendukung nama pengguna dan kata sandi. Jika kita cukup menambahkan? User.name = "pengguna saya & user.passwd =" kata sandi saya ", maka permintaan akan diterima dengan" melewati halaman masuk ".

Solusi untuk ini adalah menerapkan filter (filter java sebagai e) di sisi server dan mendeteksi tidak ada kueri string yang diteruskan sebagai argumen GET.

Saber Chebka
sumber
2
Tidak benar! Ini sepenuhnya tergantung pada backend Anda, apakah kode yang menerima POST juga menerima GET.
Colin 't Hart