舞台裏

Qiita が表でこっちが裏。こっそりやっていく。

X-XSS-Protection を試した

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Reflected XSS</title>
    </head>
    <body>
        <h1>Reflected XSS</h1>
        
        ${param["q"]}
    </body>
</html>

こんな感じの JSP を作って、 “?q=“ みたいなクエリパラメータを乗せたリクエストを送る。

X-XSS-Protection ヘッダーが設定されていない場合、 IE11 だとスクリプトがそのまま実行されて、反射型 XSS が実行できることが確認できた。

Chrome の場合はヘッダーがついていなくても XSS を検知してページが表示されなかった。

ところで ChromeXSS を検知したときにでるエラーメッセージ ERR_BLOCKED_BY_XSS_AUDITORGoogle 検索すると、 IE にしたり Firefox にしたり、はては Chrome のバージョン下げれば解決するよって言ってるのがちらほら見つかるけどええんかな。

Strict-Transport-Security を試した

HTTP Strict-Transport-Security の動作について実際に動かして試した。

HTTPS 通信の検証については、 Payara (GlassFish) を使っていればデフォルトで 8181 ポートにアクセスすれば HTTPS で通信できるので、それを利用(証明書の作成とかインポートとか面倒な作業が不要なので動作確認に便利)。

最初、 http 始まりでブックマークしてる URL とかも気を利かせて https にしてくれるのかなぁと思っていたが、そうではなかった。 あくまで、プロトコルを省略してアクセスしようとした場合の、デフォルトのプロトコルが HTTP から HTTPS になるって話だった。

ちなみにはてなブログは HTTP 通信なのでこのヘッダーはついていない。

X-Frame-Options の変更を試した

デフォルトだとレスポンスヘッダーに

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

がついていることを確認。

この中でも特に X-Frame-Options の動きを確認。

Tomcat の webapps に test フォルダを追加、↓のような index.html ファイルを追加して http://localhost:8080/test/ にアクセス。

<html>
  <head>
  </head>
  <body>
    <iframe src="http://localhost:8080/namespace/" style="width: 500px; height: 500px;"></iframe>
  </body>
</html>

f:id:opengl-8080:20170414232339j:plain

こんなエラーが出て、 <iframe> からは参照できないようになっている。

これを、ポリシーに SAMEORIGIN を設定したらどうなるか見る。

namespace

    <sec:http>
        ...
        <sec:headers>
            <sec:frame-options policy="DENY" />
        </sec:headers>
    </sec:http>

Java Configuration

        http.authorizeRequests()
                ...
                .and()
                .headers().frameOptions().sameOrigin();

f:id:opengl-8080:20170414232709j:plain

オリジンが同じなので <iframe> 上で見れるようになった。

20.2.3 DelegatingRequestMatcherHeaderWriter

20.2.3 DelegatingRequestMatcherHeaderWriter

At times you may want to only write a header for certain requests.

ときどき、あなたは一定のリクエストでだけヘッダーを書きたいと思うことでしょう。

For example, perhaps you want to only protect your log in page from being framed.

例えば、あなたはフレーム化されたログインページだけを守りたいと思うとします。

You could use the DelegatingRequestMatcherHeaderWriter to do so.

あなたは DelegatingRequestMatcherHeaderWriter を使うことでそれができます。

When using the XML namespace configuration, this can be done with the following:

XML namespace configuration を使っている場合は、次のようにすることで実現できます。

<http>
    <!-- ... -->

    <headers>
        <frame-options disabled="true"/>
        <header ref="headerWriter"/>
    </headers>
</http>

<beans:bean id="headerWriter"
    class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
    <beans:constructor-arg>
        <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher"
            c:pattern="/login"/>
    </beans:constructor-arg>
    <beans:constructor-arg>
        <beans:bean
            class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
    </beans:constructor-arg>
</beans:bean>

We could also prevent framing of content to the log in page using java configuration:

私たちは、 Java Configuration を使ってログインページのコンテンツをフレーム化することを防ぐこともできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    RequestMatcher matcher = new AntPathRequestMatcher("/login");
    DelegatingRequestMatcherHeaderWriter headerWriter =
        new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
    http
    // ...
    .headers()
        .frameOptions().disabled()
        .addHeaderWriter(headerWriter);
}
}

