2012-01-03 8 views
4

私は、HttpServletRequestを作成する私のTomcatサーバー上のサーブレットにjquery投稿を含むjspを持っています。私のサーブレットへのjspのコールだけが処理され、私のjsp以外のソースからのリクエストは無視されるようにしたいと思います。 私のサーバーを呼び出す参照ページが何であるかを確認する方法はありますか?私はrequest.getHeader("referer")を使って偽装することができるので、私はそれに頼ることができないことを知っています。誰が私のHttpServletRequestに電話していますか?

答えて

5

トークンとして固有の文字列を生成し、それをセッションに格納し、JSPのPOSTフォームに隠し入力値として埋め込み、最後にサーブレットをチェックインします。

基本的に:セッションの作成に

(例えば、HttpSessionListener#sessionCreated()で):(例えば、HttpServlet#doGet()で)JSP要求の前に

Set<String> tokens = new HashSet<String>(); 
event.getSession().setAttribute("tokens", tokens); 

:オン

String token = UUID.randomUUID().toString(); 
Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens"); 
tokens.add(token); 
request.setAttribute("token", token); 

JSP自体を処理する:

<input type="hidden" name="token" value="${token}" /> 
フォームの後処理に

(例えば、HttpServlet#doPost()に)提出:もちろん

String token = request.getParameter("token"); 
Set<String> tokens = (Set<String>) request.getSession().getAttribute("tokens"); 

if (!tokens.remove(token)) { 
    response.sendError(HttpServletResponse.SC_BAD_REQUEST); 
    return; 
} 

// ...  

私はそれが正確に通常の同期要求をシミュレートするように、あなたのjQuery.post()機能が$.post(form.action, form.serialize(), callback)のように控えめな方法で書かれていることを前提としてい(言い換えれば、あなたのフォームはJSが無効になっていると完全にうまく動作します)。

+0

ありがとうございました。私はjqueryを初めて使っていることを認めなければならないので、このアプローチが私の問題のために働くかどうかはわかりません。私のJSPでは、次のようなものがあります。[code type] "text/JavaScript"> ... var aMap = {"action": "getdata"} $ .getJSON( "/ MyServlet"、aMap、function(json ){// jsonの結果で何かする}}; [/ code]だから私はあなたが説明したようにトークンを渡す方法については明確ではない。ありがとうございました。 – Steve

+0

ああ、Webサービスとしてサーブレットを使用しています。これは実際にあなたの質問に記載されているように "jQueryの投稿"ではありません。それは単なるGET要求です。正確にこれが呼び出されるのはいつですか?ページの読み込み中に1回だけ?または、ユーザーインタラクションで何回も使用できますか? – BalusC

+0

混乱して申し訳ありません。実際には、javascriptタイマーに基づいて呼び出されます(ループ内のsetTimeoutメソッドを使用)。数秒ごとに、 "$ .getJSON ..."が呼び出され、返されたjsonオブジェクトに基づいてjspのステータスが更新されます。 – Steve

0

あなたのJSPに安全なトークンをレンダリングし、それを確認できるサーブレットへのAjax呼び出しにインクルードすることができます。これは、Ajax呼び出しがブラウザとJavascriptを使用して行われることを保証するものではありませんが、呼び出しを行う前に少なくともJSPから安全なトークンを取得する必要があります。

CSRFを緩和するのに同様の概念が推奨されます。

1

jspのランダムなクッキーを作成し、それをPOSTフォームに追加し、正しいクッキー値を持つリクエストのみを受け入れることができます。

+0

これは実際に言及された他のソリューションよりも安全です。アップボーニング。 – Perception

+0

@Perception:HTTPセッションはすでに「ランダムなクッキー」によってバックアップされていることに注意してください。 – BalusC

+0

@BalusC - 一般的に真です(URLの書き換えを使用するものもあります)。私の主なポイントは、クッキーは、HTMLページに埋め込まれたトークンよりも不正なクライアントによって偽装するのが難しいことです。 – Perception

0

ちょっとしたセマンティクス。リクエストは通常​​、JSPを表示するブラウザから作成されます。別のプログラムがあなたのJSPをリクエストするのを止め、何か情報を使ってリクエストすることはできません。

ユーザーのブラウザで表示されている別のWebページを、サイトへの要求の実行を停止することができます。これはCross-site request forgeryと呼ばれます。このシナリオを緩和することができます。

あなたが防止しようとするものによっては、CSRFソリューションが役立つかもしれません。 Webサーバーからプレマイドソリューションを見つけることができます。たとえば、ここにはTomcat's

関連する問題