バックエンドのスタンダード:Laravel入門
■第6話:Laravelのセキュリティ慣行
(最終更新日:2024.11.26)
(絵が小さい場合はスマホを横に)
「セキュリティ機能について理解しよう」
今回は、Laravelアプリケーションのセキュリティを強化するためのベストプラクティスについて学ぶ。
ここでは、XSS(クロスサイトスクリプティング)やSQLインジェクションなどの一般的な攻撃手法を防ぐための対策に加え、
CSRF(クロスサイトリクエストフォージェリ)保護や、セキュリティ関連パッケージの活用方法についても詳しく解説する。
より安全で信頼性の高いアプリケーションを構築するための知識と技術を身につけよう。
1.セキュリティのベストプラクティス
Laravelはセキュアなアプリケーションを構築するためのさまざまなツールと機能を提供している。
このセッションでは、Laravelのセキュリティのベストプラクティスを詳しく説明する。
Laravelでは以下の9項目に加え、SQLインジェクション対策を備えている。9項目に関して説明する。
1.1 CSRF(クロスサイトリクエストフォージェリ)保護
LaravelはデフォルトでCSRF保護を提供している。
フォームでCSRFトークンを生成し、それを検証することで、外部からの不正なリクエストを防ぐ。
@csrfがトークン生成にあたる。
CSRF(クロスサイトリクエストフォージェリ)保護
1.2 エスケープ出力(XSS対策)
Bladeテンプレートでは、データの出力時に自動的にエスケープ処理を行う。
HTMLのタグを直接出力できないようにしている。
これにより、XSS(クロスサイトスクリプティング)攻撃を防ぐ(下記の上段)。
エスケープを行わない出力が必要な場合は、以下のように「!!」で括って記述する(下記の下段)。
エスケープ処理
1.3 バリデーション
ユーザー入力は常にサーバーサイドでバリデーションを行う。
下記では型や文字数など入力できる値を指定している。
これにより、悪意のあるデータがアプリケーションに流入するのを防ぐ。
バリデーション
1.4 認証と認可
前回説明したLaravelの認証機能を使用して、ユーザーの認証を行う。
また、ポリシーやゲートを利用して、ユーザーが特定のアクションを実行できるかどうかを制御する。
認証と認可
1.5 パスワードのハッシュ化
Laravelはパスワードを安全にハッシュ化するための機能を提供する。
ユーザーのパスワードは常にハッシュ化して保存する。
パスワードのハッシュ化
1.6 環境変数の使用
データベース接続情報やAPIキーなどの機密情報は環境変数に保存する。
これにより、コードベースから機密情報を分離する。
環境変数の保存先(上)と取得(下)
1.7 HTTPSの使用
アプリケーション全体でHTTPSを使用することで、データの盗聴や改ざんを防ぐ。
Laravelのミドルウェアを使用して、HTTPSを強制できる。
ミドルウェアによるhttpsの強制
1.8 セキュリティヘッダー
セキュリティヘッダーを設定することで、クリックジャッキングやXSS攻撃などを防ぐ。
ヘッダーの設定はミドルウェアを使用して行う。
セキュリティヘッダー
1.9 ログイン試行の制限
LaravelのThrottleRequestsミドルウェアを使用して、ログイン試行の回数を制限する。
下記では10回に制限している。これにより、ブルートフォース攻撃を防げる。
ThrottleRequestsによる制限
Laravelは、上記の9項目を含めた強力なセキュリティ機能を提供しており、これを活用することで安全なアプリケーションを構築することができる。 CSRF保護、エスケープ出力、バリデーション、認証と認可、パスワードのハッシュ化、環境変数の使用、HTTPSの使用、 セキュリティヘッダーの設定、ログイン試行の制限など、多層的なセキュリティ対策を講じることが重要だ。 次項以降ではCSRFやXSS、SQLインジェクションなど、攻撃対象になりやすいものへの対策に関して、より詳しく説明する。
2.CSRF保護
CSRF(クロスサイトリクエストフォージェリ)は、ユーザーが意図しないアクションをWebアプリケーションに対して実行させられる攻撃手法だ。
LaravelはデフォルトでCSRF保護機能を提供しており、この種の攻撃から守ることができる。
2.1 CSRF保護の仕組み
Laravelは、CSRF保護のためにトークンを使用する。
CSRFトークンは、フォーム送信時に生成され、サーバー側で検証されるユニークな文字列だ。
これにより、不正なリクエストがブロックされる。
CSRFトークンの生成に関しては、1.1の部分で説明した通りで、これによりトークンが生成される。
@csrfには、具体的には下記のような隠しフィールドが生成されている。
生成される隠しフィールド
2.2 CSRFトークンの検証
Laravelは、受信したリクエストのCSRFトークンを自動的に検証する。
CSRFトークンが一致しない場合、リクエストは拒否される。
これにより、本来行って良い場所以外からの不正なリクエストが防止される。
2.3 CSRF保護の無効化
特定のルートに対してCSRF保護を無効にしたい場合は、ミドルウェアの例外を設定する。
通常は避けるべきだが、APIエンドポイントなどで必要な場合はこれを使う。
本来の場所以外からでも、リクエストを行うことができる。
必要最小限を意識して使おう。
ユーザー登録ビュー
2.4 AJAXリクエストでのCSRFトークン
AJAXのリクエストでもCSRFトークンを送信する必要がある。
その場合、一般的にはJavaScriptを使用してCSRFトークンをヘッダーに追加する。
ユーザー登録ビュー
そして、metaタグを使用して、CSRFトークンをHTMLドキュメントに埋め込む。 これにより、AJAXリクエストでもCSRFトークンが正しく送信され、サーバー側で検証される。
メタタグへの埋め込み
3.XSSとSQLインジェクションの防止
Webアプリケーションのセキュリティには、XSS(クロスサイトスクリプティング)とSQLインジェクションの防止が非常に重要だ。
Laravelはこれらの攻撃からアプリケーションを守るためのツールとベストプラクティスを提供している。
3.1 XSS(クロスサイトスクリプティング)の防止
XSS攻撃は、攻撃者が悪意のあるスクリプトをWebページに埋め込み、他のユーザーがそのページを閲覧したときにスクリプトが実行される攻撃だ。
これにより、ユーザーのクッキー情報やセッション情報が盗まれる可能性がある。
LaravelのBladeテンプレートエンジンは、デフォルトでエスケープ処理を行うため、XSS攻撃を防ぐことができる。
1.2項で説明したとおりだ。また、HTMLPurifierのようなサードパーティのサニタイズライブラリを使ってもよい。
JavaScriptの不正な使用をさせないようにできるだろう。
3.2 SQLインジェクションの防止
SQLインジェクションは、攻撃者がSQLクエリを実行し、データベースに対して不正な操作を行う攻撃だ。
これにより、データの漏洩や破壊が発生する可能性がある。
LaravelのEloquent ORMやクエリビルダは、パラメータバインディングを使用して、SQLインジェクションを防ぐ。
formなどの入力値を後からバインディングすることで、
セミコロン(;)やコーテーション(’)などをSQLの命令として認識させず、通常の文字として扱うことができる。
クエリビルダ(Eloquentよりも細かな設定が可能)も同様にパラメータバインディングを使用している。
これにより、FORMなどにSQLを操作する情報を入れたとしても、そのまま実行されることはない。
LarabelのSQLインジェクション防止
生のSQLクエリを使用する場合は、明示的にパラメータバインディングを行うことが重要だ。 下記ではパラメータを「?」にして、そこに[$email]の値をバインディングさせている。 この方法を使用することで、入力データが適切にエスケープされ、SQLインジェクション攻撃が防止される。
生のSQLクエリでのパラメータバインディング
Laravelは、基本的にはXSSやSQLインジェクション攻撃から保護される仕組みになっている。 注意すべきは、非エスケープ処理をした場合や生SQLを使う場合である。 それらを使う場合は、第三者から不正な情報を混入される可能性があるということを覚えておこう。
4.セキュリティ関連パッケージ
Laravelエコシステムには、アプリケーションのセキュリティを強化するための、さまざまなパッケージが用意されている。 これらのパッケージは、認証、認可、暗号化、入力データのサニタイズなど、さまざまなセキュリティ関連の機能を提供する。 ここでは、Laravelでよく使われるセキュリティ関連のパッケージを紹介する。
4.1 Laravel Sanctum
Laravel Sanctumは、SPA(シングルページアプリケーション)、モバイルアプリケーションなどに、
シンプルなAPIトークンベースの認証を提供するパッケージだ。
APIトークンの生成と管理ができ、SPAおよびモバイルアプリケーション用のセッションベースの認証ができるという特徴がある。
シンプルなセットアップが可能である。下記では、最初にインストールのためのコマンド、
次にLaravel上での設定、最後にマイグレーションの実行を行って、実装している。
Laravel Sanctumのインストールと設定
これにより、APIトークンの生成とデータベースへのトークンの保存を行うことができる。 Sanctumが良いのは、トークンベースの認証が非常に簡単に管理でき、トークンの発行、取り消し、スコープの設定などが簡単に行える点である。 クッキーを利用したセッションベースの認証とAPIトークンを組み合わせたハイブリッドな認証方式を簡単に実装できる。 2.4で説明したCSRF保護も、デフォルトで有効になっているため、CSRF攻撃にも対応できる。 近年、フロントエンドとバックエンドを分けて開発することが多い。 デフォルトでこれらの開発を支援するセキュリティ機能が実装されているのは非常にありがたい。
4.2 Laravel Passport
Laravel Passportは、OAuth2サーバーを構築するためのパッケージだ。
これにより、完全なOAuth2認証をアプリケーションに追加することができる。
こちらも、コマンド入力と簡単な設定だけで実装することができる。
4.3 Laravel Cashier
Laravel Cashierは、StripeやBraintreeを使用したサブスクリプション課金システムを簡単に統合するためのパッケージだ。
こちらも、コマンド入力と簡単な設定だけで実装することができる。
4.4 Laravel Socialite
Laravel Socialiteは、OAuthプロバイダ(Facebook、Twitter、Google、GitHubなど)を通じてソーシャル認証を簡単に統合するためのパッケージだ。
Laravelには多くのセキュリティ関連パッケージがあり、アプリケーションのセキュリティを強化するための多くの機能を提供している。 これらのパッケージを適切に使用することで、認証、認可、データサニタイズなど、さまざまなセキュリティ要件を満たすことができる。 セキュリティのベストプラクティスを守り、適切なパッケージを使用することで、Laravelアプリケーションをより安全に保つことができる。
5.まとめ
今回は、Laravelアプリケーションのセキュリティ強化のためのベストプラクティスを学んだ。 CSRF保護、XSS防止、SQLインジェクション対策の基本的な方法を学び、 Laravelが提供する各種セキュリティ関連パッケージ(Sanctum、Passport、Cashier、Socialite、HTMLPurifier)を理解することができた。 これにより、認証、認可、データサニタイズなどの多層的なセキュリティ対策をでき、 安全で信頼性の高いアプリケーションの構築方法を学べたと思う。
▼参考図書、サイト
「改定2版 速習Laravel」 山田祥寛 WINGSプロジェクト
「1週間で基礎から学ぶLaravel入門」 Minatomi