web-dev-qa-db-ja.com

GETとPOST Webアプリケーションセキュリティの違いはありますか?

2つのWebアプリケーション間でデータを送信する方法は2つあります。

  1. データをBase64でエンコードしてURLに追加し、宛先アプリケーションでこれらのパラメーターを取得して、パラメーターをデコードします。

    たとえば、http:/myDomain/someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ

  2. パラメータを非表示の値としてapplication1からapplication2に送信します。

    文字列res =(String)request.getAttribute( "paramValue"); 
     document.myForm.action = 'myDestinationURL'; 
     document.myForm.method = "POST"; 
     document.myForm.submit(); 
     
     <form name = "myForm" method = "post"> 
     <input type = "hidden" name = "paramValue" value = "<%= res%>" />

選択肢1では、送信しているパラメーターと私のエンコード手法を知ることができます。選択肢2では、ソースの表示を簡単に行うことにより、送信しているデータを表示できます。

上記のものとは別に、侵入者が私のシステムをよりよく知るために可能な方法は何ですか?そして、開発者にとって一般的に適しているのはどのオプションですか?選択肢1または選択肢2?

41
Vikas V

いずれにしても、オプション1では、セキュリティに関連しない多くの問題が発生する可能性があります。

  • 結果のURLは、ブラウザによってキャッシュされるか、ブックマークされ、ユーザーに再送信させます。
  • 結果のURLはユーザーによって共有される可能性があり、第三者が送信する可能性があります。
  • URLは ブラウザのベンダー に送信され、サイトにアクセスする可能性があります。

しかし、これはセキュリティに関するものであり、オプション2にはないいくつかのリスクをもたらします。

  • パラメータ付きのURLは、途中ですべてのプロキシログに記録され、データが明らかになる可能性があります。
  • これで、デコード関数は追加の攻撃ベクトルになります。 (Unicodeは正しく処理されますか?長さに制限はありますか?)
  • エンコードされた文字列を セキュリティによるあいまいさ (またはそれほどあいまいさではない)、またはおそらくより適切な セキュリティシアター の場合、何らかの方法で安全であると考えたくなるかもしれません。

とはいえ、それらは他の点ではそれらが提供するセキュリティにおいてほぼ同等です。どちらもHTTPヘッダーでプレーンテキストデータを送信します。base64は正確なロケットサイエンスではありません(POSTバージョン)をbase64エンコードできます)。

どちらも、データに意味のある保護を提供しません。

ユーザーに見せたくない情報の場合。はじめにそれをユーザーに送信するのはなぜですか?使用しているアーキテクチャを検討し、クライアント側でその情報を処理しないことによってリスクを完全に取り除く方法があるかどうかを確認してください。

したがって、質問に答えるために:データの送信に関して-both同じ情報を攻撃者に明らかにします。状況に適したオプションを選択します( このTreehouseブログ投稿がそれを助けるかもしれません )が、すべきではありませんいずれかの方法で実際に何かを保護します。

43
Bob Watson

Webページに単純な<img>タグを含めることで、クロスサイトGETリクエストを簡単に作成できます。たとえば、www.evilhacker.comのページでは、一部のJavascriptが攻撃者が選択したパスを含む<img>タグの長いストリームを生成し、すべてがwww.targetbank.com-およびを指します。 yourブラウザは、すべてのリクエストに銀行のCookieを含めます。

これだけでも、ターゲットサイトでのすべての変更を意味するGETリクエストのサポートがない方がよい。一般的なルールとして、GETリクエストは リプレイ攻撃 が問題ではない操作に予約する必要があります-つまり、実際には、静的データへの読み取りアクセス )のみ

15
Thomas Pornin

POSTを使用して、サーバーでデータを変更するリクエストを送信します。

HTTP仕様 により、GETリクエスト(URL内のパラメーターなど)は、データを変更せずに取得する(したがって、GETという名前の)リクエストにのみ使用する必要があります。 POSTリクエスト(非表示のパラメーターですが、HTTPリクエストではまだ暗号化されていません)は、リクエストがデータベースに保存されるデータ(標準ログ以外)を作成/更新/変更するときは常に使用する必要があります。これにより、攻撃者がクロスサイトリクエストフォージェリを実行することが やや難しく され、Webページの履歴やWebサーバーのログに秘密情報が誤って二重送信または保存される可能性が低くなります。

ピン変数は秘密ですか?

