도움말 - 글감 수집하기 (인용)

도움말 - 부분 리뷰 작성하기

리액트(React) 앱의 가장 흔한 XSS 취약점(The Most Common XSS Vulnerability in React.js Applications)

사람들은 isomorphic (또는 universal) 렌더링의 이점 덕분에 리액트에 끌리는 경우가 있다. 즉, 서버 쪽에서 단일 페이지 앱을 렌더링한 후, 그 html을 클라이언트로 보내서 전체 페이지를 다시 렌더링 할 필요없이 클라이언트가 인터렉티브 하게 되도록하는 기능이다.

리덕스(Redux)와 같은 라이브러리에는 이 기능을 제공하는 방법에 대한 문서만 있다. 문서에서 보면 다음과 같은 코드를 볼 수 있다:


XSS 취약점 예제 코드: 서버와 클라이언트의 상태를 공유하는 방법에 대한 리덕스 문서

자, 아마 이 부분을 보면서 왜 보안상 문제가 있는지 확신 할 수 없을 것이다.

걱정 하지 말자, 당신 혼자만 그런 것은 아니다.

나는 최근 Jimmy Jia와 대화를 나눴는데, 내가 작업 했던 앱이 실수로(accidentally) XSS 취약점에 노출된 것을 알게 됐다. 보안 교육을 받은 전문(highly experienced) 소프트웨어 엔지니어 임에도 불구하고 말이다.

뭐가 문제일까?

이 코드의 문제는 store state를 앱에 전달하는 방법에 있다. 위의 스크린 샷을 보면 단순히 JSON.stringify 호출을 수행하고 이것을 스크립트 태그 전역 변수에 할당한다. 이것이 바로 취약점이다.

웹 브라우저가 페이지의 HTML을 파싱하고 <script> 태그를 발견하면 </ script>가 나타날 때까지 계속 읽어 내려간다. 즉, 리덕스 store에 다음과 같은 값이 있고 이것을 클라이언트에서 로드한다면 "XSS 취약점이 있습니다!"라는 경고(alert) 메시지가 나타날 것이다.


{
user: {
username: "NodeSecurity",
bio: "as</script><script>alert('You have an XSS vulnerability!')</script>"
}
}

실제로 마지막 중괄호 부분까지 브라우저가 읽지 않고, 대신에 bio: "as  이후 스크립트(</script>) 태그에서 완료하게 된다.



이 XSS 취약점을 어떻게 방지 할 수 있을까?

Open Web Application Security Project에는 XSS 예방에 대한 다양한 자료가 풍부하게 있다. 이 취약점을 방지하려면 앱에서 몇 가지 조치가 필요하다:

  1. 모든 사용자 입력에는 HTML 엔티티가 이스케이프(escape)되어야 한다. 이 부분은 리액트를 사용할 때 DOM 노드와 텍스트 콘텐츠를 만드는 방법 때문에 대부분의 XSS 취약점을 예방할 수 있다.
  2. 서버에서 상태 값을 클라이언트에 보낼 때 HTML 엔티티를 이스케이프 처리한 후 보내야 한다. 이것은 보통 리액트를 사용하여 이 문자열을 만들지 않기 때문에 문자열이 자동으로 이스케이프되지 않는다.

야후(Yahoo)의 엔지니어들 덕분에 HTML 이스케이프를 Serialize JavaScript 모듈을 통해 쉽게 구현할 수 있다. 어떤 앱에서든 쉽게 사용 할 수 있다.

먼저 모듈을 다음과 같이 설치하자: 


npm install --save serialize-javascript

그런 다음 위에서 사용 했던 코드를 다음과 같이 변경 한다. 특히 __PRELOADED_STATE__에 값을 할당 할 때 JSON.stringify 대신 serialize를 사용한 것을 확인하자.


야후의 Serialize Javascript 모듈을 사용하여 XSS 취약점을 제거하는 snippet

클라이언트 쪽에서 데이터를 받는 것은 문자열의 HTML 엔터티가 이스케이프 처리 된 것만 제외하면 이전과 동일하다 (</ script> 대신에 \\ u003C \\ u002Fscript \\ u003E  처럼 보일 것이다).

주의 사항 : 최신 기술이나 Facebook에서 사용하는 기술로 앱을 만들때 뿐만 아니라 Rails, Django, PHP 또는 이전 스택으로 앱을 만드는 경우에도 모든 일반적인(standard) 보안을 처리해야한다.




이 게시물은 처음 이러한 취약점을 내가 알려준 Jimmy Jia와의 대화를 기반으로 작성했다. 나는 원래 브라우저가 이와는 다르게 작동하고 스크립트 태그의 내용을 알고 있다고 생각했다.



이 글은 Em Smith의 The Most Common XSS Vulnerability in React.js Applications을 번역한 글 입니다. 전문 번역가가 아니라서 오역이 있을 수 있습니다. 지적해주시면 수정하도록 하겠습니다. 원문은 아래에서 확인 할 수 있습니다.


리뷰