28

Tomcat 7 サーバーで実行されている Web アプリケーションがあります。セッション ID を持つ Cookie には、デフォルトでフラグHttpOnlySecure. JSESSIONIDCookieのこのフラグを無効にしたい。しかし、それはうまくいきません。web.xmlファイルでこれを変更しましたが、機能していません。

<session-config>
    <session-timeout>20160</session-timeout>
    <cookie-config>
        <http-only>false</http-only>
        <secure>false</secure>
    </cookie-config>
</session-config>

攻撃者が xss の脆弱性を見つけた場合、Cookie を盗んでセッションを乗っ取ることができるため、これがセキュリティ リスクであることはわかっています。

Cookie は、JSESSIONIDHTTP と HTTPS、および AJAX 要求で送信する必要があります。

編集:

次のオプションをファイルHttpOnlyに追加して、フラグを無効にしました。conf/context.xml

<Context useHttpOnly="false">
....
</Context>
4

3 に答える 3

2

tomcat からコードを読むと、次のことがわかります。

// Always set secure if the request is secure
if (scc.isSecure() || secure) {
    cookie.setSecure(true);
}

sessionCookieConfig.setSecure(false);そのため、リスナーまたは<cookie-config><secure>false</secure></cookie-config>web.xmlで JSESSIONID Cookie のセキュア フラグを非アクティブ化しようとしても、Tomcat がセキュア フラグを true に強制するため、リクエストがセキュアな場合 (つまり、https URL または SSL ポートから来た場合) は機能しません。

解決策は、リクエスト フィルタを使用して、セッションの作成直後にサーバー レスポンスの JSESSIONID Cookie を変更することです。これは私の実装です(非常に基本的です):

public class DisableSecureCookieFilter implements javax.servlet.Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if(request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
            request = new ForceUnsecureSessionCookieRequestWrapper((HttpServletRequest) request, (HttpServletResponse) response);
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() { }

    public static class ForceUnsecureSessionCookieRequestWrapper extends HttpServletRequestWrapper {
        HttpServletResponse response;

        public ForceUnsecureSessionCookieRequestWrapper(HttpServletRequest request, HttpServletResponse response) {
            super(request);
            this.response = response;
        }

        @Override
        public HttpSession getSession(boolean create) {
            if(create) {
                HttpSession session = super.getSession(create);
                updateCookie(response.getHeaders("Set-Cookie"));
                return session;
            }
            return super.getSession(create);
        }

        @Override
        public HttpSession getSession() {
            HttpSession session = super.getSession();
            if(session != null) {
                updateCookie(response.getHeaders("Set-Cookie"));
            }

            return session;
        }

        protected void updateCookie(Collection<String> cookiesAfterCreateSession) {
            if(cookiesAfterCreateSession != null && !response.isCommitted()) {
                // search if a cookie JSESSIONID Secure exists
                Optional<String> cookieJSessionId = cookiesAfterCreateSession.stream()
                                                        .filter(cookie -> cookie.startsWith("JSESSIONID") && cookie.contains("Secure"))
                                                        .findAny();
                if(cookieJSessionId.isPresent()) {
                    // remove all Set-Cookie and add the unsecure version of the JSessionId Cookie
                    response.setHeader("Set-Cookie", cookieJSessionId.get().replace("Secure", ""));

                    // re-add all other Cookies
                    cookiesAfterCreateSession.stream()
                            .filter(cookie -> !cookie.startsWith("JSESSIONID"))
                            .forEach(cookie -> response.addHeader("Set-Cookie", cookie));
                }
            }
        }
    }

}

および web.xml で:

<filter>
    <filter-name>disableSecureCookieFilter</filter-name>
    <filter-class>com.xxxx.security.DisableSecureCookieFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>disableSecureCookieFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

安全でない Cookie を有効にすると、重要な https セキュリティがバイパスされることに注意してください。(http から https へのスムーズな移行のために、これを行う必要がありました)

于 2018-06-05T14:07:58.843 に答える
2

Tomcat でこれに対する解決策は見つかりませんでしたが、apache をリバース プロキシとして使用している場合は、次のことができます。

Header edit* Set-Cookie "(JSESSIONID=.*)(; Secure)" "$1"

これによりmod_headers、セキュアフラグを削除するために戻る途中でヘッダーが変更されます。きれいではありませんが、これが重要な場合に機能します。

于 2017-02-08T18:05:03.407 に答える
-1

上記の Apache に対する George Powell のソリューションに加えて、IIS を使用している場合は、次のように解決できます。

  1. IIS URL 書き換えモジュールをインストールする
  2. 以下を web.config に追加します

<rewrite>
  <outboundRules>
    <rule name="RemoveSecureJessionID">
      <match serverVariable="RESPONSE_Set-Cookie" pattern="^(.*JSESSIONID.*)Secure;(.*)$" />
      <action type="Rewrite" value="{R:1}{R:2}" />
    </rule>
  </outboundRules>
</rewrite>

このソリューションは、Pete Freitag のブログからのものです。

上記のように、最近の Chrome の更新 (2017 年 1 月) 以降、これが問題になっています。

于 2017-02-20T23:41:07.483 に答える