pin変数の意味によっては、現在行っていることは安全ではないようです。これは潜在的な盗聴者から秘密にしておく必要がありますか、それともピンを傍受している人々がそれを使って何らかの攻撃を行うことができますか?その場合、このシークレットデータを使用するすべての要求に対してHTTPS(トランスポート層でのエンドツーエンドの暗号化)のみを使用してください。使用したbase-64値は_3000670269_のようです(適切なb64エンコーディングにするために2つの等号を追加する必要があったことを認めています)。

攻撃者が他のピンを使用しようとするとどうなりますか?

私の_pin='300670269'_としましょう。ただし、システムをテストするために_MzAwMDY3MDI1OQ_を送信しました(_pin='3000670259'_の場合)。それにより、別のユーザーアカウントに効果的に侵入できますか?もしそうなら、少なくとも、checksum=SHA256(pin+secret_server_side_string)のような追加のPOST変数のようなものを実行する必要があります。ここで_secret_server_side_string_は、長いランダムな文字列です(たとえば、何か_de10RRORX50UAUhx0dDIxJnzXKBAs68yjdWVz8QQ_- 40 random upper + lower + numbers文字はlg(62)* 40 = 238ビットのエントロピーを持つ)のようになり、アプリケーションはピンにチェックサムが一致する場合にのみピンに作用します。アプリケーションはチェックサムを生成する必要があります(secret_server_side_stringをクライアントに公開せずに)。ピンでチェックサムをチェックするとき、アプリケーションが一定時間の文字列比較を行うように注意する必要があります。これにより、アプリケーションがタイミング攻撃に対して脆弱になりません。 。

11
dr jimbob

Bobの回答に加えて、機密パラメータを指定したGETリクエストを使用する場合、セキュリティ上の別の欠点があります。

機密情報を含むURLは、結果のHTMLページによって参照されるリソースをホストしているサードパーティのWebサーバーに送信されます。

例:

最初のリクエスト:

GET /someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ HTTP/1.0
Host: domain

その要求への応答:

HTTP/1.0 OK
Content-type: text/html

<img src="http://thirdparty/hello.jpg" />

WebブラウザーはHTMLをレンダリングし、次のように画像を取得しようとします。

GET /hello.jpg HTTP/1.0
Host: thirdparty
Referer: http://domain/someCode/pages/somePage.jsf?pin=MzAwMDY3MDI2OQ

これは、ページにレンダリングされたHTMLが攻撃者によって制御されている場合(ある程度、ホワイトリストにhtmlがある場合)に特に問題になります。たとえば、セッションをURLに配置するWebメールサービスにより、攻撃者は、メールのHTML本文で、攻撃者のWebサーバー/スクリプトを指す画像を送信することができます。次に、攻撃者は、画像をレンダリングするときに、被害者のWebブラウザーから送信されたRefererヘッダーのURLをたどる必要があります。この種の脆弱性は、実際にはExciteメール(ここでは履歴を話します:))や過去の他のいくつかのWebメールサービスに影響を及ぼしました。

3
Sandro Gauci

Webアプリケーションファイアウォールルールを回避するために悪用された最近の興味深い攻撃は、「 HTTPパラメータ汚染攻撃 」として知られています。のような例で説明します

POST /index.aspx?par=1&par=2 HTTP/1.1
User-Agent: Mozilla/5.0
Host: Host
Cookie: par=5; par=6
Content-Length: 19
par=3&par=4 

このPost Requestアプリケーションの動作は、Javaの開発者などに依存します。

  1. javax.servlet.ServletRequestInterface(クエリ文字列直接解析)
  2. Java.lang.StringgetParameter(Java.lang.Stringname)リクエストパラメータの値を文字列として返します。パラメータが存在しない場合はnullを返します。
  3. Java.lang.String [] getParameterValues(Java.lang.Stringname)指定されたリクエストパラメータが持つすべての値を含むStringオブジェクトの配列を返します。パラメータが存在しない場合はnullを返します。
3
Ali Ahmad

考慮すべきもう1つのセキュリティ要素は、Webサーバーのアクセスログは通常、クエリ文字列パラメーターを含め、要求されたURLをキャプチャすることです。クエリ文字列をログに記録したくない場合は、POSTリクエストに頼る必要があります。

もちろん、ページをリロードするときのブラウザの動作や、ブラウザの[戻る]ボタンを使用してページが呼び出されるときなど、GETリクエストとPOSTリクエストのどちらを決定するかを検討するときに、セキュリティに関連しない要素があります。

0
200_success