[시큐어코딩 가이드] 2-1-16. 포맷 스트링 삽입

포맷 스트링 삽입

정의

  • 외부로부터 입력된 값을 검증하지 않고 입·출력 함수의 포맷 문자열로 그대로 사용하는 경우 발생할 수 있는 보안약점
  • 공격자는 포맷 문자열을 이용해 취약한 프로세스를 공격하거나 메모리 내용을 읽고 쓸 수 있으며, 이를 통해 취약한 프로세스의 권한을 취득해 임의의 코드를 실행

 

안전한 코딩기법

  • 포맷 문자열을 처리하는 함수 사용 시 사용자 입력값을 직접적으로 포맷 문자열로 사용하거나 포맷 문자열 생성에 포함시키지 않아야 한다.
  • 사용자로부터 입력받은 데이터를 포맷 문자열로 사용하고자 하는 경우에는 서식 지정자를 포함하지 않거나 파이썬의 내장함수 또는 내장변수 등이 포함되지 않도록 해야 한다.

 

코드예제

외부에서 입력받은 문자열을 바로 포맷스트링으로 사용하면 내부 정보가 외부로 노출될 수 있는 문제를 가지고 있습니다. 아래 예제는 안전하지 않은 코드예제입니다.

#포맷스트링 삽입(안전X)
AUTHENTICATE_KEY = 'Passw0rd'
def make_user_message_bad(request):
    user_id = request.GET.get('user_id')
    user_info = User.objects.get(id=user_id)
    format_string = request.GET.get('msg_format', '')

    message = format_string.format(user=user_info)
    return render(request, "success.html", {'data': message})

 

user_id=2&msg_format=만나서%20반가워요!%20{user.name}

 

외부에서 입력받은 문자열은 반드시 포맷 지정자를 이용해 바인딩 후에 사용해야 하며 직접적으로 포맷 문자열로 사용해서는 안됩니다. 다음은 안전한 코드예제입니다.

#포맷스트링 삽입(안전O)
def make_user_message_good(request):
    user_id = request.GET.get('user_id')
    user_info = User.objects.get(id=user_id)

    message = 'user name is {}.'.format(user_info.name)
    return render(request, "success.html", {'data': message})

 

user_id=1

 

 

 

입력데이터 검증 및 표현/포맷 스트링 삽입

[참고문헌] Python 시큐어코딩 가이드(2022) / KISA(한국인터넷진흥원)