銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

【技術書メモ】安全なウェブサイトの作り方・安全なSQLの呼び出し方 〜毎週アウトプットチャレンジ③〜

毎週 1冊技術書を読んでブログでアウトプットするチャレンジの第三弾です〜!

今回は、安全なウェブサイトの作り方安全なSQLの呼び出し方(短いので2冊で1冊扱い)を読みました。

どちらもIPA独立行政法人 情報処理推進機構)が無料で公開しています。

f:id:ysk_pro:20180805204003j:plain

# はじめに

脆弱性対策には、根本的解決と保険的解決がある

根本的解決

- 脆弱性を作り込まない実装

- 根本的解決を実装することでその脆弱性を狙った攻撃を無効化できる

保険的対策

- 攻撃の影響を軽減する対策

- 根本的解決と違い、脆弱性の原因そのものを無くすものではないが、攻撃の影響を軽減できる
- 根本的解決の実装に漏れが生じる場合、保険的対策はセーフティネットとして機能するので、根本的解決と保険的対策を組み合わせるのが有効

 

1. ウェブアプリケーションのセキュリティ実装

設計や実装レベルでの対策

1) SQLインジェクション

根本的解決

- SQL文の組み立ては全てプレースホルダで実装する

- SQL文の組み立てを文字列連結で行う場合は、エスケープ処理を行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する

保険的対策

- エラーメッセージをそのままブラウザに表示しない 〜 攻撃者への手がかりを与えてしまう

- データベースアカウントに適切な権限を与える 〜 データベースに接続するアカウントの権限が必要以上に高いと攻撃による被害が深刻化する恐れがある

 

2) OSコマンド・インジェクション

- WebサーバのOSコマンドを不正に実行されてしまう問題

根本的解決

- シェルを起動できる言語機能の利用を避ける

保険的対策

- シェルを起動できる言語機能を利用する場合は、その引数を構成する全ての変数に対してチェックを行い、あらかじめ許可した処理のみを実行する

 

3) パス名パラメータの未チェック/ディレクトリ・トラバーサル

- パラメータにファイル名を指定しており、ファイル名指定の実装に問題がある場合、公開を想定していないファイルを参照されてしまう恐れがある

根本的解決

- 外部からのパラメータでWebサーバ内のファイル名を直接指定する実装は避ける

- ファイルを開く際は固定のディレクトリを指定し、かつファイル名にディレクトリ名が含まれないようにする

保険的対策

- Webサーバ内のファイルへのアクセス権限の設定を正しく管理する

- ファイル名のチェックを行う

 

4) セッション管理の不備

- セッションIDの発行や管理に不備がある場合、悪意のある人にログイン中の利用者のセッションIDを不正に取得され、その利用者になりすましてアクセスされてしまう可能性がある

根本的解決

- セッションIDを推測困難なものにする

- セッションIDをURLパラメータに格納しない

- HTTP通信で利用するCookieにはsecure属性を加える 〜 secure属性が設定されたCookieHTTPS通信のみで利用できる

- ログイン成功後に、新しくセッションを開始する

- ログイン成功後に既存のセッションIDとは別に秘密情報を発行し、ページ遷移ごとにその値を確認する

保険的対策

- セッションIDを固定値にしない

- セッションIDをCookieにセットする場合、有効期限の設定に注意する

 

5) クロスサイト・スクリプティング

- スクリプトを埋め込むことが可能な脆弱性がある場合、利用者のブラウザ上でスクリプトが実行される可能性がある

根本的解決

- Webページに出力するすべての要素に対して、エスケープ処理を施す

- URLを出力するときは、http://・https://で始まるもののみ許可する〜 javascript:の形式で始まるURLはクロスサイト・スクリプティング攻撃が可能になる場合がある

- <script>...</script>要素を動的に生成しない

- スタイルシートを任意のサイトから取り込めるようにしない

- HTTPレスポンスヘッダのContent-Typeフィールドに文字コード(charset)を指定する

保険的対策

- 入力値の内容チェックを行う

- Cookie情報の漏えい対策として、発行するCookieにHttpOnlyを加え、TRACEメソッドを無効化する

- クロスサイト・スクリプティング潜在的脆弱性対策として有効なブラウザの機能を有効にするレスポンスヘッダを返す

 

6) CSRF(クロスサイト・リクエスト・フォージェリ)

- ログインした利用者からのリクエストについて、その利用者が意図したリクエストであるかどうかを識別する仕組みを持たないwebサイトは、外部サイトを経由した悪意あるリクエストを受け入れてしまう場合がある

根本的解決

- 処理を実行するページPOSTメソッドでアクセスするようにし、そのhiddenパラメータに秘密情報が挿入されるよう、前のページを自動生成して、実行ページではその値が正しい場合のみ処理を実行する

- 処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは再度入力されたパスワードが正しい場合のみ処理を実行する

- Refererが正しいリンク元かを確認し、正しい場合のみ処理を実行する 〜 Refererを確認することで、本来の画面遷移を経ているかどうかを確認できる

保険的対策

- 重要な操作を行った際に、その旨を登録済みのメールアドレスに自動送信する

 

7) HTTPヘッダ・インジェクション

