[주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스] 4강 — [Day 4] 에러 페이지 적용 미흡
안녕하세요! Hackerstory 공부방의 IT/보안 튜터 정다은입니다. 👋
어느덧 [주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스]의 Day 4에 오신 여러분을 환영합니다!
지난 시간까지 다뤘던 직접적인 공격 기법(인젝션)이나 서버 구조 탐색(디렉터리 인덱싱)에 이어, 오늘은 공격자에게 시스템의 내부 정보를 고스란히 바치는 '[Day 4] 에러 페이지 적용 미흡' 취약점에 대해 배워보겠습니다.
"에러 좀 난 게 뭐가 대수라고?" 하고 넘어가기 쉽지만, 사실 이 에러 페이지는 공격자에게 시스템 내부를 들여다보는 거울 역할을 합니다. 초보자분들도 이해하기 쉽게 원리부터 대응 방안까지 하나씩 풀어드릴게요!
[Day 4] 에러 페이지 적용 미흡 (Imperfect Error Page Application)
1. 개념 이해하기: 에러 페이지 적용 미흡이란?
💡 "시스템의 무심한 친절이 공격자의 무기가 됩니다"
우리가 웹 사이트를 이용하다 보면 잘못된 주소를 입력하거나 시스템 내부 오류가 발생할 때가 있습니다. 이때 개발자나 관리자가 **‘예외 처리(Exception Handling)’**를 제대로 해두지 않았거나 **‘사용자 정의 에러 페이지(Custom Error Page)’**를 설정하지 않았다면 어떻게 될까요?
웹 서버나 애플리케이션 프레임워크는 자신이 가진 기본(Default) 에러 화면을 띄워줍니다. 그런데 이 기본 에러 화면에는 개발 편의를 위해 포함된 매우 치명적인 디버깅 정보들이 들어있습니다.
- DBMS 종류 및 버전, SQL 쿼리문, 테이블/컬럼명
- 웹 서버 및 OS(운영체제) 종류와 버전
- 애플리케이션 프레임워크의 콜 스택(Call Stack) 및 절대 경로(Absolute Path)
- 소스 코드 내부 구문 및 주석
⚠️ 위험성 (Impact)
이 취약점 자체가 바로 서버를 뚫고 들어가는 것은 아닙니다. 하지만 공격자는 이 정보를 바탕으로 **시스템의 지도(Footprinting)**를 그립니다.
예를 들어 PostgreSQL 12.2 버전을 사용하는 것을 에러 메시지로 확인했다면, 공격자는 곧바로 해당 버전에 존재하는 알려진 0-day/1-day 취약점 공격 코드를 검색하여 정밀 타격을 시도하게 됩니다.
2. 취약점 동작 원리 및 실제 예시
그럼 실제 현장에서는 어떤 방식으로 에러 메시지가 노출되는지 3가지 주요 유형으로 살펴보겠습니다.
예시 ① DBMS 오류 메시지 노출 (Database Error Leakage)
로그인 페이지의 ID 입력창에 따옴표(') 하나를 넣어 유효하지 않은 값을 전송했을 때, 서버가 내부 예외를 처리하지 못하면 화면에 다음과 같은 메시지가 출력될 수 있습니다.
Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found:
1146 Table 'corp_db.user_table_v2' doesn't exist in /var/www/html/login.php:34
Stack trace:
#0 /var/www/html/login.php(34): PDO->query('SELECT * FROM u...')
#1 {main}
thrown in /var/www/html/login.php on line 34
🔍 공격자가 얻은 정보:
- DB 종류: MySQL/MariaDB (PDO 구조)
- 내부 데이터베이스명:
corp_db- 내부 테이블명:
user_table_v2- 웹 서버 내부 Absolute Path:
/var/www/html/
예시 ② 프레임워크 디버그 모드 노출 (Framework Debug Mode)
Django, Laravel, Spring 등 현대 웹 프레임워크는 개발 단계에서 유용한 디버거(Debugger) 화면을 제공합니다. 하지만 **운영 환경(Production)**으로 이관할 때 디버그 설정을 끄지 않으면 아래와 같이 매우 상세한 콜 스택과 환경 변수가 노출됩니다.
(개념 이미지)
- Django 예시 (
DEBUG = True설정 시): 웹 페이지에 오류 발생 시環境變數(Environment Variables),SECRET_KEY, 설치된 패키지 리스트, 절대 경로, Python 구문이 화면 전체에 렌더링됩니다.
예시 ③ 웹 서버 버전 및 OS 정보 노출 (Web Server Default 404/500)
존재하지 않는 페이지(https://example.com/non_existent_file)를 요청했을 때, 웹 서버의 기본 에러 페이지가 노출되는 경우입니다.
404 Not Found
---------------------------------------------------
Apache/2.4.41 (Ubuntu) Server at target.com Port 80
🔍 공격자가 얻은 정보: 웹 서버가
Apache 2.4.41이며, 서버 OS는Ubuntu Linux라는 점을 단번에 파악할 수 있습니다.
3. 보안 대책 및 대응 방안
에러 페이지 적용 미흡 취약점을 해결하기 위해서는 [1] 개발 단계의 예외 처리와 [2] 서버/프레임워크 설정 변경이라는 2가지 트랙으로 접근해야 합니다.
대응 1. 세심한 예외 처리 (Try-Catch & Logging)
소스 코드 내에서 에러가 발생할 수 있는 구문(DB 연동, 파일 I/O 등)은 반드시 try-catch 블록으로 감싸야 합니다.
❌ 취약한 코드 (PHP 예시):
// 에러 발생 시 화면에 그대로 에러 노출 $stmt = $pdo->query("SELECT * FROM users WHERE id = " . $_GET['id']); $user = $stmt->fetch();⭕ 안전한 코드 (PHP 예시):
try { $stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id"); $stmt->execute(['id' => $_GET['id']]); $user = $stmt->fetch(); } catch (Exception $e) { // 1. 상세 에러는 서버 내부 로그 파일에만 기록 error_log($e->getMessage()); // 2. 사용자에게는 추상화된 정중한 메시지만 전달 header("Location: /error/500.html"); exit(); }
대응 2. 프레임워크 운영 모드 전환 (Disable Debug)
배포 전, 프레임워크의 환경 설정 파일에서 디버그 옵션을 False / Off로 변경합니다.
- Django (
settings.py):DEBUG = False ALLOWED_HOSTS = ['yourdomain.com'] - Laravel (
.env):APP_ENV=production APP_DEBUG=false - PHP (
php.ini):display_errors = Off log_errors = On
대응 3. 사용자 정의 에러 페이지 (Custom Error Page) 적용
웹 서버(Nginx, Apache, IIS 등) 차원에서 모든 HTTP 에러 코드(403, 404, 500 등)에 대해 미리 준비한 일관된 디자인의 Custom 에러 페이지를 렌더링하도록 설정합니다.
Nginx 설정 (
nginx.conf):server { # ... 기존 설정 ... # Server 토큰(버전 정보) 숨기기 server_tokens off; # Custom 에러 페이지 지정 error_page 403 404 /error/40x.html; error_page 500 502 503 504 /error/500.html; location = /error/500.html { root /var/www/html; internal; } }Apache 설정 (
httpd.conf또는.htaccess):# Apache 버전 정보 숨기기 ServerTokens Prod ServerSignature Off # Custom 에러 페이지 지정 ErrorDocument 404 /error/404.html ErrorDocument 500 /error/500.html
4. 오늘 강의 핵심 요약 📝
- 원인: 서버 오류 발생 시 예외 처리가 미흡하여 상세한 기술적 스택(DBMS, OS, 경로, 버전)이 외부로 출력되는 현상.
- 영향: 정보 수집(Footprinting)을 허용하여 2차 정밀 공격(Targeted Attack)의 빌미를 제공함.
- 진단 포인트:
- 존재하지 않는 URL 호출 (404 유도)
- 특수문자(
',",\등) 및 비정상 인자값 입력 (500 유도) - 웹 서버 응답 헤더 및 에러 바디 확인
- 조치 방안:
- 소스 코드 단위의
Try-Catch처리 및 서버 측 에러 로깅(error_log) - 프레임워크
DEBUG모드 비활성화 (Production환경 전환) - 웹 서버 차원의
Custom Error Page등록 및Server Tokens비활성화
- 소스 코드 단위의
🎁 정다은 튜터의 한마디
"보안은 공격자에게 단 1%의 힌트도 주지 않는 것에서 시작합니다. 사용자에게는 '시스템에 일시적인 오류가 발생했습니다'라는 친절한 안내 페이지를 보여주고, 세부적인 오류 내용은 오직 서버 내부의 로그 파일에만 기록하는 습관! 꼭 기억해 주세요."
🔮 다음 챕터 예고: [Day 5] 정보 노출 (Information Exposure)
다음 시간에는 에러 페이지뿐만 아니라, **웹 애플리케이션 곳곳에 방치된 다양한 민감 정보들(소스 코드 주석, 백업 파일, 관리자 주소, Git/SVN 메타데이터 등)**을 탐지하고 차단하는 '[Day 5] 정보 노출' 취약점에 대해 다뤄보겠습니다.
오늘도 고생 많으셨습니다. 다음 시간에 만나요! 질문은 댓글로 편하게 남겨주세요! 😊
댓글 0
로그인하면 댓글을 작성할 수 있습니다.