Djangoの設定で x-xss-protection の設定を追加する
どーも。ばぁどです。
最近諸事情ありまして、より専門的なサイバーセキュリティの知見を得ております。
今回はXSSの対策の一つである X-XSS-Protection
を Django に付与する方法です。
XSS とは?
開発者が意図しないJavaScriptが攻撃者により実行されてしまうWebアプリケーションの脆弱性です。
詳細は下記の筆者の過去記事を参考してください。
そもそもDjangoのXSS対策は?
基本はHTMLへのアウトプット時に Django の機能によりエスケープ処理がされています。Djangoが持っているHTMLテンプレートのルール通りに記述すれば大丈夫です。
詳しくは下記を参考にしてください。
しかし、上記のDjangoの設定に加えて、サーバー側でx-xss-protection
の設定を付与しておくことで、さらにXSSに対して堅牢なシステムを構築することが可能です。
X-XSS-PROTECTION とは
サーバー側で設定することで、ブラウザ側で実行されそうな XSS
のスクリプトを無効化するような設定です。近年は対応していないブラウザもあるようなのですが、過去のブラウザを使用していることを考慮するならば、今でも付けておく必要がありそうです。
HTTP の X-XSS-Protection レスポンスヘッダーは Internet Explorer, Chrome, Safari の機能で、反射型クロスサイトスクリプティング (XSS) 攻撃を検出したときに、ページの読み込みを停止するためのものです。強い Content-Security-Policy をサイトが実装して、インライン JavaScript の使用を無効にしていれば ('unsafe-inline')、現在のブラウザーではこれらの防御は大枠で不要なものですが、まだ CSP に対応していない古いウェブブラウザーを使用しているユーザーには防御になります。
現在のブラウザーではこれらの防御は大枠で不要なものです
英語
X-XSS-Protection: 1; mode=block Some browsers have the ability to block content that appears to be an XSS attack. They work by looking for JavaScript content in the GET or POST parameters of a page. If the JavaScript is replayed in the server’s response, the page is blocked from rendering and an error page is shown instead.
The X-XSS-Protection header is used to control the operation of the XSS filter.
To enable the XSS filter in the browser, and force it to always block suspected XSS attacks, you can pass the X-XSS-Protection: 1; mode=block header. SecurityMiddleware will do this for all responses if the SECURE_BROWSER_XSS_FILTER setting is True.
日本語訳
X-XSS-Protection: 1; mode=block 一部のブラウザにはXSS攻撃のように見えるコンテンツをブロックする機能があります。 これらはページのGETまたはPOSTパラメーターでJavaScriptコンテンツを探すことによって機能します。 サーバーの応答でJavaScriptが実行されると、ページのレンダリングがブロックされ、代わりにエラーページが表示されます。
X-XSS-Protectionヘッダーは、XSSフィルターの動作を制御するために使用されます。
ブラウザでXSSフィルタを有効にし、疑わしいXSS攻撃を常にブロックするように強制するには、X-XSS-Protection: 1; mode=block header を渡すことがで制御できます。 SecurityMiddlewareは、SECURE_BROWSER_XSS_FILTER設定がTrueの場合、すべての応答に対してこれを実行します。
SECURE_BROSER_XSS_FILTER
Djangoの全てのヘッダーに X-XSS-Protection
の設定を付与するためには、Djangoの設定ファイルに SECURE_BROWSER_XSS_FILTER
の設定を TRUE
にする必要があります。デフォルトでは False
です。
英語
Default: False
If True, the SecurityMiddleware sets the X-XSS-Protection: 1; mode=block header on all responses that do not already have it.
Modern browsers don’t honor X-XSS-Protection HTTP header anymore. Although the setting offers little practical benefit, you may still want to set the header if you support older browsers.
日本語訳
Default: False
Trueの場合、SecurityMiddlewareはX-XSS-Protection: 1; mode=blockを設定します。特別に設定されていないヘッダーにはすべてX-XSS-Protectionの設定がつきます。。
最近のブラウザは、X-XSS-Protection HTTPヘッダーを採用しなくなりました。 この設定は実用的なメリットはほとんどありませんが、古いブラウザをサポートしている場合は、ヘッダーを設定することをお勧めします。
実際につけてみる
django_manage/settings.py
~~~~~~~~~~~~~省略~~~~~~~~~~~~~ SECURE_BROWSER_XSS_FILTER = True
X-XSS-Protection を付与していない場合
Date: Wed, 19 May 2021 23:20:21 GMT Server: WSGIServer/0.2 CPython/3.7.2 Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN Vary: Cookie Content-Length: 15201 Set-Cookie: csrftoken=q6m56So4ENuJlxEJAtMJF64s8OoKyghbJBQh0odp7qAKK53OukP9tbZyM6Cprote; expires=Wed, 18-May-2022 23:23:18 GMT; Max-Age=31449600; Path=/
X-XSS-Protection を付与した場合
Date: Wed, 19 May 2021 23:23:18 GMT Server: WSGIServer/0.2 CPython/3.7.2 Content-Type: text/html; charset=utf-8 X-Frame-Options: SAMEORIGIN Vary: Cookie Content-Length: 15201 x-xss-protection: 1; mode=block Set-Cookie: csrftoken=q6m56So4ENuJlxEJAtMJF64s8OoKyghbJBQh0odp7qAKK53OukP9tbZyM6Cprote; expires=Wed, 18-May-2022 23:23:18 GMT; Max-Age=31449600; Path=/
Content-Length
の後ろに x-xss-protection
が付与されていることがわかりますね。