Rails セキュリティのベスト プラクティスに関する包括的なガイド
あなたも私と同じなら、素晴らしいアプリを構築するのが好きでこのビジネスに参入したはずです。開発分野に十分長く携わっていれば、 最終的にはそれほど素晴らしいと感じられないような素晴らしいアプリの作業をしなければならないことになります。 。セキュリティもその 1 つです。 Rails フレームワークが面倒な作業の多くを行っているとしても、Rails のセキュリティを真剣に考えることは重要です。
Ruby on Rails のセキュリティの詳細に深く入る前に、少し時間を取って、良き時代を振り返ってみましょう。

...そして現実世界に戻ります。
セキュリティの脅威について心配しなければならないのは最悪です。毎朝起きて、あなたが作っているものを壊そうとする人たちがいるなんて、本当にうんざりします。
しかし、そういう人たちは存在するのです。彼らはあなたのセキュリティに穴を開けようと懸命に働いています。そして、 成功したときはあなたのせいです。
クライアントは、あなたに代わってコードを安全にすることはできません。あなたのマネージャーはあなたの代わりにそれをすることはできません。すべてはあなた次第です。だから、自分が一体何をしているのかを知ったほうがいいよ。
Rails のセキュリティを考慮する必要があるのはなぜですか?
- セキュリティのベスト プラクティスに従おうとしていますが、よく理解していませんか?
- XSRF、MITM、XSR 攻撃の仕組みについてよくわかりませんか?
- あなたのアプリは小規模または社内向けであるため、危険にさらされることはないと思いますか?
これらのいずれかに当てはまれば、このガイドは間違いなくあなたのためのものです。セキュリティはどのアプリにとっても重要であり、そうでなくなるまでは、セキュリティへの投資を避けるのが問題ありません。 Rails を使用すると、ウェブ アプリケーションの最大のセキュリティ リスクの一部を非常に簡単に軽減できるため、ギャップを埋めないのは愚かです。
あなたのアプリケーションはターゲットではないと思いますか?
あなたはおそらく間違っています。 それがインターネット上にある場合、それは包囲下にあります。自動化されたシステムは脆弱な Web アプリを 24 時間スキャンしています。
組織犯罪であれ、ボットであれ、インターネットにはユーザーのデータを手に入れようとする悪意のある者がたくさんいます。
組織犯罪は現実のものです
クレジット カードをデータベースに保存していますか?ソルトなしのパスワードハッシュ?そうでなければいいのですが!もしそうなら、あなたはめちゃくちゃです。 Rails を使用すると、このような間違いを比較的簡単に回避できます。
ボットネットがあなたをダウンさせます

ボットネットを実行する場合、ボットの数が増えるほど資金も増えます。そこでエクスプロイト パックを購入し、古いブラウザがペイロードにヒットしたときにマルウェアをインストールするように設定し、その後、いくつかの正規サイトをハッキングしてペイロードを多くのユーザーに配信します。
外国政府があなたを捕まえようとしています
冗談のように聞こえますが、中国政府では何千人もの人々が企業秘密、政府情報、さらには政敵に関する情報を求めてシステムをハッキングしています。
とても楽しい仕事だと思いませんか?
世界中で国家がハッキング リソースを管理しているのは中国だけではありません。世界中の政府が参加しているため、セキュリティ上の懸念を真剣に受け止めるほどアプリケーションが重要でないと考える必要はありません。
ハクティビストは影に潜んでいる
劣化ウラン弾を国防総省に販売していますか?そうすれば、彼らが何をしているのかを知っている人を雇うのに十分なお金があるはずです。ハクティビストは定期的に、活動のターゲットと一致するウェブサイトをターゲットにします。
必読
これは不適切なガイドです。包括的な内容になると期待していましたか?少なくとも次の内容もお読みください。
- Rails セキュリティ ガイド
- Ruby の公式セキュリティ ページ
Ruby の 8 つのセキュリティ脆弱性 (または、p0wn される 8 つの簡単な方法)
(小規模なアプリであっても) セキュリティがどれほど重要であるかについては同じ認識を持っています。おそらく、Ruby アプリの安全性をどのように確保するか疑問に思っているでしょう。
ここでは8 つのクラスの脆弱性を取り上げます。 これは、ウェブ開発者が理解することが非常に重要です。
- 技術的以外
- クロスサイト スクリプティング (XSS)
- クロスサイト リクエスト フォージェリ (CSRF、XSRF)
- 中間者 (MITM)
- SQL インジェクション (SQLI)
- 質量の割り当てとパラメータの注入
- サービス拒否 (DOS、DDOS)
- プラットフォーム攻撃(アプリケーションを実行するホストの悪用)
Ruby on Rails のセキュリティに影響を与える可能性のある非技術的なセキュリティエクスプロイト
場合によっては、明らかな問題が最も見えにくいことがあります。これらの間違いはチェックリストには記載されていないかもしれませんが、常識を働かせる価値はあります。
できる愚かなことの数と種類は無限にあるので、いくつかだけ指摘します。
しないでください:
- 平文のパスワードをメールで送信する
- どこでも同じパスワードを使用する
- Cookie を持ってオフィスに現れる人を信頼する
- 機密データをノートパソコンに入れて持ち運ぶ
クロスサイト スクリプティング
脆弱性の 1 種類には、悪意のある攻撃者がユーザーがアプリケーションを使用する際に悪用できるものがあります。
もし私が悪者であれば、JavaScript の一部をあなたのページに挿入する方法に非常に興味があるかもしれません。
これを実行すると、アクティブなセッション Cookie を盗んだり、エクスプロイト キットを DOM にブートストラップしたり、ページにおかしなことを書かせたりすることさえできます。それはそれほど有害ではないように聞こえるかもしれませんが、悪意のあるコンテンツを挿入するだけでも風評被害を引き起こす可能性があります。

