본문 바로가기

개념정리

9/24[TIL]Browser Security

어제 배웠던 부분의 일부인 브라우저는 보안에 대한 위협을 받는다. 브라우저가 위협을 받는 근본적인 이유는 javascript를 구동하기 때문이라고 한다. 브라우저가 javascript로 할 수 있는 일들이(아래 참고) 많은 걸 보니 사용하지 않을 수가 없을 것 같다.

 

1. ajax call을 해서 api를 호출 할 수 있음

2. 동적으로 DOM을 제어 할 수 있음

3. 인증정보를 브라우저에 저장할 수 있음

4. 인증정보를 불러올 수 있음

 

웹 보안에는 1. 서버보안 / 2.DB보안 / 3. 클라이언트 보안(브라우저 보안) 있다.

 

XSS CSRF는 브라우저를 공격할 수 있는 수단 중 큰 두 가지로 생각할 수 있다.

 

XSS

쉽게 말해 클라이언트가 서버를 신뢰하기 때문에 발생하는 이슈로 정상적인 웹앱에 악성 스크립트를 주입하는 공격(해커가 서버에 코드를 심어 놓고 이용자가 그것을 내려받아 피해 보는 것)이며 input 태그 등 클라이언트에 대한 입력을 통해 발생하는 경우가 많으므로 스크립트를 일반 문자열로 변환하는 필터 장치를 마련하여 예방할 수 있다.

우리가 보통 서버에 메세지 요청 - > 메세지 응답 - > 응답받은 메세지 돔 반영하는 방식으로 진행이 되는데

하지만 이런 메세지에 태그 장난을 한다면 스크립트 인젝션 공격 같은

이는 보안이 약한 웹 애플리케이션에 대한 웹 기반 공격이며 희생자는 어플케이션의 아닌 결국 user가 된다.

해로운 콘텐츠는 js를 활용해 유해한 스크립트 전달된다.

브라우저에서 기본적인 XSS 공격은 업데이트가 계속 진행돼 오면서 현재 웬만한 것은 막혀있다고 볼 수 있다.

 

CSRF

해커가 피싱 페이지에 접속한 피해자의 인증정보를 가로채 악용하는 공격이라고 보면 되며 서버가 클라이언트를 신뢰해서 발생하는 이슈라고 생각하면 될 것이다. 보통 서버는 클라이언트는 안전하다 라는 전제를 바탕으로 진행하게 되고 서버는 이러한 클라이언트의 인증정보를 가지고 오면 믿을 수밖에 없게 된다. 

2008년도에 있었던 옥션 해킹 공격 사례를 보면 사용자는 인증정보를 가진 채로 해커가 심어놓은 링크를 누르면 해커는 인증정보를 가로채서 서버에 요청을 보내버리는 경우이다.

이와 비슷하게 보면 사용자가 뱅킹에 로그인을 하게 되면 은행은 사용자에게 토큰을 주게 된다. 이 토큰으로 사용자는 뱅킹을 이체/입금 등을 진행할 수 있다. 해커가 링크 / 메일 등으로 심어 놓은 것을 유저가 클릭하게 되면 해커가 토큰 정보를 빼내 가지고 뱅킹에 접근할 수 있다.

하지만 업데이트가 계속 진행되면서 세임 사이트(samesite) 쿠키로 인해 CSRF는 없다는 게 중론이라고 한다.

 

CORS

이전에는 서버에서 내려 받은 클라이언트와 통신을 진행했으나 기술이 발달해오면서 여러 곳에 있는 리소스를 활용할 필요가 생기기 시작했다. 이전의 same origin 요청이 아닌 cross origin 을 요청 해야 하는 것이다.

이를 바탕으로 나온 CORS(Cross Origin Resource Sharing)에서 리소스 (서버자원)을 요청하여 사용한다.

브라우저에서 크로스 도메인 요청은 기본적으로는 제한 되어 있다. 개발자들은 이에 웹 애플리케이션 고도화를 통해 개선을 요청했고 이를 통해 서버가 허락한 범위 내에서 cross origin 요청을 허용하게 된다.

 

다른 오리진 간의 리소스 공유를 뜻하며 필요에 따라 공유해도 되는 자원이 있는가 하면 아닌 것도 존재하는데 그 단계를 나눈 것이라고 보면 될 것 같다. 이는 브라우저가 자발적으로 브라우저를 사용하는 유저들을 보호하기 위한 정책이라고 볼 수 있다.

CORS가 동작하는 방식은 한 가지가 아니라 세 가지의 시나리오에 따라 변경되기 때문에 우리의 요청이 어떤 시나리오에 해당되는지 잘 파악한다면 CORS 정책 위반으로 인한 에러를 고치는 것이 한결 쉬울 것이다.

 

 

[세 가지의 시나리오]

 

simple requests

뒤에 설명할 prefilghted requests의 일부분인 예비 요청을 보내지 않고 바로 서버에게 본 요청부터 한 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식이다. 즉, 프리플라이트와 단순 요청 시나리오는 전반적인 로직 자체는 같지만 예비 요청의 존재 유무만 다르고 보면 된다.

하지만 아무 때나 단순 요청을 사용할 수 있는 것은 아니고, 특정 조건을 만족하는 경우에만 예비 요청을 생략할 수 있다. 게다가 이 조건이 조금 까다롭기 때문에 일반적인 방법으로 웹 애플리케이션 아키텍처를 설계하게 되면 거의 충족시키기 어려운 조건들이다.

 

Prefilghted requests

일반적으로 우리가 웹 애플리케이션을 개발할 때 가장 마주치는 시나리오라고 볼 수 있는데 이 시나리오에 해당하는 상황일 때 브라우저는 요청을 한 번에 보내지 않고 예비 요청과 본 요청으로 나누어서 서버로 전송한다.

이때 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 Preflight라고 부르는 것이며, 이 예비 요청에는 HTTP 메소드 중 OPTIONS 메소드가 사용된다. 예비 요청의 역할은 본 요청을 보내기 전에 브라우저 스스로 이 요청을 보내는 것이 안전한지 확인하는 것이다.

 

Requests with credentials

인증된 요청을 사용하는 방법이다. 이 시나리오는 CORS의 기본적인 방식이라기보다는 다른 출처 간 통신에서 좀 더 보안을 강화하고 싶을 때 사용하는 방법이다.

기본적으로 브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest 객체나 fetch API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 함부로 요청에 담지 않는다. 이때 요청에 인증과 관련된 정보를 담을 수 있게 해주는 옵션이 바로 credentials 옵션이다.

'개념정리' 카테고리의 다른 글

9/29[TIL]Refactor Express  (0) 2020.09.29
9/25[TIL]Node.js / Package.json / HTTP  (0) 2020.09.25
9/23[TIL]Web Architecture  (0) 2020.09.23
9/22[TIL]fetch API  (0) 2020.09.23
9/21[TIL]Async & Await  (0) 2020.09.21