
クロスサイトリクエストフォージェリー(CSRF)はDrupalにおける一般的な脆弱性ですが、これを防ぐ事はさほど難しい事ではありません。この記事では、開発者がまず適切で安全なコードを書けるようになること、そして既存のコードに見つかった場合に脆弱性を修正できることを目的としています。
まず、CSRFについて理解する必要があります。詳しくは、クロスサイトリクエストフォージェリーとは?をご覧ください。
DrupalのCSRFに対するフォームの使用
開発者は(2006年5月の)Drupal 4.7のリリース時点で、フォームの作成、検証、送信処理の中心となるDrupalコアのForm APIを使用しています。その作成と検証の一部は、フォーム送信時に特別なトークンがユーザーに送信され、検証されるように保証することです。 Drupalは、少なくとも以下の3つの値で構成されるハッシュを使用します。
- ユーザーセッションID
- 実行されるアクションに関連付けられた文字列
- サイトに対してプライベートな文字列
攻撃者がこのトークンを解析できれば、そのトークンをリクエストに追加する事で、サイトで強制的にアクションを実行させることができます。幸いにも、この情報を簡単に解析することはできません。 (トークンを解析するには、多くのコンピュータリソースと、セッションの固定などのさらなる弱点が必要になります。しかし、こういった事はほとんどありません。)
実際にフォームを作成する際には Forms APIクイックスタート・ガイドを参考にしてください。サイト上のデータ変更を伴う、あらゆるアクションにフォームを使用することでCSRFを防ぐことができます。
デザインやユーザーインターフェイスの都合上フォームが機能しない場合があり、代わりにとして、小さなリンクが必要となる場合もあります。ユーザーの削除やコンテンツの削除など、潜在的に破壊的な操作のリンクを使用する場合には、確認フォームを使用して、ユーザーがアクションを実行していることを確認する必要があります。
注意
ユーザビリティの改善に関わる人々は、確認フォームを使用すべきではないと言います。これは確かにユーザービリティの観点から言えば正しいと言えます。彼らの懸念としては、確認フォームを使用すると、フォーム入力時の流れがスムーズでなくなる事です。この解決策としては、簡単に取り消し可能な方法でデータを保存することです。
実際に確認フォームをどのように作成したら良いでしょうか?とても良い例として、 User protectモジュールのコードをご覧下さい。このパッチから実例学ぶことができます。
トークンを直接利用することでDrupalのアクションを保護する
実行しようとしているアクションが削除ほど重大でない場合はどうした良いでしょうか?
その場合、Drupalのトークン生成を直接利用するという別の方法を使用することができます。 良い例として、Security Reviewモジュールのコードをご覧ください。
security_review_reviewed ファンクション内のリンクにトークンを追加します。
$token = drupal_get_token($check['reviewcheck']);
$link_options = array(
'query' => array('token' => $token),
'attributes' => array('class' => 'sec-rev-dyn'),
);
そのトークンはsecurity_review_toggle_checkでチェックされます:
if (!drupal_valid_token($_GET['token'], $check_name)) {
return drupal_access_denied();
}
さまざまな方法でトークンをリンクに挿入し、AJAXコードを記述してリクエストを送信し、リクエストを検証することができます。 基本的な考え方は、アクションのリクエストと共に返されるトークンをページに追加し、アクションを実行される前にトークンを検証することです。
注意
多くの人は、サイト上でリンクに応答するアクションを実行する事は不適切だと思うのではないでしょうか。(それはPOSTリクエストとは対照的にHTTP GETリクエストを開始します。これは、一般的にフォーム内で使用され、サーバー上でデータを変更する際のHTTP仕様として定義されます。)
また、ページ内の全てのリンクを先読みするHTTPアクセラレーターのようなリンクを利用する場合に潜在的な問題となります。 リンクにrel = "nofollow"属性を追加することで、先読みを軽減できますが、先読みは最近ではあまり利用されることが少なくなってきているので、場合によっては対処する必要はないかもしれません。
終わりに
この記事で解説されているように Form API を適切に利用すれば簡単な実装でCSRF対策を行えます。
システム管理者向けのフォームを生成する場合は、 system_settings_form を使うことにより drupal_get_token/drupal_set_token を直接呼び出すことなくフォームを保護できます。
逆に、テンプレートにformタグ全体を直接マークアップするような実装は、脆弱性を引き起こす可能性があるので注意が必要です。
おすすめ記事
関連コンテンツ
- Drupal 10とは?長所・短所とDrupal 11の進化ポイントを徹底解説!
- DrupalとWordPressの違い─どちらのCMSを採用すべきか
- Drupal CMS 1.0がリリースされました
- Drupalテーマ開発における革新的な機能: Single Directory Components (SDC)
- DrupalにおけるAI:驚くべき機能の最新デモが示す未来
- Drupal CMSの今後の展望
- DDEVを用いてDrupal CMS(Drupal Starshot)をインストールする
- Dries Buytaert氏の基調講演が明らかにしたDrupalの未来
- 大規模サイトのCMS選定基準 - インフラコストと運用負荷の最適化ガイド
- DrupalベースのEC構築事例 - インフラコストを抑えた大規模サイト運用
Drupal 初心者講座バックナンバー
-
Drupal 9/10 初心者講座
-
第 1 回 歴史に見る Drupal の DNA
-
第 2 回 Drupal はフレームワークか?CMS か?他の CMS との比較
-
第 3 回 Drupal の特徴
-
第 4 回 Drupal 9 / 10 のインストール (1)
-
第 5 回 Drupal 9 / 10 のインストール (2)
-
第 6 回 Drupal にコンテンツを投稿してみる
-
第 7 回 Drupal のボキャブラリとタクソノミーの使い方
-
第 8 回 コンテンツ管理における Drupal と他の CMS との比較
-
第 9 回 Drupal のブロックシステム
-
第 10 回 Drupal の標準クエリビルダー Views の使い方
-
第 11 回 Drupal と他の CMS のクエリビルダー機能を比較
-
第 12 回 Drupal の多言語機能と他の CMS やサービスとの比較
-
第 13 回 Drupal の権限設定と WordPress や Movable Type との比較
-
第 14 回 Drupal のテーマシステムについて
-
第 15 回 Drupal の拡張モジュールの選定と使い方
-
第 16 回 Drupal をもっと知りたい方に向けた各種情報