Dev/Java

XSS 취약점 대응 및 출력 인코딩 설계

압뜔라뚜 2026. 4. 30. 18:47


1. 문제 상황
    게시판 서비스에서 사용자가 입력한 내용(게시글, 댓글 등)을 화면에 출력하는 과정에서 보안 취약점이 존재했습니다.

특히 사용자 입력값을 별도의 검증 없이 그대로 HTML에 렌더링하는 구조로 인해 다음과 같은 문제가 발생할 수 있었습니다.

* <script> 태그 삽입을 통한 악성 스크립트 실행 가능
* HTML 태그 조작을 통한 화면 변조
* 다른 사용자의 브라우저에서 의도치 않은 스크립트 실행

이러한 문제는 대표적인 웹 취약점인 Cross-Site Scripting(XSS) 공격으로 이어질 수 있는 위험 요소였습니다.



2. 기존 동작 흐름
    기존 시스템은 사용자 입력값을 그대로 저장하고 그대로 출력하는 구조였습니다.

1. 사용자가 게시글 또는 댓글 작성
2. 서버에서 별도의 필터링 없이 DB에 저장
3. 조회 시 HTML에 그대로 렌더링

이 구조의 가장 큰 문제는

사용자 입력값 = 신뢰된 데이터

로 간주하고 있다는 점이었습니다.



3. 개선 아이디어: 출력 시점 인코딩 전략

문제 해결의 핵심은 다음과 같습니다.

“입력값을 신뢰하지 말고, 출력 시점에 반드시 인코딩 처리한다”

이를 위해 HTML Escape 처리를 적용하여 브라우저가 태그를 코드가 아닌 단순 문자열로 인식하도록 변경했습니다.



4. 개선된 시스템 구조

입력 단계

* 사용자의 입력값은 그대로 저장 (데이터 원형 유지)

출력 단계

* 화면에 렌더링하기 전 HTML Escape 처리 수행
* 줄바꿈은 별도로 변환하여 사용자 가독성 유지



5. 구현 핵심 포인트

1. HTML Escape 처리

사용자 입력값을 그대로 출력하지 않고, 특수 문자를 치환하여 안전하게 렌더링합니다.

예시

String safeContent = StringEscapeUtils.escapeHtml4(content);

이 처리를 통해

* < → &lt;
* > → &gt;

로 변환되어 스크립트 실행이 차단됩니다.



2. 줄바꿈 처리 로직 분리

기존에는 저장 시 <br> 태그로 변환하는 방식이었으나, 이를 제거하고 출력 시점에 처리하도록 변경했습니다.

safeContent = safeContent.replace("\n", "<br>");

이 방식의 장점은

* 데이터 원형 보존
* 보안 처리와 표현 로직 분리

입니다.



3. 보안과 UX의 균형 유지

보안만 강화하면 사용자 경험이 깨질 수 있기 때문에

* 줄바꿈 유지
* 화면 가독성 확보

를 함께 고려했습니다.



6. 개선 결과 비교

Before

* 사용자 입력값 그대로 렌더링
* 스크립트 실행 가능성 존재
* XSS 공격 위험

After

* HTML Escape 적용으로 스크립트 실행 차단
* 안전한 문자열 기반 렌더링
* 보안성과 안정성 확보



7. 기술 개념 요약

XSS (Cross-Site Scripting)
웹 애플리케이션에 악성 스크립트를 삽입하여 다른 사용자에게 실행되도록 하는 공격 방식

HTML Escape
특수 문자를 치환하여 브라우저가 코드가 아닌 문자열로 인식하도록 만드는 처리 방식

출력 인코딩 (Output Encoding)
데이터를 출력하는 시점에 안전하게 변환하는 보안 기법



8. 마치며

이번 작업을 통해 사용자 입력값을 그대로 신뢰하는 것이 얼마나 위험한지 다시 한 번 확인할 수 있었습니다.

특히 보안 처리는 단순히 필터링을 추가하는 것이 아니라

데이터 흐름 전체를 고려한 설계가 필요하다는 점을 느꼈습니다.

앞으로는 XSS뿐만 아니라 SQL Injection, CSRF 등 다양한 웹 취약점에 대해서도 대응 범위를 확장해 나갈 계획입니다.




#웹보안
#XSS
#CrossSiteScripting
#HTML이스케이프
#SpringBoot
#Java
#보안취약점
#웹개발
#백엔드개발