舞台裏

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

20.1.7 Content Security Policy (CSP)

20.1.7 Content Security Policy (CSP)

Content Security Policy (CSP) is a mechanism that web applications can leverage to mitigate content injection vulnerabilities, such as cross-site scripting (XSS).

Content Security Policy は、 Web アプリケーションがコンテンツインジェクション脆弱性を緩和するのに利用できるようにするメカニズムです。 例えば、 XSS などがそうです。

CSP is a declarative policy that provides a facility for web application authors to declare and ultimately inform the client (user-agent) about the sources from which the web application expects to load resources.

CSPは、Webアプリケーション作成者が宣言し、最終的にWebアプリケーションがリソースを読み込むソースについてクライアント(ユーザーエージェント)に通知するための機能を提供する宣言型ポリシーです。

Content Security Policy is not intended to solve all content injection vulnerabilities.

CSP は全てのコンテンツインジェクション脆弱性を解決することを意図していません。

Instead, CSP can be leveraged to help reduce the harm caused by content injection attacks.

代わりに、 CSP はコンテンツインジェクション攻撃を原因とする問題を減らすのに活用できます。

As a first line of defense, web application authors should validate their input and encode their output.

最初の防衛ラインとして、 Web アプリケーションの制作者は彼らの入力を検証し、出力をエンコードすべきです。

A web application may employ the use of CSP by including one of the following HTTP headers in the response:

Webアプリケーションは、レスポンスに次のHTTPヘッダーのいずれかを含めることで、CSPを使用することができます。

  • Content-Security-Policy
  • Content-Security-Policy-Report-Only

Each of these headers are used as a mechanism to deliver a security policy to the client.

これらのヘッダーは、クライアントにセキュリティポリシーを提供するためのメカニズムとして使用されます。

A security policy contains a set of security policy directives (for example, script-src and object-src), each responsible for declaring the restrictions for a particular resource representation.

セキュリティポリシーは、特定のリソース表現についての制限を宣言したセキュリティポリシーディレクティブのセット(例えば script-srcobject-src)を含んでいます。

For example, a web application can declare that it expects to load scripts from specific, trusted sources, by including the following header in the response:

例えば、 Web アプリケーションは、次のレスポンスヘッダを含めることで、アプリケーションが特定の信頼された場所からスクリプトを読み込むことを期待していることを宣言できます。

Content-Security-Policy: script-src https://trustedscripts.example.com

An attempt to load a script from another source other than what is declared in the script-src directive will be blocked by the user-agent.

script-src ディレクティブで宣言された場所とは異なる場所からスクリプトをロードしようとすると、ユーザエージェント(※ブラウザとか)によってブロックされます。

Additionally, if the report-uri directive is declared in the security policy, then the violation will be reported by the user-agent to the declared URL.

さらに、もし report-uri ディレクティブがセキュリティポリシーに宣言されていた場合、違反行為はユーザエージェントによって宣言された URL に報告されます。

For example, if a web application violates the declared security policy, the following response header will instruct the user-agent to send violation reports to the URL specified in the policy’s report-uri directive.

例えば、もし Web アプリケーションが宣言されたセキュリティポリシーに違反した場合、以下のレスポンスヘッダーはユーザーエージェントに違反のレポートをポリシーの report-uri ディレクティブで指定された URL に対して送信するよう指示します。

Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/

Violation reports are standard JSON structures that can be captured either by the web application’s own API or by a publicly hosted CSP violation reporting service, such as, REPORT-URI.

違反のレポートは Web アプリケーション自身の API か、 CSP 違反レポートサービス(例えば REPORT-URI)によってホストされたポリシーのいずれかでキャプチャー可能な標準的な JSON の構造をしています。

The Content-Security-Policy-Report-Only header provides the capability for web application authors and administrators to monitor security policies, rather than enforce them.

Content-Security-Policy-Report-Only ヘッダーは Web アプリケーションの作者と管理者に代わってセキュリティポリシーを監視する能力を提供します。

This header is typically used when experimenting and/or developing security policies for a site.

このヘッダーは通常、サイトのセキュリティポリシーを検証したり開発しているときに使用します。

When a policy is deemed effective, it can be enforced by using the Content-Security-Policy header field instead.

ポリシーが有効とみなされると、代わりに Content-Security-Policy ヘッダーフィールドが使用されるようになります。

Given the following response header, the policy declares that scripts may be loaded from one of two possible sources.

以下のレスポンスヘッダーを与えて、ポリシーがスクリプトは2つの有効なソースのうち1つからロードされるということを宣言しています。

Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/

