CakePHP3で作ったWebサービスをHerokuでデプロイするまでにセキュリティとしてやったこと

CakePHP3でWebサービスを公開するまでのセキュリティ、どこまでやれば安心なんでしょうか。

いや正直、やるべきことが全然わからないです。

上記のような方、いらっしゃるんじゃないでしょうか。

自分がそうでした。

少しでもそういう方の道標になれば良いなと思って書きます。

具体的な手段というよりも、概要をまとめていきます。

【自分の環境】
macOS Catalina
PHP7.4.2
CakePHP3.8
MAMP5.7
Apache2.2
MySQL5.7

大前提

プラットフォーム(サーバーやネットワークなど)はHerokuを使ってます。

Herokuを使ってデプロイしています。

めちゃくちゃ簡単にデプロイできると呼び声が高いので使いましたが、それ以上にセキュリティをほとんどやってくれているというのも大きいですよね。

Herokuに頼るんかい、と思われるかもしれませんが、割と問題を起こしてからでは取り返しがつかないです。

最初は補助輪付きで…それでいいんじゃないでしょうか。

セキュリティをやる前に

セキュリティを締める前におすすめのアクションですが、「徳丸本」を読んだ方がいいと思います。

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版[リフロー版] 脆弱性が生まれる原理と対策の実践 | 徳丸 浩 | コンピュータ・IT | Kindleストア | Amazon

※上記は「リフロー版」で、電子書籍にはもう1つ「固定版」というのもあるみたいです。お気をつけて。

通称が徳丸本です。

徳丸さんが書いているから徳丸本らしいです。

Webアプリのセキュリティならこれを読め、的な本です。

とても体系的に詳しくWebアプリのセキュリティのことが載っています。

正直ネットの情報って断片的なものが多いですし、1度はこの本を読むのがいいと思います。

地味に自分は2度読みました。

正直1周目ではとても入ってこない、掴みきれないくらいの情報量でした。

2周目読んだら「あ、あれあそこに書いてあったやつだ」みたいなかんじで、ようやく咀嚼できました。

聞いたかんじWeb系のエンジニアならみんな読んでるので、読んだ方がいいです。

本題…CakePHP3(アプリ側)でやること

行きます。

と言ってもフレームワークをちゃんと使っていると、セキュリティって割としっかりするものなんです。

例えば、SQLインジェクションというものがありますが、素のSQL文(SELECT * FROM users;みたいな)で書かなければ防げています。

CakePHP3で言うと$this->Users->find();みたいなチェーンメソッドで書いていれば、防げています。

ということで、「Herokuでデプロイする」+「フレームワークをちゃんと使う」これだけでセキュリティにおいて、かなりのショートカットができる認識です。

セキュリティに詳しい人に怒られそうですが、そう思っています。

その上で気をつけたことを書いていきます。

htmlspecialchars()をつける

htmlspecialchars()ファンクションはCakePHPで言う「h()ファンクション」です。

データを出力する時に使います。

<p>あなたの写真ID</p>
<td><?= h($photo->id) ?></td>

上記みたいなかんじです。

初心者なら普通に「$photo->id」でいいじゃん、と思うと思います。

ですが、これではもしも出力するデータにHTMLやJavaScriptなどが混入していた場合、変な文字に化けてしまうことがあります。

いわゆるクロスサイトスクリプティングXSS)です。

また文字コード脆弱性も避けることができます。

文字を出力する際は必ずh()ファンクションをつけるようにします。

バリデーションを見直す

バリデーションは皆さんつけていると思います。

ですが甘い付け方だとそこに付け入られてしまう可能性があります。

例えば、ファイルアップロード時に拡張子のチェックをつけておかないと、危ないphpファイルがDBに保存される可能性があります。

仮にこれをユーザーが閲覧できると、そのファイルを見たことをきっかけにWebサーバーに攻撃を食らったりします。

適切な拡張子のファイルしか保存できないようになっているか、いま一度確認しましょう。

実際に画像の拡張子を検査するバリデーションをつけたので、別記事で紹介します。

アクセス制御

これはセキュリティと呼ぶのか分かりませんが、やったので説明します。

例えば管理者画面にユーザーが入れてしまうと、一巻の終わりです。

そこから情報を閲覧されたり、情報をいじられたり…とにかく終わりです。

なのできっちりアクセス制御しておきましょう。

手段としてはadmin、userと利用者の役割を分けてアクセス制御することや、管理者画面ではパスワードを要求するようにすることとかです。

アクセスログなどを出力する

アクセスログなども残しておいたほうがいいです。

いつ、誰が、どこで、何を、どのように…。

これらの情報を管理者が拾えるくらいのログを出力したほうがいいらしいです。

具体的には、イベントとしては「ログイン・ログアウト」「ユーザー登録・削除」「物品購入・送金」などなど、重要な操作でログを出すようにします。

またログの内容ですが、「アクセス日時」「リモートIPアドレス」「アクセス対象URL」「操作内容」「操作が成功したかどうか」などです。

これらを記録することで、いつ深刻なアクセスや操作があったか見つけられ、IPアドレスなどでアクセス禁止にすることでサイトを守ることができます。

ログ出力に関しては、長くなるので別の記事で説明させてください。

終わりに…の前に

生半可な知識で書いてて感じましたが、セキュリティに関しては徳丸本を読むことが1番のショートカットだと思います。

重大な不備があったとしたら、時間的にも金額的にもたぶん考えられないくらいの損失になります。

もちろん読んで終わりではないですが、読んで自分のサイトに落とし込んでいくのがいいです。

一旦、体系的に学んで備えることがあらゆる面で1番のショートカットだと思います。

終わりに

以上となります。

書きながら中途半端なものだなと思ってしまって公開するのを少し躊躇いましたが、公開したいと思います。

自分ももっと勉強していきます。

ありがとうございました。