- HTTPレスポンスヘッダのフィールド値を外部から渡されるパラメータ等を利用して動的に生成する実装に対して、レスポンス内容に任意のヘッダフィールドを追加する攻撃

根本的解決

- ヘッダの出力を直接行わず、webアプリケーションの実行環境や言語に用意されているヘッダ出力用APIを使用する

- 改行コードを適切に処理するヘッダ出力用APIを利用できない場合は、改行を許可しないように開発者自身で適切な処理を実装する 〜 HTTPヘッダは改行によって区切られる構造になっており、改行を許すと任意のヘッダフィールドや任意のボディを注入されたり、レスポンスを分割されたりする原因となる

保険的対策

- 外部からの入力の全てについて、改行コードを削除する

 

8) メールヘッダ・インジェクション

- メール送信機能を持つwebアプリケーションにおいて、管理者が設定した本来固定のメールアドレスではない宛先にメールを送信され、迷惑メールの送信に悪用される

根本的解決

- メールヘッダを固定値にして、外部からの入力は全てメール本文に出力する 〜 to, cc 等のメールヘッダの内容が外部からの入力に依存する場合、外部から与えられた改行コードが差し込まれてしまい、任意のメールヘッダの挿入や、任意の宛先へのメール送信に悪用される原因になる

- メールヘッダを固定値にできない場合、webアプリケーションの実行環境や言語に用意されているメール送信用APIを使用する

- HTMLで宛先を指定しない

保険的対策

- 外部からの入力の全てについて、改行コードを削除する

 

9) クリックジャッキング

- ログインしている利用者のみが使用可能な機能を、細工された罠ページを重ね合わせてクリックさせることにより、意図せず実行させる

根本的解決

- HTTPレスポンスヘッダに、X-Frame-Optionsヘッダフィールドを出力し、他ドメインのサイトからのframe要素やiframe要素による読み込みを制限する

- 処理を実行する直前のページで再度パスワードの入力を求め、実行ページでは再度入力されたパスワードが正しい場合のみ処理を実行する

保険的対策

- 重要な処理は、一連の操作をマウスのみで実行できないようにする

 

10) バッファオーバーフロー

- プログラムが入力されたデータを適切に扱わない場合、プログラムが確保したメモリの領域を超えて領域外のメモリを上書きして、意図しないコードを実行してしまう可能性がある

根本的解決

- 直接メモリにアクセスできない言語で記述する 〜 Rubyはメモリに直接アクセスできないため、バッファオーバーフローの問題は発生しない

- 直接メモリにアクセスできる言語で記述する部分を最小限にする

- 脆弱性が修正されたバージョンのライブラリを使用する

 

11) アクセス制御や認可制御の欠落

根本的解決

- アクセス制御機能による制御措置が必要とされるwebサイトには、パスワード等の秘密情報の入力を必要とする認証機能を設ける

- 認証機能に加えて認可制御の処理を実装し、ログイン中の利用者が他人になりすましてアクセスできないようにする 〜 認可とはどの利用者にどの操作を許可するか制御すること

 

2. ウェブサイトの安全性向上のための取り組み

運用レベルでの対策

1) Webサーバに関する対策

- OSやソフトウェアの脆弱性情報を継続的に入手し、脆弱性への対処を行う

- 公開を想定していないファイルを、web公開用のディレクトリ以下に置かない

 

2) DNSに関する対策

- DNSによりドメイン名を指定するだけで、該当するwebサイトへのアクセスやメールの送受信が可能になってしまう

- DNSソフトウェアの更新や設定を見直す

 

3) ネットワーク盗聴への対策

- 通信や情報が暗号化されていない場合、盗聴によって取得された情報が悪用される可能性がある

- webサイトの通信を暗号化する手段として、SSLを用いたHTTPS通信がある

- 利用者へ通知する重要情報は、メールで送らず暗号化されたhttps:// のページに表示する

 

4) フィッシング詐欺を助長しないための対策

- EV SSL証明書を取得し、サイトの運営者が誰であるかを証明する

- 利用者がログイン後に移動するページをリダイレクト機能で動的に実装しているウェブサイトについて、リダイレクト先のURLとして使用されるパラメータの値には自サイトのドメインのみを許可するようにする

 

5) パスワードに関する対策

- 入力後の応答メッセージが認証情報の推測のヒントとならない工夫をする

- ユーザIDもしくはパスワードが違います、というような表示をすることで、ヒントを与えないようにする

- パスワードをサーバ内で保管する際は、平文ではなくソルト付きハッシュ値の形で保管する

- ソルトとは乱数等により利用者毎に異なる文字列を生成すること

 

6) WAFによるwebアプリケーションの保護

- WAF(Web Application Firewall)はHTTP(HTTPS)を検査し、攻撃等の不正な通信を自動的に遮断するソフトウェア・ハードウェア

- webアプリケーションの改修が困難な状況でWAFが有効

 

おわりに

これら内容は分かっていないとwebエンジニアとして話にならないと思うので早く身につけます…!!

こちら(↓)の記事で紹介した本を順番にアウトプットしていく予定ですー!

ysk-pro.hatenablog.com

参考にしてみてください〜!

来週も頑張ります!