If the site violates this policy, by attempting to load a script from evil.com, the user-agent will send a violation report to the declared URL specified by the report-uri directive, but still allow the violating resource to load nevertheless.

evil.com からロードしようとしたためにサイトがこのポリシーに違反した場合、ユーザーエージェントは違反レポートを report-uri ディレクティブで宣言された URL に送信します。 しかし、それでもまだ違反したリソースをロードすることは許可されています。

Configuring Content Security Policy

It’s important to note that Spring Security does not add Content Security Policy by default.

Spring Security は Content Security Policy をデフォルトでは追加しないという点に注意してください。

The web application author must declare the security policy(s) to enforce and/or monitor for the protected resources.

Web アプリケーションの作者は、リソースの保護について実行するのかもしくは監視するのかについてセキュリティポリシーを宣言しなければなりません。

For example, given the following security policy:

例えば、次のセキュリティポリシーを与えるとした場合、

script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/

You can enable the CSP header using XML configuration with the <content-security-policy> element as shown below:

あなたは xml 設定を使った場合は <content-security-policy> 要素を以下に見るように使うことで CSP ヘッダーを有効にできます。

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

    <headers>
        <content-security-policy
            policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/" />
    </headers>
</http>

To enable the CSP ‘report-only’ header, configure the element as follows:

CSP の report-only ヘッダーを有効にするには、要素を次のように設定します。

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

    <headers>
        <content-security-policy
            policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
            report-only="true" />
    </headers>
</http>

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

同様に、あなたは Java Configuration を次のように使うことで CSP ヘッダーを有効にできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");
}
}

To enable the CSP ‘report-only’ header, provide the following Java configuration:

CSP の report-only ヘッダーを有効にするには、 Java Configuration では次のように提供します。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
        .reportOnly();
}
}

Additional Resources

Applying Content Security Policy to a web application is often a non-trivial undertaking.

Web アプリケーションに Content Security Policy を適用することは、しばしば重要ではないことがあります。

The following resources may provide further assistance in developing effective security policies for your site.

以下のリソースは効果的なセキュリティポリシーをサイトに組み込むときの助けを提供します。

An Introduction to Content Security Policy

CSP Guide - Mozilla Developer Network

W3C Candidate Recommendation

20.1.6 X-XSS-Protection

正しさの保証なんてものは(ry

20.1.6 X-XSS-Protection

Some browsers have built in support for filtering out reflected XSS attacks.

いくつかのブラウザは Refrected XSS 攻撃を回避する組み込みのサポートを持っています。

※Referected XSS 攻撃
反射型 XSS 攻撃。リクエスト中に含まれるコードがそのまま実行されるケースの XSS 攻撃。

This is by no means foolproof, but does assist in XSS protection.

これは決して簡単ではないが、 XSS の防御を補助します。

The filtering is typically enabled by default, so adding the header typically just ensures it is enabled and instructs the browser what to do when a XSS attack is detected.

絞り込みは通常デフォルトで有効になっています。よって、ヘッダーを追加すると、 XSS 攻撃が検出された場合に何をすべきかをブラウザに指示します。

For example, the filter might try to change the content in the least invasive way to still render everything.

たとえば、フィルタは、最も侵襲的な方法でコンテンツを変更して、すべてをレンダリングしようとする可能性があります。

At times, this type of replacement can become a XSS vulnerability in itself.

時には、この種の置き換えはXSS脆弱性となることがあります。

Instead, it is best to block the content rather than attempt to fix it.

代わりに、コンテンツを修正しようとするのではなく、ブロックするのが良い。

To do this we can add the following header:

これには次のヘッダーを追加します。

X-XSS-Protection: 1; mode=block

This header is included by default.

このヘッダーはデフォルトで含まれています。

However, we can customize it if we wanted. For example:

しかしながら、私たちは任意にカスタマイズができます。たとえば、

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

    <headers>
        <xss-protection block="false"/>
    </headers>
</http>

Similarly, you can customize XSS protection within Java Configuration with the following:

同様に、次のように Java Configuration で XSS 保護をカスタマイズできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .xssProtection()
            .block(false);
}
}

20.1.5 X-Frame-Options

正しさの保証なんてものはない。

※印で始まる文章は本文にはない、私個人の感想やコメント・注釈です。

20.1.5 X-Frame-Options

Allowing your website to be added to a frame can be a security issue.

Web サイトをフレームに追加できることを許可すると、セキュリティの問題が発生する可能性があります。

For example, using clever CSS styling users could be tricked into clicking on something that they were not intending (video demo).

例えば、賢い CSS スタイルは、ユーザーに意図しないものをクリックするよう騙すことができます。

デモムービー

