김용현
Study

정리하기 파일

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

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

  • 웹사이트 개발자가 아닌 제3자가 웹사이트에 악성 스크립트를 삽입해 실행할 수 있는 취약점을 의미.

14.1.1 dangerousySetInnerHTML prop

  • 특정 브라우저 DOM의 innerHTML을 특정한 내용으로 교체할 수 있는 방법.

14.1.2 useRef를 활용한 직접 삽입

  • DOM에 직접 내용을 삽입할 수 있는 방법으로 useRef가 있다. useRef를 활용하여 직접 DOM에 접근할 수 있으므로 이 DOM에 앞서와 비슷한 방식으로 innerHTML에 보안 취약점이 있는 스크립트를 삽입하면 dangerousySetInnerHTML prop과 동일한 문제가 발생한다.

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

  • 가장 확실한 방법은 제3자가 삽입할 수 있는 HTML을 안전한 HTML 코드로 한 번 치환하는 것.
  • 이러한 과정을 새니타이즈(sanitize) 또는 이스케이프(escape)라고 하는데, 새티나이즈를 직접 구현해 사용하는 등 다양한 방법이 있지만 가장 확실한 방법은 npm에 있는 라이브러리를 사용하는 것이다.
    • DOMpurity
    • sanitize-html
    • js-xss

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

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

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

  • <a> 태그는 반드시 페이지 이동이 있을 때만 사용하는 것이 좋다. 페이지 이동이 없이 어떠한 핸들러만 작동시키고 싶다면 a 보다는 button 태그를 사용하는 것이 좋다.

14.4 HTTP 보안 헤더 설정하기

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

14.4.1 Strict-Transport-Security

  • Strict-Transport-Security 응답 헤더는 모든 사이트가 HTTPS를 통해 접근해야 하며, 만약 HTTP로 접근하는 경우 이러한 모든 시도는 HTTPS로 변경되게 한다.

14.4.2 X-XSS-Protection

  • X-XSS-Protection은 비표준 기술로, 현재 사파리와 구형 브라우저에서만 제공되는 기능이다.
  • 이 헤더는 페이지에서 XSS 취약점이 발견되면 페이지 로딩을 중단하는 헤더다.

14.4.3 X-Frame-Options

  • X-Frame-Options는 페이지를 frame, iframe, embed, object 내부에서 렌더링을 허용할지를 나타낼 수 있다.
  • X-Frame-Options는 자신의 페이지를 위와 같은 방식으로 삽입되는 것을 막아주는 헤더이다.
  • X-Frame-Options
    • DENY : 만약 위와 같은 프레임 관련 코드가 있다면 무조건 막는다.
    • SAMEORIGIN : 같은 origin에 대해서만 프레임을 허용한다.

14.4.4 Permissions-Policy

  • Permissions-Policy는 웹사이트에서 사용할 수 있는 기능과 사용할 수 없는 기능을 명시적으로 선언하는 헤더이다.

14.4.5 X-Content-Type-Options

  • 이 헤더를 이해하려면 먼저 MIME이 무엇인지 알아야 한다.
  • MIME
    • Multipurpose Internet Mail Extensions의 약자로 Content-type의 값으로 사용된다.
  • 여기서 X-Content-Type-Options란 Content-type 헤더에서 재공하는 MIME 유형이 브라우저에 의해 임의로 변경되지 않게 하는 헤더다.

14.4.6 Referrer-Policy

  • HTTP 요청에는 Referer라는 헤더가 존재하는데, 이 헤더에는 현재 요청을 보낸 페이지의 주소가 나타난다.
  • Referrer-Policy 헤더는 이 Referer 헤더에서 사용할 수 있는 데이터를 나타낸다.
  • Referer에 대해 이야기할 때는 출처(origin)을 빼놓을 수 없다.
  • https://yceffort.kr이라는 (opens in a new tab) 주소의 출처를 구성하고 있는 요소들은 다음과 같다.
    • scheme : HTTPS 프로토콜을 의미한다.
    • hostname : yceffort.kr이라는 호스트명을 의미한다.
    • port : 443 포트를 의미한다.

