그럼에도 불구하고

👨‍💻

[React] dangerouslySetInnerHTML이란? 본문

React/React basics

[React] dangerouslySetInnerHTML이란?

zenghyun 2023. 6. 28. 00:09

dangerouslySetInnerHTML에 대해 알아보겠습니다.

 

 

 

다음과 같이 msg에 "<i>Hello World</i>"를 넣고 react를 실행시켰습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from 'react'
import './App.css'
 
function App() {
  const msg = "<i>Hello World</i>";
 
  return (
    <>
    <h1>
     {msg}
    </h1>
    </>
  )
}
 
export default App;
 
 
 
 
 
cs

 

 

출력되는 화면 

 

실행한 서버에서 웹 브라우저의 개발자 도구를 열고 콘솔 화면에서 다음과 같이 스크립트를 실행해 보겠습니다. 

 

 

브라우저 화면에서 <i></i> 태그의 문자열이 그대로 출력됐습니다.

 

그 이유는 웹 애플리케이션에서 흔히 발생하는 XSS(Corss Site Scripting) 같은 공격에 대비하기 위해서 <i>가 &lt;i&gt;로 HTML 인코딩 됐기 때문입니다.

 

만일 HTML 마크업 형태의 값을 보간하려고 한다면 두 가지 방법을 사용할 수 있습니다. 

 

첫 번째 방법은 dangerouslySetInnerHTML 특성을 사용하는 것입니다. 

 

[ dangerouslySetInnerHTML ]

 dangerouslySetInnerHTML은 React 라이브러리에서 사용되는 속성입니다. 이 속성은 문자열 형태로 HTML 마크업을 동적으로 생성하여 컴포넌트의 내부에 삽입할 수 있게 해 줍니다.

React는 일반적으로 JSX 문법을 사용하여 컴포넌트의 렌더링을 처리합니다. JSX는 JavaScript와 HTML을 조합한 확장 문법이며, 컴포넌트의 구조와 동작을 선언적으로 표현할 수 있게 해 줍니다. 그러나 때로는 동적으로 생성된 HTML 마크업을 렌더링해야 할 때가 있습니다. 이때 dangerouslySetInnerHTML 속성을 사용할 수 있습니다.

dangerouslySetInnerHTML은 객체 형태의 속성으로, 해당 객체는 __html이라는 특별한 키를 가지고 있습니다. __html의 값으로 원하는 HTML 문자열을 전달합니다. React는 이 문자열을 그대로 렌더링 하여 컴포넌트의 내부에 삽입합니다. 이 속성은 이름에서 알 수 있듯이 "위험하게 설정된" HTML이기 때문에 신뢰할 수 있는 소스에서만 사용해야 합니다. 

 

사용자 입력을 포함한 외부 소스를 dangerouslySetInnerHTML로 직접 렌더링 하는 경우, XSS(Cross-Site Scripting) 공격과 같은 보안 취약점이 발생할 수 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from 'react'
import './App.css'
 
function App() {
  const msg = "<i>Hello World</i>";
 
  return (
    <>
    <h1>
     <span dangerouslySetInnerHTML={{__html: msg}} />
    </h1>
    </>
  )
}
 
export default App;
 
cs

 

 

 

두 번째 방법은 JSX가 XSS 공격에 안전하기 때문에 HTML 문자열 대신 JSX를 사용하는 것입니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from "react";
import "./App.css";
 
function App() {
  const msg = <i>Hello World</i>;
 
  return (
    <>
      <h1>{msg}</h1>
    </>
  );
}
 
export default App;
 
cs

 

Comments