※マウスに追随する形で <iframe> を動かし、透明にすることで別ページのボタンを気付かないうちにクリックできるようにしている。

For example, a user that is logged into their bank might click a button that grants access to other users.

例えば、銀行のサイトにログインしたあるユーザが、他のユーザへのアクセス権を付与するボタンを押すかもしれません。

This sort of attack is known as Clickjacking.

これはクリックジャッキング攻撃の一種として知られています。

Another modern approach to dealing with clickjacking is to use Section 20.1.7, “Content Security Policy (CSP)”.

クリックジャッキングを扱う他の最近のアプローチについては Section 20.1.7, “Content Security Policy (CSP)” を使用してください。

There are a number ways to mitigate clickjacking attacks.

クリックジャッキング攻撃を緩和する方法はいくつかあります。

For example, to protect legacy browsers from clickjacking attacks you can use frame breaking code.

例えば、レガシーなブラウザでクリックジャッキング攻撃を防ぐ方法として、 frame breaking code というものがある。


Frame Breaking Code について

X-Frame-Options-Header ヘッダーをサポートしていないレガシーなブラウザでも、 <iframe> を使ったクリックジャッキング攻撃ができないようにするための対策方法。

ページが <iframe> 経由で読み込まれているかどうかを判定して、 <iframe> 経由で表示されている場合は現在の URL を強制的に <iframe> 内部の URL で書き換えてしまう。

そうすることで、気付かないうちに <iframe> 内のボタンを押させられていた、といったことを防ぐ。

要するに <iframe> 経由でページを読み込めないように強制してしまうことで、クリックジャッキング攻撃を防ぐという手法。

具体的には次のような html と JavaScript をページ内に記述することで実現できる。

<!-- 現在のページ全体を強制的に非表示にする CSS 設定 -->
<style id="antiClickjack">body{display:none !important;}</style>
if (self === top) {
        // iframe を利用せず直接開かれた場合は、すぐに <style> タグを除去する
        var antiClickjack = document.getElementById("antiClickjack");
        antiClickjack.parentNode.removeChild(antiClickjack);
} else {
        // iframe 経由で読み込まれたらこっちが実行されて、ページの URL が強制的に書き換わる
        top.location = self.location;
}

While not perfect, the frame breaking code is the best you can do for the legacy browsers.

しかし、これは完全ではありません。 frame breaking code はレガシーブラウザでのベストな方法です。

A more modern approach to address clickjacking is to use X-Frame-Options header:

クリックジャッキングへのより現代的なアプローチは、 X-Frame-Options ヘッダーを使うことです。

X-Frame-Options: DENY

The X-Frame-Options response header instructs the browser to prevent any site with this header in the response from being rendered within a frame.

X-Frame-Options のレスポンスヘッダーは、レスポンスにこのヘッダーがある場合、任意のサイトでフレーム内でレンダリングされることを防ぐようブラウザに指示します。

By default, Spring Security disables rendering within an iframe.

デフォルトでは、 Spring Security は iframe でのレンダリングは無効にしています。

You can customize X-Frame-Options with the frame-options element.

あなたは X-Frame-Options<frame-options> 要素でカスタマイズすることができます。

For example, the following will instruct Spring Security to use “X-Frame-Options: SAMEORIGIN” which allows iframes within the same domain:

例えば、以下は Spring Security に同一ドメインでのフレームの利用を許可するよう X-Frame-Options: SAMEORIGIN を使って指示しています。

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

    <headers>
        <frame-options
        policy="SAMEORIGIN" />
    </headers>
</http>

Similarly, you can customize frame options to use the same origin within Java Configuration using the following:

同様に、Java Configuration だと次のような方法で同一オリジンでのフレームの使用を許可するようカスタマイズできます。

@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
    // ...
    .headers()
        .frameOptions()
            .sameOrigin();
}
}

JJUG CCC 2016 Fall で話してきました

JJUG CCC 2016 FallJPA について話してきました。

懇親会やTL上でアウトプット重要という言葉を何度も目にし耳にし、色んな人がハイレベルな感想とかを上げていらっしゃるのを見てて、「僕もせな」と思い、発表に至った経緯(想い)について書いてみることにします。

発表資料は Qiita に上げています。

JPA と DDD の関係で僕が思っていること - Qiita

あと、当日 Java EE アドベントカレンダーの3日目の記事も上げましたのでよろしくどうぞ。

JPA マッピングカタログ - Qiita

CCCは今まで日帰りで見るだけの参加でしたが、今回初めて話す側で参加しました。

なぜ話す側で参加することにしたのか、理由は3つほどあります。

  1. JPAが誤解によって使いづらいと思われてないだろうか? という個人的な考えを言いたかった

  2. 僕よりJPAについて詳しい人からマサカリを引っ張り出す

  3. 懇親会ぼっち対策

