競合状態についてアプリケーションをテストする価値がある理由

アプリケーションまたはサービスが内部通貨で動作する場合は、競合状態の脆弱性(「競合状態」、より正確には「同時実行の不確実性」)をテストする必要があります。競合状態は、攻撃者によって悪用される可能性のある「フローティングバグ」です。つまり、並列コード実行のおかげで、アプリケーションの内部通貨にアクセスして操作し、必要に応じて、サービスの所有者に目に見える経済的損害を与えることができます。最近、クライアントの1つでこの問題を発見し、解決に役立てました。







競合状態とは



開発者は、コードを複数のスレッドで同時に実行できることを忘れがちなので、このエラーは非常に一般的ですが、競合状態について製品をテストしません。



バックエンドの観点からは、次のようになります。複数のスレッドが同じ共有リソース(ブロッキングや同期がない変数またはファイル)に同時にアクセスします。これにより、データ出力に一貫性がなくなります。



このような脆弱性の具体例を次に示します。支払いウォレット間でボーナスを転送できるアプリケーションがあるとしましょう。攻撃者にはAとBの2つのウォレットがあり、それぞれに1000のボーナスがあります。この図は、トランザクションのリクエストを送信する時間を操作することにより、攻撃者が自分のアカウントへの転送量を増やし、20のうち10のボーナスを







作成する方法を示しています。このような脆弱性を検索する自動ツールがあります。たとえば、 RacePWNは、最小限の時間で多くのHTTPリクエストをサーバーに送信し、入力としてjson構成を受け入れ、サイバー犯罪者の攻撃プロセスを容易にします。これは、POSTリクエストを送信することによって手動で行われます。



モータルの競合状態



米国では、1985年6月から1987年1月にかけて、カナダの州組織であるAtomic Energy of Canada Limited(AECL)によって作成されたTherac-25放射線治療装置の競合状態エラーにより、 6回の放射線過剰投与が発生しました。犠牲者は何万もの喜びの線量を受けました。 1000のレベルは致命的と見なされます。結果として生じた火傷の後、犠牲者は数週間以内に死亡しました。 1人の患者だけがなんとか生き残った。



以前のTheracモデルには、ハードウェア保護メカニズムがありました。電子ビームを制御する独立したブロッキング回路。機械的ブロッカー; ハードウェアサーキットブレーカー; ヒューズを外します。Therac-25ではハードウェア保護が削除されました。ソフトウェアはセキュリティを担当していました。デバイスにはいくつかの動作モードがあり、競合状態エラーのために、医師はデバイスが実際にどのモードで動作するかを理解できないことがありました。裁判所の手続き中に、Therac-25ソフトウェアは1人のプログラマーによって開発されたことが判明しましたが、AECLは正確に誰についての情報を持っていませんでした。



このプロセスの結果、米国政府は、人々にとって安全性が重要なシステムの設計と運用に関する要件を大幅に厳しくしました。



身を守る方法



競合状態の問題を解決する最も簡単で安価な方法は、アプリケーションアーキテクチャを正しく設計することです。これについては、次のように予測する必要があります。



  • データベース内の重要なレコードをロックします。特定の時点で1つのストリームを記録する作業を確実に行うには、さまざまな方法があります。主なことは、不要なものをブロックしないことです。
  • データベース内のトランザクションの分離。これにより、トランザクションが順番にコミットされます。ここで最も重要なことは、安全性とスピードのバランスを取ることです。
  • . . , , , . , , , .




私たちのクライアントは、クーポンを使用して割引を提供する機能をサポートするオンライン食料品配達店です。テスト中に、クーポン値を使用してPOSTリクエストを送信するときに脆弱性が見つかりました。時間遅延の異なるリクエストを送信することで、2回の割引を受けることができました。どうやら、開発者は購入で識別されたオブジェクトへの共有アクセスに関連する重大なエラーを犯しました。



同期メカニズムのないこのような擬似コードがあった可能性があり

ます。…

1promo_flagが設定されていない場合:

2 Price = get_price()

3 Price- = price * promo_percent;

4 set_price(価格)

5 set_promo_flag()

...

ここで、プロモーションコードを適用し、適切なフラグを設定することは、アトミック操作ではありません。ほとんどの場合、プロモーションコードの2番目のアプリケーションが開始されたとき、最初のアプリケーションは5行目で停止しました(つまり、まだ実行されていません)。この時点で、2行目のget_price()関数は、すでに割引された新しい価格値を返しました。



決定



問題は簡単に解決されます:



1 acqure_mutex()

2 promo_flagが設定されていない場合:

3 Price = get_price()

4 Price- = price * promo_percent;

5 set_price(price)

6 set_promo_flag()

7 release_mutex()

...

これで、プロモーションコードの適用が完全に1回実行されます。最初のプロセスがすでに処理でビジー状態であるときに、2番目のスレッドがプロモーションコードを適用しようとする状況が発生した場合でも、それを行うことはできません。ミューテックスは「クリティカルセクション」へのアクセスをブロックし、2番目のプロセスは最初のプロセスが終了するまで待機する必要があります。



競合状態を過小評価してはなりません。会社の予算を含め、予期しない結果を回避するために、脆弱性を探すために時間とリソースを費やす方がよいでしょう。






ブログ ITGLOBAL.COM-マネージドIT、プライベートクラウド、IaaS、ビジネス向け情報セキュリティサービス:






All Articles