JavaScript(ES2023 기준)을 기반으로 시큐어코딩(Secure Coding)에 대해 깊이 있게 알아보고,
Express.js, Node.js 등의 프레임워크를 활용한 실제 코드 예시를 통해 크로스사이트스크립트(XSS) 보안 취약점을 예방하는 전략을 소개해드릴게요.
XSS 보안 약점과 예방 방법
크로스사이트스크립트(XSS, Cross-Site Scripting)는 공격자가 악성 스크립트를 주입하여 사용자 브라우저에서 실행되도록 하는 보안 취약점입니다. 이를 통해 쿠키 탈취, 세션 하이재킹, 피싱 공격 등이 발생할 수 있습니다. 본 가이드에서는 XSS의 유형과 방어 기법을 코드 예제와 함께 살펴보겠습니다.
1. XSS 유형과 방어 기법
1.1. 반사형 XSS(Reflected XSS) 방지
반사형 XSS는 사용자 입력이 검증 없이 웹 페이지에서 즉시 실행될 때 발생합니다.
❌ 취약한 코드 예제
const userInput = "<script>alert('XSS')</script>";
document.getElementById("output").innerHTML = userInput; // XSS 취약
✅ 안전한 코드 예제 (출력 시 textContent 사용)
const userInput = "<script>alert('XSS')</script>";
document.getElementById("output").textContent = userInput; // 안전한 출력
✅ CSP(Content Security Policy) 설정
Content-Security-Policy: default-src 'self'; script-src 'self' https://trustedapis.com
1.2. 저장형 XSS(Stored XSS) 방지
저장형 XSS는 악성 스크립트가 데이터베이스 등에 저장된 후, 다른 사용자가 접근할 때 실행되는 유형입니다.
✅ 입력 검증(Input Validation) 적용
const sanitizeHtml = require("sanitize-html");
const safeInput = sanitizeHtml(userInput, { allowedTags: [], allowedAttributes: {} });
✅ ORM 사용 및 이스케이프 처리
const Sequelize = require("sequelize");
const User = sequelize.define("user", { bio: Sequelize.STRING });
User.create({ bio: safeInput });
1.3. DOM 기반 XSS(DOM XSS) 방지
DOM XSS는 클라이언트 측 JavaScript에서 DOM 조작 시 발생합니다.
❌ 취약한 코드 예제 (사용자 입력을 innerHTML에 직접 삽입)
const userInput = location.hash.substring(1);
document.getElementById("content").innerHTML = userInput;
✅ 안전한 코드 예제 (출력 시 textContent 사용)
const userInput = location.hash.substring(1);
document.getElementById("content").textContent = userInput;
✅ Strict CSP 정책 설정
Content-Security-Policy: default-src 'self'; script-src 'none';
2. 안전한 코드 작성 습관
✅ eval() 사용 금지 (동적 코드 실행 방지)
// ❌ 위험한 코드
eval("alert('XSS')");
// ✅ 안전한 대안
const func = new Function("alert('Hello')");
func();
✅ innerHTML 대신 textContent 사용
document.getElementById("output").textContent = userInput;
✅ 동적 import 보안 (사용자 입력을 기반으로 한 모듈 로딩 차단)
// ❌ 취약한 코드
import(userInput).then((module) => module.run());
// ✅ 안전한 코드
import("./safeModule.js").then((module) => module.run());
3. 보안 헤더 설정
✅ Helmet을 사용한 보안 헤더 설정
const helmet = require("helmet");
app.use(helmet());
✅ 주요 보안 헤더 설정
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: no-referrer
4. 추가적인 보안 강화 방법
✅ Strict Mode 사용 (잠재적인 보안 취약점 방지)
"use strict";
✅ Rate Limiting 적용 (DoS 공격 방어)
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 });
app.use(limiter);
✅ 로깅 및 모니터링 설정 (보안 이벤트 감지)
const winston = require("winston");
const logger = winston.createLogger({ level: "info", transports: [ new winston.transports.Console() ] });
logger.info("XSS 방어 로깅 활성화됨");
✅ 의존성 보안 점검
npm audit fix
npx snyk test
✅ CORS 설정 강화
const cors = require("cors");
app.use(cors({ origin: "https://trustedwebsite.com" }));
✅ 환경 변수 보호
require("dotenv").config();
const dbPassword = process.env.DB_PASSWORD;
🎯 결론
JavaScript 기반 웹 애플리케이션에서 XSS 공격을 방지하려면 다음을 실천해야 합니다.
- XSS 예방 기법 적용: textContent, sanitize-html 등의 필터링 사용
- 입력 검증 강화: 사용자 입력을 신뢰하지 말고, CSP를 적극 활용
- 보안 헤더 설정: helmet, X-Content-Type-Options, CORS 설정 적용
- 로깅 및 모니터링: winston 등을 활용하여 공격 시도 탐지
앞으로도 최신 보안 가이드를 지속적으로 업데이트하여 안전한 웹 환경을 만들 수 있도록 돕겠습니다! 🚀🔒
Happy coding and stay secure!
'시큐어코딩 > JavaScript' 카테고리의 다른 글
(시큐어코딩) Node.js 보안 가이드: 웹 애플리케이션에서 발생하는 보안 취약점 방어법 (0) | 2025.03.21 |
---|---|
🚀【시큐어코딩】자바스크립트 시큐어코딩 가이드, 보안취약점 예방방법 (0) | 2025.03.03 |
🚀【시큐어코딩】Django, Flask, Express.js, Node.js에서 SQL 삽입(SQL Injection) 방지 방법 (0) | 2025.03.02 |
🚀【시큐어코딩】웹 보안 필수! JavaScript 개발자를 위한 시큐어코딩 완벽 가이드 (0) | 2025.03.02 |