14.4.7 Content-Security-Policy

  • 콘텐츠 보안 정책(Content-Security-Policy, 이하 CSP) 은 XSS 공격이나 데이터 삽입 공격과 같은 다양한 보안 위협을 막기 위해 설계됐다.
  • -src
    • font-src, img-src, script-src 등 다양한 src를 제어할 수 있는 지시문이다.
  • form-action
    • form-action은 폼 양식으로 제출할 수 있는 URL을 제한할 수 있다.

14.4.8 보안 헤더 설정하기

  • Next.js

    • next.config.js에서 다음과 같이 추가할 수 있다.
    const securityHeaders = [
      {
        key: "key",
        value: "value",
      },
    ];
     
    module.exports = {
      async headers() {
        return [
          {
            // 모든 주소에 설정한다.
            source: "/:path*",
            headers: securityHeaders,
          },
        ];
      },
    };
  • NGINX

    • 정적인 파일을 제공하는 NGINX의 경우 다음과 같이 경로별로 add_header 지시자를 사용해 원하는 응답 헤더를 추가할 수 있다.
    location / {
    	#...
    	add_header X-XSS-Protection "1; mode=block";
    	add_header Content-Security-Policy "default-src 'self'; script-src 'self'; child-src e...m; style-src 'self' example.com; font-src 'self';";
    	#...
    }

14.4.9 보안 헤더 확인하기

  • 현재 서비스 중인 웹사이트의 보안 헤더를 확인할 수 있는 가장 빠른 방법은 보안 헤더의 현황을 알려주는 https://securityheaders.com/ 을 방문하는 것이다.

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

  • https://security.snyk.io/ 를 방문해 사용하는 패키지 이름으로 검색해 보면 현재 라이브러리의 취약점을 한눈에 파악할 수 있으므로 패키지 보안 이슈를 추적하는 데 많은 도움이 된다.

14.6 OWASP Top 10

  • OWASP은 Open Worldwide (Web) Application Security Project라는 오픈소스 웹 애플리케이션 보안 프로젝트를 의미한다.
  • 주로 웹에서 발생할 수 있는 정보 노출, 악성 스크립트, 보안 취약점 등을 연구하며 주기적으로 10대 웹 애플리케이션 취약점을 공개하는데 이를 OWASP Top 10이라고 한다.
  • 2021년 OWASP Top 10
    • A01: 2021-Broken Access Control
    • A02: 2021-Cryptographic Failures
    • A03: 2021-Injection
    • A04: 2021-Insecure Design
    • A05: 2021-Security Misconfiguration
    • A06: 2021-Vulnerable and Outdated Components
    • A07: 2021-Identification and Authentication Failures
    • A08: 2021-Software and Data Integrity Failures
    • A09: 2021-Security Logging and Monitoring Failures
    • A10: 2021-Server-Side Request Forgery

14.7 정리

  • 버그가 없는 완벽한 소프트웨어는 없다. 모든 소프트웨어에는 버그가 있으며, 이 버그가 때로는 보안 취약점으로 이어진다.
  • 보안 이슈는 단순히 개발만 잘해서 해결되는 문제가 아니다.
  • 소프트웨어를 설계하고, 코드를 작성하고, 서비스를 제공하며 유지보수하는 단계에 이르기까지 웹 서비스의 생명주기 전체에 걸쳐서 발생할 수 있으며, 때로는 개발자 본인이 작성한 코드밖에서도 일어날 수 있다.

15장. 마치며

15.1 리액트 프로젝트를 시작할 때 고려해야 할 사항

15.1.1 유지보수 중인 서비스라면 리액트 버전을 최소 16.8.6에서 최대 17.0.2로 올려두자

  • 16.8에서 훅이 소개됐고, 훅 덕분에 함수형 컴포넌트의 개념이 정립됐다.
  • 따라서 향후 원활한 지원을 위해 버전을 16.8.6 이상으로 맞추는 것이 좋다.
  • 또한 17 버전은 리액트 팀에서 공언한 대로 새로운 기능 출시 및 호환성이 깨지는 변경 사항을 최소한으로 맞춘 업데이트이므로 가능하다면 17버전으로 가는 것도 좋다.

