적절하지 않은 난수 값 사용
정의
예측 불가능한 숫자가 필요한 상황에서 예측 가능한 난수를 사용한다면, 공격자가 생성되는 다음 숫자를 예상해 시스템을 공격할 수 있다.
안전한 코딩기법
난수 발생기에서 시드(Seed)를 사용하는 경우에는 고정된 값을 사용하지 않고 예측하기 어려운 방법으로 생성된 값을 사용한다.
코드예제
random 라이브러리를 사용할 때는 유추하기 어려운 seed 값을 이용하여 난수를 생성해야 합니다. 다음은 안전하지 않은 코드예제입니다. 아래 코드와 같이 강도가 낮은 난수는 안전하지 않습니다.
#적절하지 않은 난수 값 사용(안전X)
def get_opt_num_bad(request):
random_str = ''
for i in range(6):
random_str += str(random.randrange(10))
return render(request, "success.html", {'msg': f'random : {random_str}'})
다음은 안전한 코드예제로 secrets 라이브러리를 사용해 6자리 난수 값을 생성하는 코드입니다.
#적절하지 않은 난수 값 사용(안전O)
def get_opt_num_good(request):
random_str = ''
for i in range(6):
random_str += str(secrets.randbelow(10))
return render(request, "success.html", {'msg': f'secrets : {random_str}'})
다음은 안전하지 않은 코드예제로, 세션 토큰값을 random 라이브러리를 사용해 생성하는 코드입니다.
#적절하지 않은 난수 값 사용(안전X)
def generate_session_key_bad(request):
RANDOM_STRING_CHARS = string.ascii_letters + string.digits
result = "".join(random.choice(RANDOM_STRING_CHARS) for i in range(32))
return render(request, 'success.html', {'msg': f"random : {result}"})
다음은 안전한 코드예제로, secrets 라이브러리를 사용하여 생성한 코드입니다.
#적절하지 않은 난수 값 사용(안전O)
def generate_session_key_good(request):
RANDOM_STRING_CHARS = string.ascii_letters + string.digits
result = "".join(secrets.choice(RANDOM_STRING_CHARS) for i in range(32))
return render(request, 'success.html', {'msg': f"secrets : {result}"})
보안기능/적절하지 않은 난수 값 사용
[참고문헌] Python 시큐어코딩 가이드(2022) / KISA(한국인터넷진흥원)