본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 10. 31. · 64 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)
함께 보면 좋은 카드 뉴스
Cron과 Webhooks 완벽 가이드
Node.js 환경에서 자동화의 핵심인 Cron 작업과 Webhooks를 활용하는 방법을 다룹니다. 정기적인 작업 스케줄링부터 외부 서비스 연동까지, 실무에서 바로 적용할 수 있는 자동화 기법을 배워봅니다.
보안 모델 및 DM Pairing 완벽 가이드
Discord 봇의 DM 보안 정책과 페어링 시스템을 체계적으로 학습합니다. dmPolicy 설정부터 allowlist 관리, 페어링 코드 구현까지 안전한 봇 운영의 모든 것을 다룹니다.
Media Pipeline 완벽 가이드
실무에서 자주 사용하는 미디어 파일 처리 파이프라인을 처음부터 끝까지 배웁니다. 이미지 리사이징, 오디오 변환, 임시 파일 관리까지 Node.js로 구현하는 방법을 초급 개발자도 이해할 수 있도록 쉽게 설명합니다.
Slack 통합 완벽 가이드 Bolt로 시작하는 기업용 메신저 봇 개발
Slack Bolt 프레임워크를 활용하여 기업용 메신저 봇을 개발하는 방법을 초급자도 이해할 수 있도록 단계별로 설명합니다. 이벤트 구독, 모달 인터랙션, 실전 배포까지 실무 활용 사례와 함께 다룹니다.
Discord 봇 개발 완벽 가이드
discord.js로 Discord 봇을 만들어봅시다. 실시간 채팅 연동부터 슬래시 커맨드까지, 실무 코드로 배우는 Discord 통합 가이드입니다.