용어 사전

TOCTOU란 무엇인가: 확인과 사용 사이에 상태가 바뀔 때

TOCTOU(time-of-check to time-of-use)는 확인 이후에 상태가 바뀌는 경쟁 조건입니다. 작동 방식과 방어법: 확인과 사용을 한 단계로 결합하세요.

게시 2026-11-15 업데이트 2026-11-15 4분 읽기
이 페이지에서

TOCTOU(time-of-check to time-of-use)는 어떤 대상의 상태가 확인된 시점과 사용된 시점 사이에 바뀌는 문제입니다. 이 페이지에서는 작동 방식과 예방 방법을 설명합니다(공격 절차는 다루지 않습니다).

TOCTOU란 무엇인가

프로그램은 흔히 "확인하고, 괜찮아 보이면 사용한다" 방식으로 동작합니다. 예를 들어 "이 파일에 쓸 수 있는지 확인한 다음, 열어서 쓴다"와 같습니다. 그러나 확인과 사용 사이에는 짧은 시간 차이가 있습니다. 그 사이에 다른 프로그램이나 요청이 대상을 바꾸면, 확인 결과는 더 이상 유효하지 않습니다.

MITRE의 CWE-367은 이를 제품이 자원의 상태를 확인한 뒤 사용하는데, 확인과 사용 사이에 상태가 바뀌어 확인이 무효화될 수 있는 약점이라고 설명합니다. CWE(Common Weakness Enumeration)는 취약점의 바탕이 되는 약점을 모아 놓은 공유 목록입니다. TOCTOU는 동시에 실행되는 작업들의 타이밍에 따라 결과가 달라지는 경쟁 조건의 한 종류입니다.

왜 발생하나요

1. 확인: 이 파일에 쓸 수 있는가? → 예
2. 틈: 다른 프로세스가 해당 이름이 가리키는 대상을 교체
↓ 확인 결과가 더 이상 현실과 일치하지 않음
3. 사용: 프로그램이 한 번도 확인하지 않은 대상에 씀
확인과 사용이 별도의 단계이면, 그 사이에 대상이 바뀌어 확인 결과가 낡은 정보가 될 수 있습니다.

CWE-367에 따르면, 그 결과로 접근해서는 안 되는 자원에 접근하거나, 원치 않는 방식으로 자원이 변경되거나, 로그가 누락되는 문제가 생길 수 있습니다. 이 틈은 짧을 수 있지만, 많은 작업이 동시에 실행되는 시스템에서는 우연히 한 번 맞는 것이 아니라 반복적으로 발생합니다.

어디에서 나타나나요

영역확인사용문제 발생 방식
파일 처리존재 여부 또는 권한 확인열기 또는 쓰기확인 후 파일이 교체됨
웹 앱의 재고 또는 잔액남은 수량을 SELECT수량을 줄이기 위해 UPDATE동시 요청 두 개가 모두 통과해 한도를 넘김
결제 및 가입아직 처리되지 않았는가?작업 실행중복 제출로 두 번 실행됨
파일 업로드내용 검사저장 또는 게시검사 후 내용이 바뀜

업로드 검사에 대해서는 파일 업로드 취약점도 함께 참고하세요.

방어: 확인과 사용을 분리하지 마세요

1

사용 전에 확인하지 마세요

CWE-367의 가장 기본적인 조언은 사용 전에 확인을 수행하지 않는 것입니다. 자원을 바로 사용하고, 실패하면 오류를 처리하세요. 이렇게 하면 틈 자체가 사라집니다.

2

경로가 아니라 파일 디스크립터를 사용하세요

먼저 파일을 연 다음, 열린 파일 디스크립터를 통해 상태를 확인하고 씁니다. 같은 경로 이름을 반복해서 조회하면 매번 다른 대상을 가리킬 수 있습니다. O_NOFOLLOW(심볼릭 링크를 따라가지 않음)와 같은 플래그나 openat(디렉터리 기준 상대 경로로 열기)과 같은 호출도 도움이 됩니다. 사용 가능한 기능은 운영체제에 따라 다릅니다.

3

데이터베이스에는 조건부 업데이트와 트랜잭션을 사용하세요

"확인을 위한 SELECT 후 UPDATE" 대신, 조건을 포함한 UPDATE 하나를 사용하세요(예: 수량이 1 이상일 때만 차감). 여러 문장이 관련된 경우에는 적절한 격리 수준과 행 잠금을 갖춘 트랜잭션을 사용하세요.

4

확인 전에 잠그세요

잠금을 사용한다면, CWE-367의 설명대로 확인 이전에 잠금을 획득하세요. 확인 후에 잠그면, 확인한 대상이 사용하는 대상이라는 보장이 없습니다.

5

멱등성 키로 중복 실행을 막으세요

결제 및 가입의 경우 각 요청에 고유한 키(멱등성 키)를 부여하고, 키마다 작업을 한 번만 실행하세요.

내 코드를 점검하는 방법

