※この記事は「2021年5月2日」に更新しました。
前回は、mb_send_mail関数で、メール送信する方法を紹介しました。
今回は、PHP のセキュリティについて。
PHP のセキュリティ対策
PHP で Webアプリケーションを開発する場合、必ず考えなければいけないことが、セキュリティ対策です。
色々なことが比較的容易にできてしまうため、間違った作り方をしていると、開発したサイトがハッカーの標的になってしまいます。
有名な攻撃方法を紹介していくので、なぜそんなことが起こるのかを理解すると対策が立てやすいかと思います。
クロスサイトスクリプティング
クロスサイトスクリプティング(XSS)は、不正なスクリプトを挿入することにより、脆弱性のあるサイトでなく、被害がサイトを利用しているユーザーに及ぶ攻撃です。
例えば、入力フィールドがあって、そこからユーザーが悪意のあるコードを実行できたとしたらどうでしょうか。
特に JavaScript は、非常にできることが幅広く、簡単に実行されてしまいます。
クロスサイトスクリプティング対策
クロスサイトスクリプティング対策は、以下の通りです。
- エスケープ処理
- バリデーション
これらを確実に行うことで、リスクを最小限にすることができます。
そもそも問題点は PHP がユーザーが入力した情報を幅広く受け付けてしまうことです。
例えば、htmlspecialchars関数を使えば、プログラム的に特別な意味を持つ < や > は実体参照として変換されます。
バリデーションも非常に重要です。
必要以上にユーザーが入力できる範囲を広げてしまうと、今回のようなセキュリティーホールになる可能性が高くなるわけです。
例えば、郵便番号を入力するフィールドであれば、数字以外入力する必要はないわけですから、数字以外の値を受け付けるべきではありません。
SQLインジェクション
SQLインジェクションは、開発者が意図していない、SQL文を実行される脆弱性のことです。
インジェクションとは、注入という意味で、別の SQL文を注入するということが名前の由来です。
データベースの中には個人情報など絶対に公開されてはいけない機密情報が含まれることもあるはずです。
悪意のあるユーザーがこの脆弱性を利用して、個人情報を不正に取得したり、削除したりするわけです。
SQLインジェクション対策
SQLインジェクション対策は、以下の通りです。
- エスケープ処理
- プレースホルダの利用
もともとの SQL文を書き換えられてしまうことが大問題です。
SQLエスケープを使うのも一つの手です。
ただし、全ての変数の特殊文字を適切にエスケープするのはなかなか大変だと思います。
実用的なのは、プレースホルダの利用です。
可変値をとりあえず確保しておき、埋め込む値は SQL と分離して渡すことで安全に実行できる仕組みです。
クロスサイトリクエストフォージェリ
クロスサイトリクエストフォージェリ(CSRF)は、本来拒否すべきリクエストが受信され処理されてしまう脆弱性のことです。
XSS に似ているのですが、このクロスサイトリクエストフォージェリは、名前の通り、リクエストを偽装します。
画面遷移が開発者が意図していない違うところから不正なリクエストが処理されてしまうイメージです。
例えば、本来ログインしたユーザーしか使えない機能が他のユーザーでも使えるようでは大問題です。
クロスサイトリクエストフォージェリ対策
クロスサイトリクエストフォージェリ対策は、以下の通りです。
- トークンを利用する
例えば、入力フォームの場合、ランダムに生成するトークンを埋め込んで、正しいルートから来たユーザーかどうか判定するようにすれば防ぐことができます。
ちなみに Laravel(ララベル)も CSRF対策が施されています。
このように 1回限りのトークンのことを、ワンタイムトークンといいます。
ただし、サイトに XSS の脆弱性がある場合、ワンタイムトークンも盗まれる可能性があるので注意が必要です。
最後に
いかがでしょうか。
以前の記事で、お問い合わせフォームを簡単に紹介したのですが、ただ動けば良いというレベルなら比較的簡単だということがわかるかと思います。
しかし、セキュリティのことを考えて、実用レベルまでもっていくとなるとなかなか大変です。
PHP の入門書というのは、非常にたくさんあり、私も何冊か購入させていただいたのですが、読んでいて疑問に思うことが結構ありました。
入門書なので、内容を理解するためのサンプルコードと解釈すれば、問題ないのですが、そのまま使うとかなり危険なサンプルコードはたくさんあります。
現役エンジニアではない、私でも気が付くレベルなので、セキュリティ対策をして改良する必要があるということになります。
今回、紹介したものは比較的有名なものばかりですが、正しくバリデーションやエスケープ処理(プログラムとして特別な意味を持つ文字に対して)を行うのが基本なのかなと思います。
他にも、メールヘッダインジェクションや nullバイト攻撃など、色々ありますが、やはり入力値の検証がセキュリティ対策の第一歩です。
昔、新卒としてソフト開発会社に就職したときに SE や プログラマー は、一生勉強していく世界と言われましたが、その通りだと思います。
独学に限界を感じている方は、短期間で現役のエンジニアの方からプロとしてやっていくための基礎を学ぶことができる TechAcademy(テックアカデミー)のようなスクールを利用するのも有効だと思います。
無料体験もあり、自宅にいながら学習できるので、興味のある方はどうぞ。