Skip to content

Commit 3d8a9b0

Browse files
committed
docs: SC(7-2)
1 parent dec6f88 commit 3d8a9b0

File tree

12 files changed

+174
-0
lines changed

12 files changed

+174
-0
lines changed

_posts/2025-10-15-SC(7-2).md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
title: "[Security] Secure Coding(7-2) - XSS 진단 및 대응"
3+
4+
categories: [Security, Secure Coding]
5+
tags:
6+
- [Security, Cyberattacks, 보안, 시큐어 코딩, XSS, Cross site scripting]
7+
toc: true
8+
toc_sticky: true
9+
10+
date: 2025-10-15
11+
last_modified_at: 2025-10-15
12+
---
13+
>🔒 시큐어 코딩 수업 정리
14+
15+
## XSS
16+
📚**<span style="color: #008000">XSS</span>**: 검증되지 않은 외부 입력 값을 웹 응답에 그대로 반영하여 **악의적 스크립트가 실행**되는 취약점
17+
→ 사용자 브라우저에서 악성 코드가 동작해, 쿠키· 세션 등 민감 정보 탈취 가능
18+
19+
**발생 원인**
20+
* 외부에서 입력된 사용자 입력 값을 검증하지 않고 그대로 응답에 반영
21+
* DB에 저장된 데이터를 읽어서 출력할 때 DB에서 읽어온 값을 검증하지 않고 출력 값으로 사용
22+
* 자바스크립트로 DOM구조를 조작하여 페이지를 변경하는 경우 변경되는 내용을 검증하지 않고 브라우저에 표시하는 경우
23+
24+
### XSS 공격 흐름
25+
26+
![alt text](../assets/img/SC/XSSflow.png)
27+
28+
### XSS 3가지 유형
29+
30+
#### 🔄 Reflected XSS (반사형)
31+
* 사용자 입력이 **즉시 반영**되어 페이지에 표시
32+
* 검색창, URL 파라미터 등을 통해 스크립트가 반사되어 실행
33+
* 일회성 공격
34+
35+
#### 💾 Stored XSS (저장형)
36+
* 게시판, 댓글, 프로필 등 DB에 악성 스크립트가 저장되어 **다수 사용자에게 전파**
37+
* 지속적인 공격
38+
39+
#### 🌐 DOM-based XSS
40+
* 클라이언트 측 스크립트(DOM 조작)에서 발생
41+
* `location.hash`, `location.search` 등 브라우저 객체를 통한 동적 스크립트 삽입
42+
* 서버 로그에 기록되지 않음 → 탐지가 어려움
43+
44+
### XSS 공격 피해
45+
1. **세션 쿠키 탈취**
46+
* 자동 로그인, 권한 정보 등 노출
47+
48+
2. **사용자 계정·개인정보 유출**
49+
* 이메일, 전화번호, 주소 등 민감 정보 수집
50+
* 폼에 입력한 비밀번호나 카드 정보 탈취
51+
52+
3. **브라우저 무단 제어**
53+
* 임의 스크립트 실행 → 가짜 폼 표시
54+
* 피싱 페이지로 이동
55+
* 내부 네트워크 스캔 등
56+
57+
4. **기업 이미지 타격**
58+
* 웹사이트 변조로 신뢰도 하락
59+
* 고객 정보 유출로 인한 법적 문제
60+
61+
---
62+
63+
## XSS 취약점 진단
64+
65+
### Reflected XSS
66+
* 사용자가 요청한 값을 **서버에서 검증하지 않고 응답으로 사용하는 경우** 발생
67+
68+
![alt text](../assets/img/SC/ReflectedXSS.png)
69+
70+
![alt text](../assets/img/SC/ReflectedXSS1.png)
71+
72+
### Stored XSS
73+
* 공격자가 서버에 저장한 스크립트를 사용자가 열람하는 경우 스크립트가 다운로드 되어 사용자의 브라우저에서 실행
74+
75+
![alt text](../assets/img/SC/StoredXSS.png)
76+
77+
![alt text](../assets/img/SC/StoredXSS1.png)
78+
79+
### DOM 기반 XSS
80+
* 자바스크립트로 DOM 객체 정보를 사용하여 Document에 write를 수행하는 경우 스크립트가 사용자의 브라우저에서 실행
81+
82+
![alt text](../assets/img/SC/DOMXSS.png)
83+
84+
![alt text](../assets/img/SC/DOMXSS1.png)
85+
86+
---
87+
88+
## XSS 취약점 방어
89+
90+
### 입출력 값 검증 및 필터링
91+
* **제한적인 입력 값 허용**
92+
* 클라이언트 프로그램과 서버 애플리케이션에서 [HTTP 헤더, 쿠키, 쿼리 스트링, 폼 필드, 히든 필드] 등의 모든 인자들에 대해 허용된 유형의 데이터만을 받아들이도록 **정규식을 이용하여 제한된 입력 값을 받아서 처리**
93+
* **제한적인 출력 값 허용**
94+
* 입력 값이나 DB에서 조회한 결과 값을 응답으로 내보내기전에 `XssFilter`를 적용하여 동적으로 스크립트가 실행될 수 있는 요소들은 HTML인코딩을 적용하여 출력
95+
96+
![alt text](../assets/img/SC/filteringcontext.png)
97+
> 필터링 또는 변환되어야 하는 특수문자들
98+
99+
![alt text](../assets/img/SC/bantag.png)
100+
> 차단되어야 하는 태그들
101+
102+
---
103+
104+
### HTML 엔티티 이스케이프 처리
105+
📚**<span style="color: #008000">HTML 엔티티 이스케이프(Entity Escape)</span>**: HTML 문서에서 특수 문자가 브라우저에 의해 태그나 코드로 해석되지 않도록, **해당 문자를 엔티티 코드(예: `<``&lt;`)로 변환하는 기법**
106+
107+
**XSS 공격 방어 방법**
108+
* 사용자 입력에 포함된 `<script>` 태그 등 악의적인 스크립트가 실행되지 않도록 보호
109+
* 서버와 클라이언트 모두에서 출력 전에 반드시 이스케이프 처리 필요
110+
* **동적 콘텐츠 출력 시** (특히 사용자 입력을 직접 HTML에 삽입하는 경우)
111+
112+
* **❌취약한 코드 예시**
113+
114+
```javascript
115+
// 사용자 입력을 가져와서 그대로 innerHTML에 할당 (취약)
116+
var userInput = getUserInput();
117+
document.getElementById("content").innerHTML = userInput;
118+
```
119+
120+
* **공격 시나리오**
121+
* 사용자가 `<script>alert('XSS');</script>`와 같은 입력을 전달하면, **해당 스크립트가 실행**되어 공격자가 쿠키 탈취, 세션 하이재킹 등 다양한 공격을 수행할 수 있음
122+
123+
***안전한 코드 예시**
124+
* 방법 1: **사용자 입력 이스케이프 함수 적용**
125+
126+
```javascript
127+
//사용자 입력을 HTML 엔티티로 변환하는 함수를 사용하여 안전하게 출력
128+
function escapeHtml(text) {
129+
return text.replace(/&/g, "&amp;")
130+
.replace(/</g, "&lt;")
131+
.replace(/>/g, "&gt;")
132+
.replace(/"/g, "&quot;")
133+
.replace(/'/g, "&#039;");
134+
}
135+
136+
var userInput = getUserInput(); // 예: "<script>alert('XSS');</script>"
137+
var safeInput = escapeHtml(userInput);
138+
document.getElementById("content").innerHTML = safeInput;
139+
```
140+
141+
* 방법 2: **textContent 속성 사용**
142+
143+
```javascript
144+
//DOM에 텍스트만 삽입하여 브라우저가 HTML로 해석하지 않도록 함
145+
var userInput = getUserInput(); // 사용자 입력
146+
document.getElementById("content").textContent = userInput;
147+
```
148+
149+
---
150+
151+
### Spring Web MVC에서 입출력 필터링
152+
153+
![alt text](../assets/img/SC/SpringWebMVCfilter.png)
154+
155+
---
156+
157+
### CSP(Content-Security-Policy) 적용
158+
* **HTTP 응답 헤더 CSP를 통해 설정함**
159+
160+
**XSS 공격 방어 효과**
161+
* **인라인 스크립트 차단**
162+
* 기본적으로 'unsafe-inline' 없이 **스크립트 실행을 제한**하여, 악의적으로 삽입된 인라인 코드가 실행되지 않도록 함
163+
164+
* **신뢰하는 스크립트만 허용**
165+
* 신뢰할 수 있는 도메인에서 제공하는 스크립트만 로드하게 하여, **외부 공격자의 스크립트 주입 차단**
166+
167+
* **동적 코드 실행 방지**
168+
* `eval()`이나 `new Function()` 같은 동적 코드 실행을 제한할 수 있음
169+
170+
* XSS 방어와 CSP의 연계
171+
* CSP는 XSS 취약점이 존재하더라도, 악의적 스크립트 실행을 실질적으로 차단하여 추가적인 방어층을 제공
172+
173+
![alt text](../assets/img/SC/defendXSS.png)
174+
> 예시: 웹 서버별 CSP 헤더 설정

assets/img/SC/DOMXSS.png

139 KB
Loading

assets/img/SC/DOMXSS1.png

109 KB
Loading

assets/img/SC/ReflectedXSS.png

127 KB
Loading

assets/img/SC/ReflectedXSS1.png

109 KB
Loading
156 KB
Loading

assets/img/SC/StoredXSS.png

141 KB
Loading

assets/img/SC/StoredXSS1.png

138 KB
Loading

assets/img/SC/XSSflow.png

177 KB
Loading

assets/img/SC/bantag.png

67.7 KB
Loading

0 commit comments

Comments
 (0)