14장 웹사이트 보안을 위한 리액트와 웹페이지 보안이슈

강석우's avatar
Apr 26, 2024
14장 웹사이트 보안을 위한 리액트와 웹페이지 보안이슈

14.1 리액트에서 발생하는 크로스 사이트 스크립팅

크로스 사이트 스크립팅이란 웹 애플리케이션에서 가장 많이 보이는 취약점 중 하나로 웹사이트 개발자가 아닌 제3자가 웹사이트에 악성 스크립트를 삽입해 실행할 수 있는 취약점을 의미한다. 예를 들어 3자가 게시판에 아래와 같은 글을 작성한다고 생각해보자

<p> 사용자가 글을 작성했습니다. </p>
<script>
  alert('XSS')
</script>

이 글을 방문했을 때 별도의 조치가 없다면 script가 실행되어 window.alert 도 함께 실행 될 것이다.

14.1.1 dangerouslySetInnerHTML prop

dangerouslySetInnerHTML은 이름대로 특정 브라우저 DOM의 innerHTML을 특정한 내용으로 교체할 수 있는 방법이다.

constt html = `<span><svg/onload=alert(origin)></span>`

<div dangerouslySetInnerHTML={{__html:html}}/>

위 코드를 작성하면 origin 이 alert로 나타나게 된다.

14.1.2 useRef를 활용한 직접 삽입

비슷한 방법으로 DOM에 직접 내용을 삽입할 수 있는 방법으로 useRef가 있다.

divRef.current.innerHTML = html

<div ref={divRef}/>

이 또한 dangerouslySetInnerHTML와 같이 동일한 문제가 발생한다.

14.1.3 리액트에서 XSS 문제를 피하는 방법

가장 확실한 방법은 제3자가 삽입할 수 있는 HTML을 안전한 HTML 코드로 한 번 치환하는 것이다. 이러한 과정을 새니타이즈 또는 이스케이프 라고 하는데, 직접 구현하는 방법도 있지만 가장 확실한 방법은 npm 라이브러리를 사용하는 것이다.

  • DOMpurity

  • sanitize-html

  • js-xss

또한 이러한 과정은 서버에서 수행하는 것이 좋은데 POST 요청을 curl 등으로 직접 요청하는 경우에는 스크립트에서 실행하는 이스케이프 과정을 생략하고 저장될 가능성이 있기 때문에 서버에서 처리하는 것이 안전하다.

14.2 getServerSideProps와 서버 컴포넌트를 주의하자

서버에는 일반 사용자에게 노출되면 안 되는 정보들이 담겨 있기 때문에 브라우저에 정보를 내려줄 때 조심해야 한다.

14.3 <a> 태그의 값에 적절한 제한을 둬야한다.

<a> 태그안에 javascript: 를 작성하고 뒤에 주소를 붙이면 작동하지 않는 것을 볼 수 있는데 이는 코드가 작동하지 않는 것이 아니라 javascript: 까지만 코드가 작동되는 것이다. 따라서 뒤에 javascript가 온다면 코드는 실행되게 된다. 따라서 href로 들어갈 값을 제한해야 한다.

14.4 HTTP 보안 헤더 설정하기

http 보안 헤더란 렌더링하는 내용과 관련된 보안 취약점을 미연에 방지하기 위해 브라우저와 함께 작동하는 헤더를 의미한다.

14.4.1 Strict-Transport-Security

응답 헤더는 모든 사이트가 HTTPS를 통해 접근해야하며 HTTP로 접근하는 경우 모든 시도를 HTTPS로 변경되게 한다.

14.4.2 X-XSS-Protection

현재 사파리와 구형 브라우저에서만 제공되는 기능이며 XSS 취약점이 발견되면 페이지 로딩을 중단하는 헤더다. 하지만 이 헤더를 너무 전적으로 믿어서는 안되며 반드시 페이지 내부에 XSS에 대한 처리를 해줘야 한다.

14.4.3 X-Frame-Options

페이지를 frame, iframe, embed, object 내부에서 렌더링을 허용할지를 나타낼 수 있다.
위의 옵션은 외부에서 자신을 페이지를 마치 다른 페이지 인 것 처럼 도용되는 것을 막아주는 헤더다.

14.4.4 Permissions-Policy

웹사이트에서 사용할 수 있는 기능과 사용할 수 없는 기능을 명시적으로 선언하는 헤더다.
geo-location 또는 camera 같은 기능을 명시적으로 끄거나 일부 허용하거나 해줄 수 있다.

14.4.5 X-Content-Type-Options

헤더에서 제공하는 MIME 유형이 브라우저에 의해 임의로 변경되지 않게 하는 헤더다.
MIME 는 Content-type 의 값으로 보면 되는데 단순히 말해 jpg, css,json등의 유형을 말한다.

14.4.6 Referrer-Policy

HTTP 요청에는 Referer라는 헤더가 존재하는데 이는 현재 요청을 보낸 페이지의 주소가 나타난다. 사용자가 어디서 와서 방문중인지 인식할 수 있는 헤더지만 사용자 입장에서 원치않는 정보가 노출될 수 있다.
이를 설정해서 사이트 이용자의 개인정보를 보호하도록 하자.

14.4.7 Content-Security-Policy

XSS공격이나 데이터 삽입 공격과 같은 다양한 보안 위협을 막기 위해 설계됐다.
지시문이 매우 많기 때문에 W3에 모든 지시문이 나와있으므로 링크로 대체하겠다.

14.4.8 보안 헤더 설정하기

Next.js에서는 next.config.js 파일에서 http 경로별로 보안헤더를 적용할 수 있다.

14.4.9 보안 헤더 확인하기

현재 서비스 하고 있는 사이트의 보안헤더를 확인하고 싶다면 https://securityheaders.com/ 를방문해서 보자. 웹사이트의 주소를 입력하면 바로 보안 헤더 상황을 알 수 있다.

14.5 취약점이 있는 패키지의 사용을 피하자

개발자 스스로가 프로젝트의 pakage.json에 어떤 패키지가 있는지는 파악할 수 있지만 pakage-lock.json을 파악하는 것은 불가능하다.
따라서 깃허브의 Dependabot이 발견한 취약점은 필요하다면 빠르게 업데이트해 조치해야 한다.

14.6 OWASP Top10

오픈소스 웹 애플리케이션 보안 프로젝트를 의미합니다.
정보 노출, 악성 스크립트, 보안 취약점 등을 연구하며 주기적으로 10대 웹 애플리케이션 취약점을 공개하는데 이를 OWASP Top 10 이라고 한다.

14.7 정리

버그가 없는 소프트웨어는 없다. 현재 개발하고 있는 서비스, 운영하고 있는 서비스에 관계없이 항상 보안 이슈에 귀 기울이며 만반의 준비를 갖춰야만 사용자에게 신뢰 받는 서비스를 만들 수 있을 것이다.

Share article

석우의 개발블로그