1について、JPAHibernateに関して僕個人が知る範囲では、好意的な意見はほとんど聞いたことがありませんでした。 だいたいが使いづらかったり、複雑な挙動で苦労している話だと思います。

今まさにお仕事をしている現場でも、Hibernateに対して悪いイメージが溜まっています。
しかし、その使われ方は発表資料の最初の方にあるような、シンプルなDBアクセスライブラリ的なもので、ユニットオブワークも「なんとか使わないようにしている」といった使われ方でした。

それを見ていて、「それはHibernateが悪いのではなくて、使い方を間違ってるだけなのでは?」「レーシングカーで一般道を走ってて、走りづらいなぁ、と言っているだけでは?」という思いが自分の中で溜まっていきました。

個人的にJPAは、オブジェクト指向で全部頑張るという、実現しようと思ったら色々技術的に大変で険しく、誰もが途中で諦めた道を頑張って作っているというイメージがあります。
ちょうど Fate Zero の、オケアノスというあるかどうかも分からない子供の頃の夢に全人生を捧げたイスカンダルのような感じです(イスカンダルは忠誠を誓った臣下を丁重に扱うのに対し、 JPA は信じた分だけ裏切りが待ってるという違いはありますが)。

いろんなところでJPA複雑すぎ、Hibernateは無い、という意見をちらほら見る気がするので、もしそれらの意見も同じように使い方が間違ってるだけなら、なんだかJPAがかわいそうだなぁ、という想いがあり、今回発表に踏み切ったという次第です。

と言っても、JPAの目指している(と僕が思っている)理想は非常に高く、現実に実践しようと思ったら様々な問題があるんだろうなぁ、とも思っています。
すぐ思いつくものとしたら、パフォーマンスとのジレンマは避けては通れない気はしてます。

また、それ以外にも僕の知らない様々な落とし穴がある気がしてます。
僕のような経験の浅い若造が考えたことなんて、きっと間違いがあるはずです。

ということで、この発表に対して辛酸舐め尽くした経験者からマサカリ(体験談)を出してもらうという二番目の目的がありました。

もしかしたら、大量の厳しいマサカリでズタボロになって二度と東京に行きたくなくなるかもという恐怖が、発表前からずっとありました。

今のところそこまで強烈なものは頂いていませんが、まだ気は抜けないかもしれません。。。
(このエントリをきっかけに致死レベルのマサカリがくるかもと思うと、ここまで書いた記事をすべて消して「楽しかったです!」とだけ書いて終わらせてしまおうか迷います)

ちなみに、この目標については懇親会で@megascusさんにマサカリを頂き、ひとまず達成できたと思ってます。

なんでも、ビジネスロジックを@Entity や @Embeddable に書くと、分散環境でJPAを使っていてキャッシュされシリアライズされたインスタンスがあった場合に、ロジックを修正したバージョンのソースをデプロイすると、デシリアライズ時にバージョン違いによるエラーが起こる、とのことです。

キャッシュや分散環境というのは全く考慮していなかったので、これは大きな収穫でした。
この辺をもうちょっとしっかり勉強しなければならないという、次の勉強の方向性が決まった感じです。


と、まぁここまでそれっぽい理由を並べておいて、実は3番目が最大の理由です。

当方極度の人見知り+口下手なので、何もせずに懇親会に出てもきっと辛いことになるのが目に見えていました。なので、発表して顔を知ってもらえれば少しはマシになるのでは、という思いが理由の大部分を占めていました。

これも功を奏したのか、いろいろな方とお話することができたので発表して良かったかなと思ってます。

最後の飛び入り LT については、@yy_yankさんへの無茶振りがあったところから(もしかして来るかも...?)→(いや、ないよなw)→(マジで来た?!)って感じでした。
結果として @okapies さん(テンパってて一瞬しかお顔を確認できなかったので、もし人違いでしたら申し訳ございません!)や @yoshioterada さんとお話できるきっかけにもなり、いい思い出になりました。振っていただいた @ihcomega さんには感謝です。

(ただ普段は無茶振りされるとフリーズするタイプの人間なので、お手柔らかにお願いします...)

LT 資料も Qiita に上がっていますので、よろしければどうぞ。

Scala上でアセンブリでFizzBuzz - Qiita


という感じで、発表した目的についてはだいたい達成できたのかなぁと思うところです。

今回は自分の発表でいっぱいいっぱいだったので、次回はまた聞く専門になってじっくりセッションを楽しみたいかなぁと思いました。

皆様、ありがとうございました!


これとても思いました!