20.2.2 Headers Writer

20.2.2 Headers Writer

When the namespace or Java configuration does not support the headers you want, you can create a custom HeadersWriter instance or even provide a custom implementation of the HeadersWriter.

namespace か Java Configuration がサポートしていないヘッダーが必要となった場合は、カスタムの HeaderWriter インスタンスを生成するか、カスタムの実装を提供することができます。

Let’s take a look at an example of using an custom instance of XFrameOptionsHeaderWriter.

XFrameOptionsHeaderWriter のカスタムインスタンスを使用する例を見てみましょう。

Perhaps you want to allow framing of content for the same origin.

おそらく、あなたは同じオリジンでのコンテンツのフレームかを許可したいと思うでしょう。

This is easily supported by setting the policy attribute to “SAMEORIGIN”, but let’s take a look at a more explicit example using the ref attribute.

これは、 “SAMEORIGIN” をポリシーの属性にセットすることで簡単にサポートされています。 しかし、 ref 属性を使用したより明示的な例を見てください。

<http>
    <!-- ... -->

    <headers>
        <header ref="frameOptionsWriter"/>
    </headers>
</http>
<!-- Requires the c-namespace.
See http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-c-namespace
-->
<beans:bean id="frameOptionsWriter"
    class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
    c:frameOptionsMode="SAMEORIGIN"/>

We could also restrict framing of content to the same origin with Java configuration:

私たちは、 Java Configuration で同じオリジンでコンテンツをフレーム化することを制限することもできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN));
}
}

20.2 Custom Headers, 20.2.1 Static Headers

20.2 Custom Headers

Spring Security has mechanisms to make it convenient to add the more common security headers to your application.

Spring Security はより共通のセキュリティヘッダーをアプリケーションに追加することを便利にするメカニズムを持ちます。

However, it also provides hooks to enable adding custom headers.

しかしながら、それはカスタムヘッダーを追加できるフックを提供することでもあります。

20.2.1 Static Headers

There may be times you wish to inject custom security headers into your application that are not supported out of the box.

ときどき、あなたはサポートされていないカスタムのセキュリティヘッダーをアプリケーションに追加したいと思うでしょう。

For example, given the following custom security header:

例えば、以下のカスタムのセキュリティヘッダーを提供します。

X-Custom-Security-Header: header-value

When using the XML namespace, these headers can be added to the response using the <header> element as shown below:

XML namespace を使っている場合は、レスポンスにヘッダーを追加するには <header> 要素を次のように使用します。

<http>
    <!-- ... -->

    <headers>
        <header name="X-Custom-Security-Header" value="header-value"/>
    </headers>
</http>

Similarly, the headers could be added to the response using Java Configuration as shown in the following:

同様に、 Java Configuration でレスポンスにヘッダーを追加する場合は次のようにします。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"));
}
}

20.1.8 Referrer Policy

20.1.8 Referrer Policy

Referrer Policy is a mechanism that web applications can leverage to manage the referrer field, which contains the last page the user was on.

Referer ポリシーは Web アプリケーションがユーザーが最後にアクセスしていたページを含んだ referer フィールドを管理するようできるメカニズムです。

Spring Security’s approach is to use Referrer Policy header, which provides different policies:

Spring Security のアプローチは、異なるポリシーを提供する Referer Policy ヘッダーを使うというものです。

Referrer-Policy: same-origin

The Referrer-Policy response header instructs the browser to let the destination knows the source where the user was previously.

レスポンスヘッダの Referer-Policy はユーザが以前いた場所を知らせるようブラウザに指示します。

Configuring Referrer Policy

Spring Security doesn’t add Referrer Policy header by default.

Spring Security はデフォルトでは Referer Policy ヘッダーを追加しません。

You can enable the Referrer-Policy header using XML configuration with the <referrer-policy> element as shown below:

あなたは、 XML 設定では <referer-policy> タグを次のように使用することで Referer-Policy ヘッダーを有効にできます。

<http>
    <!-- ... -->

    <headers>
        <referrer-policy policy="same-origin" />
    </headers>
</http>

Similarly, you can enable the Referrer Policy header using Java configuration as shown below:

同様に、あなたは Java Configuration で次のようにして Referer-Policy を有効にできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
}
}