기존에 클래스형으로 작성한 컴포넌트를 함수형으로 리팩터링할 필요가 있을까?

  • ‘굳이 그럴 필요는 없다’
  • 리액트 팀에서는 클래스형 컴포넌트를 사라지게 할 계획은 없다고 밝혔다. 그러므로 굳이 클래스형 컴포넌트를 함수형으로 서둘러 전환하지 않아도 된다.

15.1.2 인터넷 익스플로러 11 지원을 목표한다면 각별히 더 주의를 기한다.

  • 일반적인 경우라면 크게 상관없지만 인터넷 익스플로러 11 등 레거시 브라우저를 지원해야 하는 경우에는 npm install 에 앞서서 반드시 주의를 기울여야 한다.
  • 다음은 인터넷 익스플로러 11 을 지원하지 않는 대표적인 라이브러리다.
    • 리액트 : 리액트는 18 버전부터 인터넷 익스플로러 11을 지원하지 않기로 했다.
    • Next.js : Next.js는 13 버전부터 공식적으로 인터넷 익스플로러 11을 지원하지 않기로 했다.
    • query-string : 주소의 쿼리 문자열을 다루는 대표적인 라이브러리인 query-string도 6.x 버전부터 인터넷 익스플로러 11을 지원하지 않는다.

15.1.3 서버사이드 렌더링 애플리케이션을 우선적으로 고려한다.

  • 관리자와 같이 제한적인 사용자에게 빠르게 웹페이지를 제공해야 하는 경우, 혹은 이벤트 페이지와 같이 콘텐츠와 인터랙션이 매우 제한적인 소규모 웹페이지를 만드는 경우, 혹은 서버를 준비해야 할 상황이 여의치 않은 경우에만 싱글 페이지 애플리케이션을 만들 것을 추천한다.
  • 많은 사용자를 감당해야 하고, 혹은 그럴 계획이 있다면, 그리고 서버를 준비할 수 있는 충분한 여유가 된다면 시작부터 서버 사이드 렌더링을 고려하는 것이 좋다.

15.1.4 상태 관리 라이브러리는 꼭 필요할 때만 사용한다.

  • 관리해야 할 상태가 적은, 비교적 정적인 애플리케이션이라면 상태 관리 라이브러리가 굳이 필요하지 않을 수도 있다. 오히려 상태가 적은 애플리케이션에 상태 관리 라이브러리를 추가하는 것은 되려 부자연스러운 프로젝트 구조를 야기할 수 있으며, 쓸데없이 번들링 크기만 키우는 꼴이 될 수 있다.

15.1.5 리액트 의존성 라이브러리 설치를 조심한다.

  • 어떠한 기능 구현을 위해 라이브러리를 설치할 때, 특히 리액트에 의존적인 라이브러리를 설치하려고 하는 경우가 있을 것이다. 이런 라이브러리의 대부분은 react-** 같은 이름을 가지고 있으며, 대부분 다음과 같이 리액트에 대한 의존성을 가지고 있다.
{
	"peerDependencies" : {
		"react" : "^16.8.6 || ^17.0.0",
		"react-dom" : "^16.8.6 || ^17.0.0",
	}
}
  • 이때 반드시 이 peerDependencies가 설치하고자 하는 프로젝트의 리액트 버전과 맞는지 확인해야 한다.

15.2 언젠가 사라질 수도 있는 리액트

15.2.1 리액트는 그래서 정말 완벽한 라이브러리인가?

  • 클래스형 컴포넌트에서 함수형 컴포넌트로 넘어오면서 느껴지는 혼란
  • 너무 방대한 자유가 주는 혼란

15.2.2 오픈소스 생태계의 명과 암

  • 페이스북 라이선스 이슈
  • 오픈소스는 무료로 계속 제공될 수 있는가? colors.js, faker.js 그리고 바벨

15.2.3 제이쿼리, AngularJS, 리액트, 그리고 다음은 무엇인가?

15.2.4 웹 개발자로서 가져야 할 유연한 자세

  • 무슨 프레임워크나 라이브러리를 사용하든 한 가지 변하지 않는 사실은 HTML과 CSS, 자바스크립트가 웹페이지를 구성하는 기초 기술이라는 사실이다.