クロスサイト スクリプティングを防ぐ簡単な方法があります
クロスサイト スクリプティングを悪用しようとする攻撃者を阻止するには、ユーザー入力からテキストをエスケープして、JavaScript を無害なテキストに変える必要があります。
あなたはこれが欲しいのです。
<script>alert('I am stealing your cookies! Ha!');</script>
これは望ましくありません:
<script>alert('I am stealing your cookies! Ha!');</script>
クロスサイト スクリプティングを防ぐのがそれほど簡単ではない場合もあります
ここが問題です。古い Rails アプリケーションをセキュリティ パッチなしで実行している場合は、XSS の脆弱性がある可能性があります。 Rails の非常に初期のバージョンでは、h() を使用して信頼できない入力を手動でエスケープする必要がありました。 メソッド。
最新の Rails アプリはデフォルトで HTML 出力をエスケープするため、ほとんどの XSS 脆弱性をそのまま使用できます。しかし、特にレガシー コード、サードパーティ ライブラリ、または動的な HTML レンダリングを扱う場合は、驚くほど間違いが起こりやすいものです。
Rails の最新バージョンでも、自分の足を撃つ可能性があります。 html_safe を呼び出しています ユーザー入力でエスケープを完全にバイパスするため、ユーザー入力を HTML に挿入して安全とマークしている場合は、基本的に Rails の組み込み保護をオフにして、アプリケーションに XSS を招待していることになります。
Rails チームは、クロスサイト スクリプティングが特に蔓延しており、有害なエクスプロイトであることを認識しているため、セキュリティ ドキュメントのセクションを、このリスクを軽減するために必要なものを確実に入手できるようにすることに特化しました。アプリケーションが安全だと思われる場合でも、一読の価値はあります。
クロスサイト リクエスト フォージェリ
Rails アプリケーションにおけるもう 1 つの一般的なセキュリティ脆弱性は、クロスサイト リクエスト フォージェリと呼ばれます。例を見てみましょう。
ユーザーがパスワードを変更したい場合、バックエンドにフォームをポストしますよね?では、フォームがウェブサイトにない場合はどうなるでしょうか?
リクエストは引き続き実行されます。攻撃者は慎重に悪用することでこの事実を利用する可能性があります。
CSRF 攻撃の構造
私が CSRF 経由でアプリケーションを悪用することに興味を持っている攻撃者だとしましょう。あなたが管理者としてアプリにログインしていることを偶然知った場合、別のものに見せかけた「パスワード変更」フォームを作成するかもしれません。気づかずにフォームを送信してしまい、パスワードを変更してしまうことになります。
さらに、アプリが POST リクエストではなく GET リクエストを使用している場合は、さらに状況が悪くなります。
あなたを騙す必要さえありません。最近アクセスしたページにイメージ タグを追加するだけで、認証済みリクエストを発生させることができます。
幸いなことに、Ruby on Rails は、ほとんどが組み込みの CSRF 保護を提供することで、この種の攻撃を回避します。あなたはそれを「何らかの理由ですべてのフォームに入力される奇妙なテキスト」として知っているかもしれません。
<input type="hidden" name="authenticity_token" value="kM3jN8vBx2QzE-7wRtFpL6aYsI9uZcXmD4oHgK1rVnWe5qA0bUiJlSfTyP3hG2oC8xZ7mBvNkL4wQrEtYuI6pA" autocomplete="off" />
解読不可能なテキストは、ユーザーのセッション データに保存されている秘密キーです。ユーザーがセッション内のトークンと一致しない CSRF トークンを送信すると、アプリは例外をスローします。幸いなことに、Honeybadger はこれらの例外を見つけて修正するのに役立ちます!
それでも失敗する可能性はあります
もちろん、コントローラ内の一見無害なコード行を使用して CSRF チェックを無効にすることもできます。
skip_before_action :verify_authenticity_token
また、POST ルートであるべきものに GET ルートを使用すると、問題が発生する可能性があります。
MyApp::Application.routes.draw do
match "/launch_all_the_missiles", to: "missiles#launch_all"
end
でも、そんなことはしないでしょう?それでも、CSRF の恐ろしい点は、問題がアプリにある必要はないということです。ユーザーは、CSRF エクスプロイトが埋め込まれた別のサイトにアクセスし、アプリへのリクエストをトリガーする可能性があります。 Rails の対策を活用すると、この種の事態から身を守ることができます。
中間者攻撃とパケットスニッフィング
中間者攻撃は、たとえ話で説明するのが最も簡単です。腐ったダメ従妹のヴィニーに現金を送る必要があるとします。現金を取り出して封筒に入れ、この野郎の住所を書いて切手を貼り、封筒を郵便配達員に渡すかもしれません。
1週間後、ビニーの家に封筒が届きましたが、中には現金は入っていませんでした。どうしたの?あなたと対象の受取人の間で、誰かが封筒の中身を改ざんしました。これは単純な中間者攻撃です。
アプリケーション Cookie は中間者攻撃に対して脆弱です
上記の話は少しばかげているように聞こえるかもしれませんが、同じことがユーザーの Cookie にも起こる可能性があります。
Cookie は通常、Web リクエストごとに送信されます。公共 (Wi-Fi) ネットワーク経由で平文で送信されるとゲームオーバーです。
Firesheep のようなものを実行している悪者は、ユーザーの Cookie のコピーを簡単に入手して、アカウントを侵害することができます。
SSL が助けになります
簡単な答えは、すべてに HTTPS を使用し、厳格なトランスポート セキュリティに従うことです。カフェにいる人はユーザーのトラフィックを見ることができますが、それは暗号化されています。それほど簡単ではありませんが、状況によってはおそらくより良い答えは、Rails のセキュア Cookie を使用することです。
セキュア Cookie は HTTPS 接続経由でのみブラウザに送信されます。これは Rails 3 以降のデフォルトです。
運悪くそれよりも古いバージョンの Rails を実行している場合、安全な Cookie がプレーン テキストで送信される可能性があります。それほど安全ではありませんね?
SQL インジェクション
インターネット上のほとんどの Web サイトは、テキストの断片をつなぎ合わせて、SQL と呼ばれる言語で小さなプログラムを作成することで機能します。
それについて考えてみてください。これがどれほどクレイジーなことかわかりますか?
しかし、好むと好まざるにかかわらず、これが物事の仕組みです。そして、インターネットが存在するという事実に基づいて、それはかなりうまく機能するはずです。
SQL をインターネット上にばらまくことの副作用の 1 つは、ハッカーが独自のテキストを小さな SQL プログラムに追加できる場合、データが問題にさらされる可能性があることです。

