Play Framework を始めたばかりの方向けに、サンプルを進めるうえで困ったところを共有する目的で書いています。
Play Framework 2.8.x のScala 用フォーム入力サンプルに、 都道府県を選択するメニューを追加したときのメモです。
セキュリティ面で考えたことをまとめるためメモです。
免責事項
博多南ウェブサービス(以下、筆者)は、コンテンツを掲載するにあたって、その内容、機能等について細心の注意を払っておりますが、コンテンツの内容が正確であるかどうか、最新のものであるかどうか、安全なものであるか等について保証をするものではなく、何らの責任を負うものではありません。また、筆者は通知することなく掲載した情報の訂正、修正、追加、中断、削除等をいつでも行うことができるものとします。 また、コンテンツのご利用により、万一、ご利用者に何らかの不都合や損害が発生したとしても、筆者は何らの責任を負うものではありません。
以下、目次
- 免責事項
- 方針
- IPA のチェックリストを確認
- Play Framework 2.8.x (以下、play)でのセキュリティ機能確認しつつ、IPA のチェックリストとplay の機能の対応表作成
- play のデフォルト設定、追加するべき設定のまとめ作成
方針
- IPA のチェックリストを確認
- Play Framework 2.8.x (以下、play)でのセキュリティ機能確認しつつ、IPA のチェックリストとplay の機能の対応表作成
- play のデフォルト設定、追加するべき設定のまとめ作成
こんな感じで。
IPA のチェックリストを確認
以下のものを参考にしました。
IPA(独立行政法人情報処理推進機構)「安全なウェブサイトの作り方」(https://www.ipa.go.jp/security/vuln/websecurity.html)(最終確認日:2021/02/22)
より引用。
ウェブアプリケーションのセキュリティ実装(第1章の抜粋) 「安全なウェブサイトの作り方」第1章では、ウェブアプリケーションのセキュリティ実装として、下記の脆弱性を取り上げ、発生しうる脅威、注意が必要なサイト、根本的解決および保険的対策を示しています。下記に第1章を脆弱性ごとに抜粋した内容を掲載しています。 1.1 SQLインジェクション 1.2 OSコマンド・インジェクション 1.3 パス名パラメータの未チェック/ディレクトリ・トラバーサル 1.4 セッション管理の不備 1.5 クロスサイト・スクリプティング 1.6 CSRF(クロスサイト・リクエスト・フォージェリ) 1.7 HTTPヘッダ・インジェクション 1.8 メールヘッダ・インジェクション 1.9 クリックジャッキング 1.10 バッファオーバーフロー 1.11 アクセス制御や認可制御の欠落
Play Framework 2.8.x (以下、play)でのセキュリティ機能確認しつつ、IPA のチェックリストとplay の機能の対応表作成
チェックリストの内容 -> play の機能にあるのかという感じで探しました。
1 SQLインジェクション
SQL文の組み立ては全てプレースホルダで実装する。
-> play のドキュメントにあるPaly Slick と、Anorm にはprepared statements 機能、プレースホルダ機能がある。 なのでplay 機能にはあるが、気にすべきこと。
SQL文の構成を文字列連結により行う場合は、アプリケーションの変数をSQL文のリテラルとして正しく構成する。
ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない。
-> この辺は、play の機能ではなくどう実装するかだと思う。 なのでplay 機能にはなく、気にすべきこと。
2 OSコマンド・インジェクション
シェルを起動できる言語機能の利用を避ける。
-> Scala ではscala.sys.process package が標準としてある。
また、CVE-2020-2200 では、Jenkins Play Framework Plugin での脆弱性が報告されている。
なのでplay 機能にはなく、気にすべきこと。
3 パス名パラメータの未チェック/ディレクトリ・トラバーサル
外部からのパラメータでウェブサーバ内のファイル名を直接指定する実装を避ける。
ファイルを開く際は、固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする。
-> play ではpublic フォルダに公開するファイルを置く。また、 Play 2.6.16以降ではWindows における脆弱性が対応されている。 なのでplay 機能にはあり、(public フォルダを使えば)気にする必要はない。
4 セッション管理の不備
セッションIDを推測が困難なものにする。
セッションIDをURLパラメータに格納しない。
-> play 2.x ではsession.getId() のようなセッションIDを取得するメソッドがない。2.6 以降 session cookieはJSON Web Token (JWT) format を利用し、秘密鍵により署名される。 なのでplay 機能にはなく、(セッションID が必要なら)気にすべきこと。
HTTPS通信で利用するCookieにはsecure属性を加える。
-> デフォルトはfalse。 なのでplay 機能にはあるが、気にすべきこと。
ログイン成功後に、新しくセッションを開始する。
ログイン成功後に、既存のセッションIDとは別に秘密情報を発行し、ページの遷移ごとにその値を確認する。
-> これらは、play 機能にはなく、(セッションID が必要なら)気にすべきこと。
5 クロスサイト・スクリプティング
ウェブページに出力する全ての要素に対して、エスケープ処理を施す。
-> play の標準テンプレートエンジンであるTwirl では、 標準で出力する要素に対してエスケープ処理をやっている。 なのでplay 機能にはあり、(@html を使わなければ)気にする必要はない。
URLを出力するときは、「http://」や 「https://」で始まるURLのみを許可する。
-> 関係しそうなplay 機能を見つけられませんでした。 なのでplay 機能にあるか不明。気にすべきこと。
要素の内容を動的に生成しない。
-> 関係しそうなplay 機能を見つけられませんでした。 なのでplay 機能にあるか不明。気にすべきこと。
スタイルシートを任意のサイトから取り込めるようにしない。
-> 関係しそうなplay 機能を見つけられませんでした。 なのでplay 機能にあるか不明。気にすべきこと。
入力されたHTMLテキストから構文解析木を作成し、スクリプトを含まない必要な要素のみを抽出する。
-> 関係しそうなplay 機能を見つけられませんでした。 なのでplay 機能にあるか不明。気にすべきこと。
HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)の指定を行う。
-> play ではデフォルト設定で、テキストベースのHTTPレスポンスにcharset=UTF-8 を指定する。 なのでplay 機能にはあり、気にする必要はない。
6 CSRF(クロスサイト・リクエスト・フォージェリ)
処理を実行するページを POST メソッドでアクセスするようにし、その「hidden パラメータ」に秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する。
-> play の機能ではなくどう実装するかだと思う。 なのでplay 機能にはなく、気にすべきこと。
処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。
-> play の機能ではなくどう実装するかだと思う。 なのでplay 機能にはなく、気にすべきこと。
Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する。
-> play の機能ではなくどう実装するかだと思う。 なのでplay 機能にはなく、気にすべきこと。
7 HTTPヘッダ・インジェクション
ヘッダの出力を直接行わず、ウェブアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する。
改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しないよう、開発者自身で適切な処理を実装する。
-> これらは、play ではヘッダーへの追加にwithHeaderメソッドを使用する。 なのでplay 機能にはあり、気にする必要はない。
8 メールヘッダ・インジェクション
メールヘッダを固定値にして、外部からの入力はすべてメール本文に出力する。
ウェブアプリケーションの実行環境や言語に用意されているメール送信用APIを使用する(8-(i) を採用できない場合)。
HTMLで宛先を指定しない。
-> これらは、play のプラグインで設定し、使用する。 なのでplay 機能にはあるが、気にすべきこと。
9 クリックジャッキング
HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する。
-> play では2.6以降、デフォルト設定で"DENY"となる。 なのでplay 機能にはあり、気にする必要はない。
処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは、再度入力されたパスワードが正しい場合のみ処理を実行する。
-> play の機能ではなくどう実装するかだと思う。 なのでplay 機能にはなく、気にすべきこと。
10 バッファオーバーフロー
直接メモリにアクセスできない言語で記述する。
直接メモリにアクセスできる言語で記述する部分を最小限にする。
-> これらは、play の機能ではない。 なのでplay 機能にはなく、(Scalaを使うなら)気にする必要はない。
脆弱性が修正されたバージョンのライブラリを使用する。
-> これらは、play の機能ではない。 なのでplay 機能にはなく、気にすべきこと。
11 アクセス制御や認可制御の欠落
アクセス制御機能による防御措置が必要とされるウェブサイトには、パスワード等の秘密情報の入力を必要とする認証機能を設ける。
認証機能に加えて認可制御の処理を実装し、ログイン中の利用者が他人になりすましてアクセスできないようにする。
-> play の機能ではなくどう実装するかだと思う。 なのでplay 機能にはなく、気にすべきこと。
play のデフォルト設定、追加するべき設定のまとめ作成
まとめたもの。 いい感じでまとまるかと思いましたが、まとまりませんでした。
以上でした。