脆弱性に強い実装4つのポイント(Rails6/JS)

Rails・Webシステム開発
Anja🤗#helpinghands #solidarity#stays healthy🙏によるPixabayからの画像
スポンサーリンク

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.rbconfig.force_ssl = true

を記載すればよいようです。

ただし、常にHTTPで通信するローカルや、HTTPでしか接続できないヘルスチェックなどがある場合は、上記設定だと弾かれるので、場合分けをして回避する必要があります。

4.クリックジャッキング対策に「X-Frame-Options」を設定すること

クリックジャッキングとは、HTTP要素<iframe> を opacity:0 に設定(ボタンを透明化)することで、ユーザーに意図しないクリックをさせることができる攻撃です。例えば、脆弱性のあるサイトのフォローボタンなどの上に透明化した「課金する」ボタンを配置することで、ユーザーはフォローボタンを押したつもりが、「課金する」ボタンを押させられてしまうのです。(ちょっと複雑なので詳しく知りたい方はググってください)

ただ、その危険な分、フレームワークやクラウドも対策を練っていて、下記で対応可能のようです。

  • Rails6ではデフォルトで設定されているため特に対策不要。
  • packsなど、Railsの範囲外の画像等に対しては、別途対策が必要
    • 例えば、AWSでCloudFrontを使用している場合は、ビヘイビアの設定で、レスポンスヘッダーのポリシーにManaged-SecurityHeadersPolicyというマネージドポリシーを設定することで対策できます。

脆弱性に強いコーディングまとめ

まとめ

  1. パラメーターは常に改ざんの可能性を考慮すること
    • モデル名.find(params[:id])のような単純な取得ではなく、ログインユーザーのリレーションから取得したり、権限チェックをはさむこと。
  2. XSS(保存型)の影響を受けないよう対策すること
    • ユーザーの入力できるテキストの改行やURLを有効にしたい場合は、サニタイズするメソッドを合わせて使用すること
  3. Cookie中のsession_idはSecure属性で保護すること
  4. クリックジャッキング対策に「X-Frame-Options」を設定すること

特に1と2は、実装する際やレビューをする際に常に意識しておく必要があります。

きちんとしたプロジェクトなら「脆弱性診断」とかして指摘されたら直せばよいけど、そんな大掛かりなことをするお金も時間もないよーという場合は、せめて実装段階から上記を意識しておくと、最低限セキュアなサイトになるかなと思います。

もちろん、これに加えてIP制限やファイヤーウォールの設定も大切ですし、もっときちんと対策するなら、DDoS対策などを行う場合もあります。こちらはバックエンドエンジニアというよりはインフラエンジニアの領域に入ってきますが、最近はこの垣根もなくなりつつあるので、少なくともそういう対策が必要であることは知っておくと良いです。

web開発をする方の参考になれば嬉しいです。

はるすと
はるすと

最後まで読んでくださってありがとうございました!

この記事を書いた人
こもれびエンジニア

自然と自由を愛するエンジニア。2021年1月に、大手製造業設計からプログラマ(Rails, AWS)へ転職。動物や自然との触れ合いや、汗を流すのが好き。

/HSP(繊細さん)/18デリケートな象/ストレングスファインダー(1分析思考/2親密性/3学習欲/4調和性/5収集心)、テニス、合気道、登山、あいだみつを、ジブリ、ワンピース、ドラゴンボール、AWS、Ruby on Rails、アイミング

twitterをフォローして、記事にならないちょっとした豆知識もチェック!
Rails・Webシステム開発
スポンサーリンク
SNSでシェア/コメントして、自分のアウトプット/発信力を高めるのにお使いください。 ↓ 各ページへジャンプ ↓
twitterをフォローして、記事にならないちょっとした豆知識もチェック!
スポンサーリンク
「そんなか」サイト

コメント

タイトルとURLをコピーしました