티스토리 뷰

{
  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공격을 막기 위해)

 

 

 

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함