SQL インジェクションの例
請負業者が次のようなコードを送ってきたと想像してください。
Building.where("st_intersects(st_setsrid(st_makebox2d(st_point(#{params[:northeast][:lng]}, #{params[:northeast][:lat]}), st_point(#{params[:southwest][:lng]}, %{params[:southwest][:lat]})), 4326), buildings.location)")
これは大きな間違いであり、SQL インジェクションの危険にさらされる可能性があります。 SQL クエリでパラメータに直接アクセスすると、クライアントに独自の SQL を強制的に実行するオプションが与えられます。抜け目のない攻撃者は params[:southwest][:lat] を実行できます。 次のような悪意のある SQL コードが含まれています:
")), 4326), buildings.location); UPDATE users SET admin=1 WHERE id=666;--"
これで、私のユーザー ID に管理者権限が与えられました。 SQL インジェクションは一般的で簡単な悪用であるため、サイトのトラフィックを十分に監視している人は、最終的には SQL インジェクションの試みを目にすることになります。
Rails はほぼ自動的に SQL インジェクションから私たちを守ります
Rails は、許可している限り、多くの場合 SQL インジェクションから保護します。 where を使用した場合 正しく行われていなければ、パラメータはエスケープされており、SQL インジェクションの試行は失敗していました。
where("st_intersects(st_setsrid(st_makebox2d(st_point(?, ?), st_point(?, ?)), 4326), #{table_name}.location)", box[:northeast][:lng], box[:northeast][:lat], box[:southwest][:lng], box[:southwest][:lat]).
Rails は常に SQL インジェクションから保護できるわけではありません
しかし、Rails が生の SQL を使用している場所はたくさんあります。見落としがちな場所。
たとえば、SomeModel.sum("amount") にあることをご存知ですか? 、「金額」文字列はエスケープされずにクエリに追加されますか?
したがって、sum を呼び出すレポートがある場合、 params["col"] に直接アクセスするメソッド 、困ったね。
以下は IRB セッションの例で、信頼できない入力を sum メソッドに渡した場合の結果を示しています。
pry(main)> User.sum(%[id) AS sum_id FROM users; update users set
admin='t' where id=224;--])
(22.4ms) SELECT SUM(id) AS sum_id FROM users; update users set
admin='t' where id=224;--) AS sum_id FROM "users"
=> "0"
#pluck にも同じことが当てはまります
集団割り当て攻撃
2012 年 3 月 4 日、ロシアのハッカー Egor Homakov は、攻撃者が GitHub ユーザーになりすますことができる大量割り当ての脆弱性を公開しました。ご想像のとおり、これは非常に問題がありました。
GitHub がどのようにハッキングされたか
あなたも次のようなコードを何百回も書いたことがあるでしょう。
User.create(params[:user])
Ruby コードは読みやすいため、このコードが指定されたパラメータを使用してユーザーを作成していることが非常に簡単にわかります。
Rails 3.2.3 より前では、 これは任意のパラメータを意味していました。 明示的に指定しない限り、入力された値はモデルに割り当てられます。
これにより生じた問題は、忘れやすいということでした。そして、攻撃者が適切な POST リクエストを送信するだけでこれを引き起こす世界にいることになります。
User.create({admin: true, ...})
GitHub の場合は次のようになります。
PublicKey.update({user_id: "123"})
一括割り当ては簡単に修正できます
最新の Rails アプリにおける一括割り当ての脆弱性に対する推奨される解決策は、強力なパラメーターを使用することです。これについては、この記事の前半で説明したとおりです。
params 全体を盲目的に渡すのではなく、 User.create へのハッシュ 、どの属性が許可されるかを明示的に宣言します。
def user_params
params.require(:user).permit(:name, :email)
end
User.create(user_params)
この簡単な選択により、更新するフィールドのみを許可リストに登録することでモデルを保護できます。これは、Rails 4 以降のデフォルトの保護です。本当に古いアプリ (Rails 4 以前など) を維持している場合は、アップグレードする価値があります。
サービス拒否攻撃
今日何人を怒らせましたか?先月はどうでしょうか?
サービス拒否攻撃 (DOS) と分散型サービス拒否攻撃 (DDOS) は、infosec コミュニティによる激怒漫画のバージョンです。これらの攻撃によってデータが盗まれたり、マルウェアが拡散したりすることはありません。彼らはただあなたを黙らせたいだけなのです。これは依然として会社に多大な財務的または評判的損害を与える可能性があります。
DDOS は粗雑ですが効果的な攻撃です
分散型サービス拒否攻撃を仕掛けるには、親しい友人 500 人に電話し、アムネスティ インターナショナルの Web サイトにアクセスしてもらい、1 時間更新ボタンを押し続けてください。ボットは友人の代わりに使用できます
このような問題が発生した場合は、いくつかの解決策があります。 Rails はこの種の攻撃にあまり重点を置いていませんが、レート制限を迅速に導入するのに役立つ宝石が多数あります。 Rails には、使用できるスロットル ミドルウェアもあります。 ISP に相談し、堅牢なレート制限機能を提供する Cloudflare などのプロキシを使用することも検討してください。これらはかなり退屈ですが、よく知られている問題です。
アルゴリズムの複雑さによる攻撃
それはとてもクールだと思いませんか?
これらの攻撃は、オペレーティング システムやアプリケーション スタックなどの特定の弱点を利用し、アプリケーション ホストに問題を引き起こします。これらは、サーバーのメモリをいっぱいにしたり、CPU 使用率を高めたり、ディスク容量をいっぱいにしたりするために使用することもできます。
たとえば、古典的な SYN フラッド攻撃は、SYN リクエストをサーバーに送信することによって機能します。サーバーは閉じられていない大量の接続を開きます。接続が十分に開いていると、オペレーティング システムのメモリがすぐに不足し、アプリケーション自体がクラッシュします。これは、アルゴリズムの現実を悪用して、アプリケーションを完全にダウンさせる可能性のある重大な問題を引き起こします。
古き良きサーバーエクスプロイト
ハッカーについて考えるときに私たちが思い浮かべるのはまさにこれですよね?バッファ オーバーフローを利用して Apache に root ユーザーとして任意のコードを実行させる怪しい人?
しかし、多くの退屈な仕事と同様、これも自動化されています。今、システム ログを見てみると、ボットが SSH ログインにブルート フォース攻撃を試みているのがわかると思います。
攻撃検出を自動化する
fail2ban などの一般的なツールを使用して、あなたに対して既知の攻撃を試みているホストの IP アドレスを自動的にブロックできます。
やるべきだと分かっていることを実行しましょう。
オペレーティング システムにパッチを適用したままにしてください。必要のないサービスは実行しないでください。 SSH のパスワード認証を許可しません。リストは続きます。プラットフォームを使用している場合、これらの多くは自動的に処理されます。
Rails のセキュリティをレベルアップする時期が来ました
まず、パニックにならないでください。 Rails のセキュリティは、好むと好まざるにかかわらず、あなたの仕事の一部です。真剣に取り組んでいると、脆弱性の軽減が急速に進むでしょう。過小評価されていますが、効果的な方法は、セキュリティ更新プログラムをまだ受け取っているバージョンの Rails を使用していることを確認することです。現在重大な脆弱性が公開されているバージョンでフレームワークが実行されている場合、世界中のすべての SQL エスケープでは保護できません。 gem の依存関係についても同様です。
フレームワークがサポートされたら、このガイド (および Rails セキュリティ ガイド) を使用して、アプリのリスクの表面積を減らしてください。強力なパラメータを使用します。レート リミッターと、場合によってはプロキシを構成します。メソッドについては HTTP の規則に従い、トラフィックを強制的に SSL にします。これらすべてにより、セキュリティ上の問題が発生する可能性が少しずつ減っていきます。
編集者注:この投稿はもともと 2013 年 3 月に公開されたもので、正確性を期すために更新されています。
-
Rubyの関数とメソッド:独自の関数を定義する方法
Rubyメソッドとは何ですか? メソッドは、特定の目的のためにグループ化された1行または複数行のRubyコードです。 このグループ化されたコードには名前が付けられているため、コードを再度記述したり、コピーして貼り付けたりすることなく、いつでも使用できます。 メソッドの目的は次のとおりです : 情報を取得します。 オブジェクトを変更または作成します。 フィルターとフォーマットのデータ。 例1 : サイズ Arrayのメソッド オブジェクトは要素の数を示します(情報を取得します)。 例2 : pop メソッドは、配列から最後の要素を削除します(オブジェクトを変更します)。
-
RubyでのAWSLambda関数の記述
AWS Lambdaを使用すると、オーバーヘッドを最小限に抑えながらスケーラブルな関数をセットアップできます。 Ruby on Railsアプリ全体を作成、ホスティング、保守する代わりに、Lambda関数を使用して個々のイベントに個別に応答できます。この記事では、AWSの初心者から、独自のLambda関数でRubyを作成する方法について説明します。 Lambdaを使用すると、サーバーを管理しなくても、イベントに応答してコードを実行できます。このイベント駆動型アーキテクチャにより、コードの支払いは、アイドリング中ではなく、機能している間だけになります。 Lambdaは、S3バケット内のファイル