경쟁조건 : 검사시점과 사용시점(TOCTOU)

김경민·2022년 6월 26일
1

security

목록 보기
9/15
post-thumbnail

경쟁조건 : 검사시점과 사용시점(TOCTOU)

병렬시스템 멀티프로세스로 구현한 응용프로그램 에서는 자원 파일 소켓 등 을 사용하기에 앞서 자원의 상태를 검사한다.

하지만, 자원을 사용하는 시점과 검사하는 시점이 다르기 때문에 검사하는 시점(Time Of Check)에 존재하던 자원이 사용하던 시점(Time Of Use)에 사라지는 등 자원의 상태가 변하는 경우가 발생한다.

하나의 자원에 대하여 동시에 검사시점과 사용시점이 달라 생기는 보안약점으로 인해 동기화 오류뿐만 아니라 교착상태 등과 같은 문제점이 발생할 수 있다.

Python에서 멀티스레드 환경에서 공유 자원에 여러 쓰레드가 접근하는 것을 막기 위해 Lock 객체를 제공한다. 자원의 상태를 잠금으로 변경하는 acquire() 메서드와 사용 중인 자원을 해제하는 release() 메서드를 제공한다.

안전하지 않은 코드의 예

1: import io                                                                                                     
2: import datetime                                                                                             
3: import threading                                                                                           
4: 
5: def write_shared_file(filename, content):                                                                     
6:  # 멀티스레드 환경에서는 다른 사용자들의 작업에 따라 파일이 사라질                    
7:  # 수 있기 때문에 공유 자원에 대해서는 검사와 사용을 동시에 해야 한다.
8:  if os.path.isfile(filename) is True:                                                                             
9:	f = open(filename, 'w')                                                                                        
10:	f.seek(0, io.SEEK_END)                                                                                         
11:	f.write(content)                                                                                             
12:	f.close()                                                                                                      
13:
14: def start():                                                                                                   
15:  filename = ‘./temp.txt’                                                                                    
16:  content = ‘start time is ’ + datetime.datetime.now()                                                 
17:  my_thread = threading.Thread(target=write_shared_file, args=(filename, content))            
18:  my_thread.start()                                                                                          

안전한 코드의 예

1:  import io                                                                                                       
2:  import datetime                                                                                               
3:  import threading                                                                                             
4:                                                                                                                    
5:  lock = threading.Lock()                                                                                      
6:  def write_shared_file(filename, content):                                                                  
7:	# lock 을 이용하여 여러 사용자가 동시에 파일에 접근하지 못하도록 제한         
8:	with lock:                                                                                                     
9:	    if os.path.isfile(filename) is True:                                                                          
10:	 	f = open(filename, 'w')                                                                                      
11:		f.seek(0, io.SEEK_END)                                                                                      
12:		f.write(content)                                                                                               
13:		f.close()                                                                                                        
14:                                                                                                                   
15: def start():                                                                                                      
16:  filename = ‘./temp.txt’                                                                                       
17:  content = ‘start time is ’ + datetime.datetime.now()                                                    
18:  my_thread = threading.Thread(target=write_shared_file, args=(filename, content))               
19:  my_thread.start()       

출처: 행정안전부 인터넷진흥원 Python 시큐어코딩 가이드

Python 시큐어코딩 가이드

0개의 댓글