[시큐어코딩 가이드] 오류 메시지 정보노출
- 정보보안/시큐어코딩 가이드
- 2022. 8. 9.
■ 에러처리
에러를 처리하지 않거나, 불충분하게 처리하여 에러 정보에 중요정보(시스템 내부정보 등)가 포함될 때, 발생할 수 있는 취약점으로 에러를 부적절하게 처리하여 발생하는 보안약점이다.
오류 메시지 정보노출
■ 개요
응용프로그램이 실행환경, 사용자 등 관련 데이터에 대한 민감한 정보를 포함하는 오류 메시지를 생성하여 외부에 제공하는 경우, 공격자의 악성 행위를 도울 수 있다. 예외발생 시 예외 이름이나 트레이스백(traceback)를 출력하는 경우, 프로그램 내부 구조를 쉽게 파악할 수 있기 때문이다.
Django 프레임워크와 Flask 프레임워크는 HTTP 오류 코드가 있는 요청을 처리하기 위한 사용자 에러 페이지 핸들러를 제공한다.
■ 안전한 코딩 기법
오류 메시지는 정해진 사용자에게 유용한 최소한의 정보만 포함하도록 한다. 소스코드에서 예외 상황은 내부적으로 처리하고 사용자에게 시스템 내부 정보 등 민감한 정보를 포함하는 오류를 출력하지 않도록 미리 정의된 메시지를 제공하도록 설정한다.
Django 프레임워크에서는 urls.py에 사용자 정의 에러 페이지를 핸들러를 정의 할 수 있다.
코드예제
사용자 요청을 처리할 수 없는 경우 에러 페이지에 디버그 정보 또는 서버의 정보가 노출될 수 있다. 만일 어플리케이션을 배포 할 때 DEBUG 모드를 True로 설정 하고 배포할 경우에 아래와 같이 시스템의 주요 정보가 노출 될 수도 있다.
Django는 DEBUG 모드를 False로 배포했을 경우 아래와 같이 사용자 에러페이지를 설정하지 않을 경우에는 Django 기본 에러페이지가 보이게 된다.
안전하지 않은 코드의 예 |
# config/urls.py # 별도 에러페이지를 선언하지 않아 django의 기본 에러페이지를 출력한다. |
제공되는 에러 페이지 핸들러를 이용해 별도의 에러 페이지를 생성하여 사용자에게 표현하고 서버의 정보노출을 최소화 한다.
안전한 코드의 예 |
# config/urls.py from django.conf.urls import handler400, handler403, handler404, handler500 # 사용자 정의 에러페이지를 지정하고 # views.py에 사용자 정의 에러페이지에 대한 코드를 구현하여 사용한다. handler400 = "blog.views.error400" handler403 = "blog.views.error403" handler404 = "blog.views.error404" handler500 = "blog.views.error500“ |
아래는 traceback을 사용하여 에러 스택을 표준출력으로 표시하는 예제이다.
안전하지 않은 코드의 예 |
import traceback def fetch_url(url, useragent, referer=None, retries=1, dimension=False): ...... try: response = requests.get(url, stream=True, timeout=5, headers={ 'User-Agent': useragent, 'Referer': referer, }) ...... except IOError: # 에러메시지를 통해 스택정보가 노출됨. traceback.print_exc() break |
오류 처리 시 아래와 같이 에러 이름이나 에러 추적 정보가 노출 되지 않도록 한다.
안전한 코드의 예 |
import logging def fetch_url(url, useragent, referer=None, retries=1, dimension=False): ...... try: response = requests.get(url, stream=True, timeout=5, headers={ 'User-Agent': useragent, 'Referer': referer, }) ...... except IOError: # 에러 코드와 정보를 별도로 정의하고 최소 정보만 로깅 logger.info('ERROR-01:통신에러') break |