본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 10. 31. · 28 Views
XSS 방어 웹 보안 가이드
XSS(Cross-Site Scripting) 공격으로부터 웹 애플리케이션을 보호하는 방법을 학습합니다. 실제 코드 예제를 통해 안전한 데이터 처리 방법을 익힐 수 있습니다.
들어가며
이 글에서는 XSS 방어 웹 보안 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- 기본_HTML_이스케이프
- textContent_사용하기
- URL_검증하기
- DOMPurify_라이브러리_사용
- CSP_헤더_설정
- 쿠키_보안_설정
- React에서_안전하게_렌더링
- 입력값_검증과_제한
- JSON_안전하게_다루기
- 이벤트_핸들러_안전하게_사용
1. 기본 HTML 이스케이프
개요
사용자 입력을 HTML에 삽입할 때는 반드시 특수 문자를 이스케이프해야 합니다. <, >, &, " 등의 문자를 안전한 형태로 변환합니다.
코드 예제
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
console.log(escapeHtml('<script>alert("XSS")</script>'));
// 출력: <script>alert("XSS")</script>
설명
특수 문자를 HTML 엔티티로 변환하여 스크립트가 실행되지 않도록 방지합니다. 이는 XSS 방어의 가장 기본적인 방법입니다.
2. textContent 사용하기
개요
DOM을 조작할 때 innerHTML 대신 textContent를 사용하면 HTML 태그가 실행되지 않고 텍스트로만 처리됩니다.
코드 예제
const userInput = '<img src=x onerror=alert("XSS")>';
// 안전하지 않음
// element.innerHTML = userInput;
// 안전함
const element = document.getElementById('output');
element.textContent = userInput;
// 화면에 그대로 텍스트로 표시됨
설명
textContent는 입력값을 HTML로 해석하지 않고 순수한 텍스트로 처리하므로 스크립트 실행을 원천 차단합니다.
3. URL 검증하기
개요
사용자가 입력한 URL을 링크나 리다이렉트에 사용할 때는 javascript: 프로토콜 등 위험한 스키마를 차단해야 합니다.
코드 예제
function isSafeUrl(url) {
const allowedProtocols = ['http:', 'https:', 'mailto:'];
try {
const parsed = new URL(url, window.location.href);
return allowedProtocols.includes(parsed.protocol);
} catch {
return false;
}
}
console.log(isSafeUrl('https://example.com')); // true
console.log(isSafeUrl('javascript:alert(1)')); // false
설명
URL 객체로 파싱하여 프로토콜을 검증함으로써 악의적인 자바스크립트 실행을 방지합니다.
4. DOMPurify 라이브러리 사용
개요
사용자가 입력한 HTML을 안전하게 정화(sanitize)해주는 라이브러리를 사용하면 신뢰할 수 있는 HTML만 허용할 수 있습니다.
코드 예제
// DOMPurify 라이브러리 사용 예제
import DOMPurify from 'dompurify';
const dirtyHtml = '<p>안전한 텍스트</p><script>alert("XSS")</script>';
const cleanHtml = DOMPurify.sanitize(dirtyHtml);
console.log(cleanHtml);
// 출력: <p>안전한 텍스트</p>
// <script> 태그는 제거됨
설명
DOMPurify는 위험한 태그와 속성을 자동으로 제거하여 안전한 HTML만 남깁니다. 리치 텍스트 에디터에 적합합니다.
5. CSP 헤더 설정
개요
Content Security Policy 헤더를 설정하면 브라우저가 허용된 출처의 스크립트만 실행하도록 제한할 수 있습니다.
코드 예제
// Express.js 서버 예제
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'"
);
next();
});
설명
CSP 헤더로 자기 도메인의 스크립트만 실행을 허용하여 외부에서 삽입된 악성 스크립트를 차단합니다.
6. 쿠키 보안 설정
개요
쿠키에 HttpOnly와 Secure 플래그를 설정하면 자바스크립트로 쿠키에 접근하지 못하고 HTTPS에서만 전송됩니다.
코드 예제
// Express.js에서 쿠키 설정
res.cookie('sessionId', 'abc123', {
httpOnly: true, // JS로 접근 불가
secure: true, // HTTPS만 허용
sameSite: 'strict', // CSRF 방어
maxAge: 3600000
});
// 클라이언트에서 document.cookie로 접근 불가
설명
HttpOnly 플래그는 XSS 공격으로 쿠키를 탈취하는 것을 방지하고, Secure 플래그는 전송 중 쿠키를 보호합니다.
7. React에서 안전하게 렌더링
개요
React는 기본적으로 중괄호 {}로 렌더링할 때 자동으로 이스케이프하지만, dangerouslySetInnerHTML은 주의해서 사용해야 합니다.
코드 예제
import React from 'react';
function SafeComponent({ userInput }) {
// 안전: 자동 이스케이프됨
return <div>{userInput}</div>;
// 위험: HTML이 그대로 실행됨
// return <div dangerouslySetInnerHTML={{__html: userInput}} />;
}
// 사용 예
<SafeComponent userInput="<script>alert('XSS')</script>" />
설명
React는 중괄호 내부의 값을 자동으로 이스케이프하므로 일반적인 경우 안전합니다. dangerouslySetInnerHTML은 꼭 필요할 때만 사용하세요.
8. 입력값 검증과 제한
개요
서버와 클라이언트 양쪽에서 입력값을 검증하고 길이를 제한하여 악의적인 입력을 차단합니다.
코드 예제
function validateInput(input) {
// 길이 제한
if (input.length > 1000) return false;
// 허용된 문자만 사용 (예: 영문, 숫자, 공백)
const pattern = /^[a-zA-Z0-9\s]+$/;
return pattern.test(input);
}
const userInput = prompt('이름을 입력하세요:');
if (validateInput(userInput)) {
console.log('안전한 입력:', userInput);
} else {
console.log('유효하지 않은 입력입니다.');
}
설명
허용된 문자 패턴을 정의하고 검증함으로써 악의적인 스크립트나 특수 문자가 포함된 입력을 사전에 차단합니다.
9. JSON 안전하게 다루기
개요
사용자 입력을 JSON으로 처리할 때는 JSON.parse와 JSON.stringify를 사용하여 안전하게 직렬화합니다.
코드 예제
// 안전하지 않음: eval 사용 금지
// const data = eval('(' + userInput + ')');
// 안전함: JSON.parse 사용
const userInput = '{"name": "홍길동", "age": 25}';
try {
const data = JSON.parse(userInput);
console.log(data.name); // 홍길동
} catch (e) {
console.error('유효하지 않은 JSON');
}
설명
eval()은 임의의 코드를 실행할 수 있어 매우 위험합니다. JSON.parse()는 JSON 형식만 파싱하므로 안전합니다.
10. 이벤트 핸들러 안전하게 사용
개요
HTML 속성에 직접 이벤트 핸들러를 작성하지 말고 addEventListener를 사용하여 안전하게 이벤트를 처리합니다.
코드 예제
// 안전하지 않음: HTML 속성에 직접 작성
// <button onclick="alert('클릭')">버튼</button>
// 안전함: addEventListener 사용
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log('버튼이 클릭되었습니다.');
});
설명
addEventListener를 사용하면 사용자 입력이 코드로 해석될 가능성이 없어 더 안전합니다. HTML 속성 방식은 피하세요.
마치며
이번 글에서는 XSS 방어 웹 보안 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#JavaScript #XSS #WebSecurity #InputValidation #Sanitization
댓글 (0)
함께 보면 좋은 카드 뉴스
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
EFK 스택 로깅 완벽 가이드
마이크로서비스 환경에서 로그를 효과적으로 수집하고 분석하는 EFK 스택(Elasticsearch, Fluentd, Kibana)의 핵심 개념과 실전 활용법을 초급 개발자도 쉽게 이해할 수 있도록 정리한 가이드입니다.
Grafana 대시보드 완벽 가이드
실시간 모니터링의 핵심, Grafana 대시보드를 처음부터 끝까지 배워봅니다. Prometheus 연동부터 알람 설정까지, 초급 개발자도 쉽게 따라할 수 있는 실전 가이드입니다.
분산 추적 완벽 가이드
마이크로서비스 환경에서 요청의 전체 흐름을 추적하는 분산 추적 시스템의 핵심 개념을 배웁니다. Trace, Span, Trace ID 전파, 샘플링 전략까지 실무에 필요한 모든 것을 다룹니다.
Spring 예외 처리와 검증 완벽 가이드
스프링에서 예외를 우아하게 처리하고, 사용자 입력을 안전하게 검증하는 방법을 배웁니다. @ControllerAdvice부터 Bean Validation까지, 실무에서 바로 사용할 수 있는 예외 처리 전략을 다룹니다.