32

私が取り組んでいる製品は、潜在的な顧客による厳しいセキュリティ監査を受け、認証が行われる前に Tomcat が JSESSIONID Cookie を設定することに腹を立てています。つまり、Tomcat は、ステートレス ログイン ページが読み込まれるとき、ただしログイン前にこの Cookie を設定します。

彼らは次のいずれかを提案します。

  1. ログイン後に新しい JSESSIONID Cookie を発行する
  2. JSESSIONID Cookie がログイン ページの最初の場所 (つまり、認証が行われる前) に設定されるのを防ぎます。

私はこのサイトで JSESSIONID 関連のすべてを調べましたが、簡単な答えが見つかりません。私はいくつかのアイデアを望んでいます。それぞれの私の最善の解決策は次のとおりです。

  1. ログイン直後に、すべての属性をコピーし、古いセッションを無効にし、新しいセッションを作成し、値をコピーし、それをリクエストに関連付けて、それが機能することを期待して、セッション (id を除く) を複製します。
  2. ログインページが最初に読み込まれる前に、JSESSIONID Cookie を取り除くチェーンの最後にサーブレット Filter を作成します。そして、JSESSIONID が設定されていなくてもログイン要求が機能することを願っています。

私は少し眠らなければなりませんが、朝にこれらを試してみます. あなたのように、私よりずっと賢い人からフィードバックやより良い提案を得ることができれば素晴らしいことです!

とにかく、他の多くの人が同様のことをしたいと思っているように見えるので、ここに結果を投稿します.

4

10 に答える 10

47

後ではなく直前にリフレッシュします。login アクションを最初に実行するときは、次のようにします。

HttpSession session = request.getSession(false);
if (session!=null && !session.isNew()) {
    session.invalidate();
}

次に、次のようにします。

HttpSession session = request.getSession(true); // create the session
// do the login (store the user in the session, or whatever)

参考までに、このトリックで解決しているのはhttp://www.owasp.org/index.php/Session_Fixationです

最後に、セッションの自動作成を無効にして、本当に必要な場合にのみセッションを作成できます。JSP を使用する場合は、次のようにします。

<%@page contentType="text/html"
        pageEncoding="UTF-8"
        session="false"%>
于 2011-11-17T10:57:18.510 に答える
8

ポイントが足りないため、上記の@cherouvimの回答にはコメントできません。セッション固定を避けるために、新しいセッション ID は、ユーザーが正常にログインした「後」に設定する必要があります。私は自分の推論を説明しようとします。

セッション固定とは、事実上、攻撃者が何らかの方法でユーザーをだまして、攻撃者が知っている値を使用させたことを意味します。簡単にするために、攻撃者がユーザーのデスクに近づき、Firebug を使用してユーザーの Cookie を編集したと仮定しましょう。ユーザーがログインすると、攻撃者が制御する Cookie でログインされます。攻撃者もこの値を知っているため、ブラウザを更新すると、そのセッション ID にマップされたリソース (被害者のリソース) が攻撃者に提供されます。それがセッション固定です。正しい?

ここで、被害者のユーザーがログインする前にsession.invalidateを実行したとします。Cookie の最初の値が abc だったとします。session.invalidateを実行すると、値 abc がサーバーのセッションから消去されます。

今、私が同意しない部分があります。ユーザーが実際にログインする前に新しいセッションを生成することをお勧めします(ユーザー名とパスワードを入力して送信をクリックします)。これにより、新しい Cookie が生成されることは間違いありませんが、ユーザーがログインする前にブラウザーに表示されます。そのため、攻撃者が「ログイン前」Cookie を再度編集できる場合、ユーザーがログインした後も同じ Cookie が使用されるため、攻撃は持続します。

これが正しい流れだと思います。

  • ユーザーは GET /login.html を実行します
  • 現在ブラウザにある Cookie を含むログイン ページを返す
  • ユーザーが資格情報を入力し、[送信] をクリックします
  • アプリケーションは資格情報を検証します
  • 資格情報が正しいことがわかったとき。session.invalidate() が実行され、古い Cookie が破棄されます。
  • request.getSession(true)を使用して新しい Cookie を生成します。

これが意味することは、ログイン前に攻撃者がユーザーをだまして制御された値を使用させたとしても、ログイン後にアプリケーションが強制的に値を変更するため、ユーザーは保護されているということです。

この問題に関する良いブログはこちらです - https://blog.whitehatsec.com/tag/session-fixation/

于 2014-01-06T20:52:53.870 に答える
5

次の方法に従って、古いセッションから新しいセッションを再生成しました。あなたがそれから恩恵を受けることを願っています。

private void regenerateSession(HttpServletRequest request) {

    HttpSession oldSession = request.getSession();

    Enumeration attrNames = oldSession.getAttributeNames();
    Properties props = new Properties();

    if (attrNames != null) {
        while (attrNames.hasMoreElements()) {
            String key = (String) attrNames.nextElement();
            props.put(key, oldSession.getAttribute(key));
        }

        //Invalidating previous session
        oldSession.invalidate();
        //Generate new session
        HttpSession newSession = request.getSession(true);
        attrNames = props.keys();

        while (attrNames.hasMoreElements()) {
            String key = (String) attrNames.nextElement();
            newSession.setAttribute(key, props.get(key));
        }
    }
于 2014-11-24T20:08:39.073 に答える
2

私が見つけた2つのことは、他の人に役立つかもしれません.

  1. Apache Wicket を使用している場合は、バージョン 1.4 以降でこれに対する解決策があります。私のアプリはまだ 1.3 にあるので、気が付きませんでしたが、自分の WebSession クラスで非常に簡単にバックポートすることができました。Wicket 1.4 は、replaceSession() メソッドを WebSession に追加します。これはうまく機能します。認証の直後に呼び出すことができ、新しい JSESSIONID を取得できます。それは基本的に私にとってこの問題を解決しました。詳細はこちら: https://issues.apache.org/jira/browse/WICKET-1767

  2. バージョン 5.5.29 以降で利用可能な Apache Tomcat バルブがあり、context.xml に追加できます。認証後に新しい JSESSIONID の発行を処理します。詳細については、https ://issues.apache.org/bugzilla/show_bug.cgi?id=45255 を参照してください。バルブのエントリは次のようになります。<Valve className="org.apache.catalina.authenticator.FormAuthenticator" changeSessionIdOnAuthentication="true"/>

于 2011-11-18T17:07:26.480 に答える
1

JSESSIONID がブラウザに表示されているか、Cookie に設定されていることが問題ですか? あなたの場合は後者だと思います。

1.ログイン後に新しいJSESSIONID Cookieを発行する

これは、ログイン時にhttp から https に切り替えた場合の Tomcat のデフォルトの動作です。古いものは破棄され、新しいものが生成されます。

ログイン自体が http 経由である場合、それは監査人にとって別のセキュリティ問題だと思います ;)

それとも、すべてのページが https 経由ですか?

于 2011-11-17T10:31:22.030 に答える
-1
session=request.getSession(true);
Enumeration keys = session.getAttributeNames();     
HashMap<String,Object> hm=new HashMap<String,Object>();  
while (keys.hasMoreElements())
{
  String key = (String)keys.nextElement();
  hm.put(key,session.getValue(key));
  session.removeAttribute(key);      
}
session.invalidate();
session=request.getSession(true);
for(Map.Entry m:hm.entrySet())
{
  session.setAttribute((String)m.getKey(),m.getValue());  
  hm.remove(m);
}  
于 2016-12-31T06:44:45.890 に答える