직접 만들었거나 관리하는 코드에서 다음을 수행하세요.

  1. 확인 코드와 사용 코드가 별도의 호출로 나뉘어 있는 곳을 찾으세요(존재 확인 후 열기, SELECT 후 UPDATE)
  2. 각 경우에 대해, 확인을 없애고 단계를 하나의 연산으로 만들 수 있는지 살펴보세요
  3. 같은 요청을 동시에 여러 번 보내는 테스트를 작성하고, 한 번만 적용되는지 확인하세요
  4. 타인의 서비스에는 절대 시도하지 마세요. 자신의 환경을 사용하세요

이 사이트의 견해: 확인을 사용과 같은 연산 안에 넣으세요

TOCTOU는 "누군가 확인을 빠뜨린" 문제가 아닙니다. 확인 자체는 존재하지만 사용과 분리되어 있습니다. 확인 코드를 더 추가한다고 해결되지 않습니다. 해결책은 확인을 추가 단계로 두는 것이 아니라, 확인을 사용과 같은 원자적 연산 안에 넣는 것입니다. 코드 리뷰에서 도움이 되도록 IDOR와 함께 학습해 보세요. 둘 다 "확인은 존재하지만 제 역할을 하지 못하는" 버그입니다.

출처(1차 자료)

  • MITRE CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition — cwe.mitre.org (정의, 결과, 완화 방법)
  • 구체적인 기법(O_NOFOLLOW, openat, 멱등성 키, 트랜잭션)은 일반적인 구현 관행으로 설명되었으며, 사용 가능 여부는 운영체제와 데이터베이스에 따라 다르므로 각 제품의 공식 문서를 확인하세요

다음으로 읽을거리

분류 번호

CWE는 취약점의 원인이 되는 약점의 종류를, MITRE ATT&CK는 공격자의 기법을 분류한 번호 체계입니다. 둘 다 MITRE가 관리하며 취약점 정보와 탐지 규칙 분류에 널리 쓰입니다.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QTOCTOU는 무엇을 의미하나요?
A

time-of-check to time-of-use의 약자입니다. 자원의 상태가 확인된 시점과 사용된 시점 사이에 바뀌는 문제를 뜻합니다. MITRE의 CWE-367은 제품이 자원의 상태를 확인한 뒤 사용하는데, 그 상태가 확인을 무효화하는 방식으로 바뀔 수 있는 약점이라고 설명합니다. 경쟁 조건의 한 종류입니다.

QTOCTOU는 어디에서 발생하나요?
A

대표적인 곳은 파일 처리입니다. 프로그램이 파일이 존재하거나 쓰기 가능한지 확인한 뒤 별도의 호출로 파일을 열면, 그 사이에 파일이 바뀔 수 있습니다. 웹 앱과 데이터베이스에서도 발생합니다. 예를 들어 '재고 확인 후 주문 확정'이나 '잔액 확인 후 차감'처럼 확인과 갱신이 별도의 단계일 때입니다.

Q주된 방어 방법은 무엇인가요?
A

확인과 사용을 하나의 원자적 연산으로 결합하세요. CWE-367은 가장 기본적인 조언으로, 사용 전에 확인을 수행하지 말라고 합니다. 파일의 경우 먼저 열고, 열린 파일 디스크립터를 통해 검사하거나 작업하세요. 데이터베이스의 경우 조건부 업데이트를 사용하거나, 잠금이 포함된 트랜잭션을 사용하세요.

Q잠금을 추가하면 항상 안전한가요?
A

잠금은 확인 이후가 아니라 확인 이전에 획득해야 합니다. CWE-367은 잠금이 확인 이후가 아니라 확인 이전에 이루어지도록 하라고 설명합니다. 확인 후에 잠금을 걸면, 확인한 대상이 사용하는 대상과 같다는 보장이 없습니다. 또한 잠금의 범위가 너무 좁거나 다른 프로그램이 잠금을 무시하면 아무 효과도 없습니다.

QTOCTOU는 웹 애플리케이션에도 영향을 주나요?
A

네, 영향을 줍니다. 예를 들어 업로드된 파일을 검사한 뒤 저장하는 경우, 읽은 후 쿠폰이나 재고 수량을 차감하는 경우, 두 번 실행되면 안 되는 결제 처리기 등이 있습니다. 같은 요청이 동시에 두 번 도착하면 둘 다 확인을 통과할 수 있습니다. 갱신을 하나의 조건부 연산으로 만들고, 멱등성 키를 사용해 중복 실행을 막으세요.

Q내 코드에서 TOCTOU를 어떻게 찾나요?
A

확인하는 코드와 사용하는 코드가 별도의 줄이나 호출로 나뉘어 있는 곳을 찾으세요. 파일 코드에서는 존재 여부나 권한을 확인한 뒤 경로로 여는 부분이 해당합니다. 데이터베이스 코드에서는 확인을 위한 SELECT 다음에 UPDATE가 오는 부분이 해당합니다. 그다음 확인을 없애고 하나의 연산으로 만들 수 있는지 살펴보고, 동시 요청 테스트를 추가하세요.