レースコンディション(Race Condition)とは?

レースコンディション(Race Condition)とは?

レースコンディション(Race Condition)とは、複数の処理が同時に行われた際に競合状態によって予期しない状態が引き起こされる問題を指します。

競合状態によって生じる問題は、データベースなどがデッドロックになることでデータに不整合が生じる、あるいはマルチスレッド時の共有リソースに格納されたデータが不特定多数に公開される別人問題など様々な自体を引き起こします。

レースコンディション(Race Condition)攻撃の仕組み

以下はJava言語における共有リソースへのアクセスによって引き起こされるレースコンディション(Race Condition)の例です。

まずJava言語ではローカル変数(メソッド内に定義された変数)は、スレッドセーフ(スタック領域に格納される変数)ですが、その他のインスタンス変数やクラス変数はスレッドセーフではありません。スレッドセーフではない変数の値はヒープ領域に格納されるため、マルチスレッド動作時に複数のスレッドから該当データに対して参照および更新・削除等の操作ができます。

レースコンディション(Race Condition)が存在するServletの記述例

public class SampleServlet extends HttpServlet {

	private String instance_name;//インスタンス変数
	private static String class_name; //クラス変数

	public static void methodSample(){
		String local_name = "local"; // ローカル変数
	}
		
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
		instance_name = request.getParameter("name"); // インスタンス変数にユーザー名を格納

		PrintWriter out = response.getWriter();
		out.println("Hello " + instance_name); // そのまま応答ページに出力
	}
}

上記のプログラムは一見、問題がないように見えますが、このServletでは複数のアクセスが生じた際にタイミングによっては以下のような現象が発生します。

レースコンディション(Race Condition)の概要

このようにタイミングによって共有リソースのデータが別のスレッドを通じて漏洩してしまう現象を別名、別人問題などと呼びます。

脆弱性の解説動画

レースコンディション(Race Condition)が起こる原因

前述した通りレースコンディション(Race Condition)は共有リソースに対して適切に排他制御を設けていないことが原因で引き起こされます。

なお、レースコンディション(Race Condition)の発生原因は単純ですが、並列処理における排他制御の妥当性をテストすることは極めて難しいことに加えて、問題が顕在化するのには特定のタイミングが必要なため、問題を抱えたまま運用されているWebアプリケーションは少なくありません。

また、前述したマルチスレッドによるレースコンディション(Race Condition)以外にも

  • トランザクションを意識していないRDBMの利用
  • 物理ロック、論理ロックを行わないファイルの入出力処理

などにおいても排他制御が十分でない場合に、レースコンディション(Race Condition)の問題が混入する恐れがあります。

さらに、ピュアコードもしくはフレームワークのどちらを用いてWebアプリケーションを構築していたとしても共有リソースへの排他制御は開発者が設計および実装する必要があるため、意図せずに作り込むとレースコンディション(Race Condition)脆弱性が混入します。そのため、Webアプリケーション構築時には開発手法を問わずに十分に注意が必要な問題といえます。

レースコンディション(Race Condition)攻撃への対策手法

以下の対策を実施することで問題の混入を防止することが可能です。

必須対策(排他制御の実装)

平行処理を実装する際には適切な排他制御を設けます。排他制御を実装することでレースコンディション(Race Condition)の問題の混入を防ぐことができます。以下は排他制御が必要となる処理の例です。

  1. マルチスレッドでの処理(変数などの共有リソース)
  2. トランザクションが必要となるデータベースアクセス(COMMIT、ROLLBACK)
  3. ファイルアクセス時の排他制御

まずは手軽にツールで脆弱性診断

上述の対策手法が重要となる一方で、脆弱性が混入されていないかを検知する事も重要となります。

脆弱性診断とは何かについて詳しく知りたい⽅は脆弱性診断とは(エンジニア向け)脆弱性診断とは(⾮エンジニア向け)もぜひご参照ください。

脆弱性検知やセキュリティレベルを強化したい企業様はぜひ弊社の脆弱性診断ツール「Securify Scan」を活⽤ください。

無償でのトライアル実施も⾏っておりますので、お気軽にお問い合わせください。

Webアプリケーションの
継続的セキュリティを簡単に実現
Securify

ブログ一覧へ戻る

サービスに関するご質問・ご相談など
お気軽にお問い合わせください