webシステム開発をする際に、必ず意識しなければならないのが「脆弱性」です。
今どき、個人情報を入力してもらったり、アクセス制限(認可)を設定するサイトが多いと思うので、
情報漏えいやマルウェア感染をしないよう対策することは開発者の責務ですよね。
でも、何からしたらよいかわからない・・・
そんな駆け出しエンジニアの方に向けて、この4つだけは押さえておこう!という基本の脆弱性対策をまとめました。
1.パラメーターは常に改ざんの可能性を考慮すること
モデル名.find(params[:id])
のような単純な取得は危ない。パラメータは簡単に改竄(かいざん)可能です。getリクエストならURLのクエリ部分を直接編集すれば出来るし、postやpatchなども、一見パラメータがURLに出てこないので安全と思いきや、ブラウザの開発者ツールから容易に改ざんできてしまいます。
対策としては、
- current_userなど、出来るだけセッションに格納されたログインユーザー自身のIDに紐付いたインスタンス変数から取得すること。
- どうしてもパラメータから取得する場合は、権限の有無を判定する処理をはさむこと。
です。
2.XSS(保存型)の影響を受けないよう対策すること
XSS(クロスサイトスクリプティング)とは、脆弱性のあるサイトにJavaScriptなどのコードが書かれたスクリプトを埋め込むことで、そのサイトを見た人にマルウェア感染させ、情報漏えいさせることができる攻撃です。サイトをまたいで(=クロスサイト)スクリプトで攻撃する(=スクリプティング)みたいな雰囲気かなと思います。
具体的には、ユーザーがテキストなどを入力して保存できる仕様で、そのテキストに対してRubyの◯◯.html_safe
メソッドやJSの.html('◯◯')
メソッドを使用した場合、保存した際に悪意のあるスクリプトを埋め込められる可能性があります。
対策としては、
- Rubyの
.html_safe
メソッド:sanitizeメソッドやhメソッドを用いること。 - JSの
.html()
メソッド:replaceなどを用いてサニタイズすること。あるいは.text()
メソッドで代用できないか検討すること。
おそらく、改行やURLを有効にしたくて上記メソッドを使用している場合が多いと思うので、そういった場合に、「脆弱性が生じるかも」という感覚を持っていると良いです。
3.Cookie中のsession_idはSecure属性で保護すること
CookieをHTTPでも送れるようになっていると、第三者に傍受される危険性があります。特にセッションIDは大切なログイン情報であるから、HTTPS(SSL通信)でのみアクセスできるよう制限しておく必要があります。ただ、Railsでの設定は簡単で、
config/environments/production.rb
にconfig.force_ssl = true
を記載すればよいようです。
ただし、常にHTTPで通信するローカルや、HTTPでしか接続できないヘルスチェックなどがある場合は、上記設定だと弾かれるので、場合分けをして回避する必要があります。
4.クリックジャッキング対策に「X-Frame-Options」を設定すること
クリックジャッキングとは、HTTP要素<iframe>
を opacity:0
に設定(ボタンを透明化)することで、ユーザーに意図しないクリックをさせることができる攻撃です。例えば、脆弱性のあるサイトのフォローボタンなどの上に透明化した「課金する」ボタンを配置することで、ユーザーはフォローボタンを押したつもりが、「課金する」ボタンを押させられてしまうのです。(ちょっと複雑なので詳しく知りたい方はググってください)
ただ、その危険な分、フレームワークやクラウドも対策を練っていて、下記で対応可能のようです。
- Rails6ではデフォルトで設定されているため特に対策不要。
- packsなど、Railsの範囲外の画像等に対しては、別途対策が必要
- 例えば、AWSでCloudFrontを使用している場合は、ビヘイビアの設定で、レスポンスヘッダーのポリシーに
Managed-SecurityHeadersPolicy
というマネージドポリシーを設定することで対策できます。
- 例えば、AWSでCloudFrontを使用している場合は、ビヘイビアの設定で、レスポンスヘッダーのポリシーに
脆弱性に強いコーディングまとめ
まとめ
- パラメーターは常に改ざんの可能性を考慮すること
モデル名.find(params[:id])
のような単純な取得ではなく、ログインユーザーのリレーションから取得したり、権限チェックをはさむこと。
- XSS(保存型)の影響を受けないよう対策すること
- ユーザーの入力できるテキストの改行やURLを有効にしたい場合は、サニタイズするメソッドを合わせて使用すること
- Cookie中のsession_idはSecure属性で保護すること
- クリックジャッキング対策に「X-Frame-Options」を設定すること
特に1と2は、実装する際やレビューをする際に常に意識しておく必要があります。
きちんとしたプロジェクトなら「脆弱性診断」とかして指摘されたら直せばよいけど、そんな大掛かりなことをするお金も時間もないよーという場合は、せめて実装段階から上記を意識しておくと、最低限セキュアなサイトになるかなと思います。
もちろん、これに加えてIP制限やファイヤーウォールの設定も大切ですし、もっときちんと対策するなら、DDoS対策などを行う場合もあります。こちらはバックエンドエンジニアというよりはインフラエンジニアの領域に入ってきますが、最近はこの垣根もなくなりつつあるので、少なくともそういう対策が必要であることは知っておくと良いです。
web開発をする方の参考になれば嬉しいです。
最後まで読んでくださってありがとうございました!
コメント