React React Element에 $$typeof가 필요한 이유

심재철
3 min readJul 20, 2020

--

{
type: 'div',
props: {
bgcolor: '#ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$typeof: Symbol.for('react.element'),
}

react의 element는 이렇게 plain object 형태로 되어 있다.

이중에서 $$typeof는 왜 필요한건지 궁금해서 찾아보았다.

Symbol.for

$$typeof의 value로 사용된 공유 심볼에 대한 이해가 먼저 필요하다. (링크)

간략하게 얘기하면 react.element라는 string key를 가진 유니크한 글로벌 심볼을 리액트 엘리먼트의 property중 하나로 사용한것이다.

React.createElement(type, props, children)

React의 엘리먼트를 생성해주는 위 API를 사용하면 내부적으로 $$typeof를 추가해준다.

결론부터 얘기하면 이 필드는 XSS공격을 막기 위해 사용된다. XSS공격에 대해서는 잘 설명되어 있는 블로그가 많으니 알고 있다고 가정하겠다.

만약, 서버에서 아래와 같은 코드를 클라이언트로 내려줬다고 해보자.

let expectedTextButGotJSON = {
type: 'div',
props: {
dangerouslySetInnerHTML: {
__html: "악의적으로 삽입된 스크립트";
},
},
// ...
};
let message = { text: expectedTextButGotJSON };

// React 0.13에서 이는 위험할 수 있다.
<p>
{message.text}
</p>

expectedTextButGotJSON이라는 리액트 엘리먼트를 그대로 렌더링하게 되면 개인정보 탈취 또는 세션 하이재킹 목적으로 작성된 스크립트가 실행될 수 있는 위험이 존재한다.

서버에서 이런 값이 내려오더라도 사용자를 지킬 수 있도록 라이브러리에서 지원할 필요가 생겼다.

{
type: 'marquee',
props: {
bgcolor: '#ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$typeof: Symbol.for('react.element'),
}

그래서 $$typeof라는 필드가 생긴것이다. 심볼은 자바스크립트 객체 Object classinstance에만 넣을 수 있다. JSON에는 심볼을 넣을 수 없다. 그래서 만약에 서버에서 악의적인 스크립트가 포함된 JSON을 내려준다고 해도, 그 JSON에는 심볼이 없을것이므로 리액트가 렌더링을 거부할 수 있다.

리액트는 $$typeof에 심볼이 들어있을때만 엘리먼트를 화면에 렌더링해준다.

서버에서 JSON으로 엘리먼트를 내려도 리액트는 렌더링을 하지 않는다. (XSS공격을 막기 위해)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response