Web Security

XSS 방지책 (ReactJS)

꼰대코더 2025. 12. 2. 15:05

1. 🛑 dangerouslySetInnerHTML의 위험성

React의 자동 이스케이프 기능을 무력화시키고 사용자 입력에 대한 XSS 공격을 허용하는 코드입니다.

JavaScript
 
// 사용자 입력(악성 스크립트)이라고 가정
const userInput = "<img src='x' onerror='alert(\"XSS Attack!\")' />"; 

function RiskyComponent() {
  return (
    // ❌ 경고: 자동 이스케이프가 비활성화되어 스크립트가 실행됩니다.
    <div dangerouslySetInnerHTML={{ __html: userInput }} />
  );
}

2. ✅ 안전한 대안: DOMPurify를 사용한 HTML 정제

신뢰할 수 없는 HTML을 렌더링해야 할 경우, DOMPurify 라이브러리를 사용하여 **악성 코드를 제거(정제/Sanitize)**한 후 삽입해야 합니다.

Bash
 
# 💡 DOMPurify 설치 (React 프로젝트에서)
npm install dompurify
JavaScript
 
import DOMPurify from 'dompurify';

// 악성 코드가 포함된 사용자 입력이라고 가정
const userInput = '<h1>Hello</h1><img src="x" onerror="alert(\'XSS Attack!\')" /><a href="javascript:alert(\'link xss\')">Click Me</a>';

function SafeComponent() {
  // 1. DOMPurify.sanitize()로 HTML을 정제하여 안전하게 만듭니다.
  const cleanHTML = DOMPurify.sanitize(userInput);

  return (
    // 2. 정제된 HTML을 dangerouslySetInnerHTML에 전달합니다.
    <div dangerouslySetInnerHTML={{ __html: cleanHTML }} />
  );
}

// ✨ 결과: <h1>Hello</h1>만 안전하게 렌더링되고, 악성 코드는 제거됩니다.

3. 🔗 URL 바인딩 공격 방지 (프로토콜 검증)

<a> 태그의 href나 <img> 태그의 src 등에 javascript: 프로토콜이 사용되는 것을 막기 위한 유효성 검사 함수입니다.

JavaScript
 
// 💡 허용할 프로토콜 목록을 정의합니다. (화이트리스트 방식)
const allowedProtocols = ['http:', 'https:', 'mailto:'];

/**
 * URL이 허용된 프로토콜을 사용하는지 검사합니다.
 * @param {string} url 검사할 URL 문자열
 * @returns {boolean} 유효성 여부
 */
function isValidURL(url) {
  try {
    const parsedUrl = new URL(url);
    // 허용된 목록에 protocol이 포함되어 있는지 확인
    return allowedProtocols.includes(parsedUrl.protocol);
  } catch (e) {
    // URL 형식이 아닐 경우 false 반환
    return false; 
  }
}

// 검사할 URL 예시
const safeUrl = "https://www.google.com";
const maliciousUrl = "javascript:alert('URL XSS')";

function SafeLinkComponent() {
  // 검증 후 유효하면 사용하고, 유효하지 않으면 안전한 기본값('#')을 사용합니다.
  const finalSafeUrl = isValidURL(safeUrl) ? safeUrl : '#'; 
  const finalMaliciousUrl = isValidURL(maliciousUrl) ? maliciousUrl : '#';

  return (
    <div>
      <a href={finalSafeUrl}>안전한 외부 링크</a>
      <a href={finalMaliciousUrl}>차단된 악성 시도 (기본값 #로 대체)</a>
    </div>
  );
}

4. 📝 React의 기본 방어: 자동 이스케이핑

React가 기본적으로 XSS를 방어해주는 가장 기본적인 원리입니다. JSX 내부에 데이터를 삽입하면 스크립트가 아닌 텍스트로 처리됩니다.

JavaScript
 
// 사용자 입력 (스크립트 태그 포함)
const safeInput = "<script>alert('React is Safe')</script>"; 

function EscapingComponent() {
  return (
    // ✨ React가 자동으로 이스케이프하여 안전합니다.
    <div>{safeInput}</div>
  );
}

/*
브라우저에 렌더링되는 결과:
<div>&lt;script&gt;alert('React is Safe')&lt;/script&gt;</div>
(화면에 "<script>alert('React is Safe')</script>"라는 텍스트가 그대로 보일 뿐, 스크립트는 실행되지 않습니다.)
*/

 

'Web Security' 카테고리의 다른 글

XSS 방지책 (Express.js)  (0) 2025.12.02
XSS 방지책 (Flask)  (0) 2025.12.02
CSRF (Cross-Site Request Forgery) attack  (0) 2025.12.02
크로스 사이트 스크립팅 (Cross-Site Scripting, XSS)  (0) 2025.11.30
SQL Injection (SQLi)  (0) 2025.10.30