token, XSS, CSRF

내승현·2022년 4월 24일
0

❗️token

JSON Web Token, 줄여서 jwt는 서버에서 사용자를 식별할 수 있는 정보를 담아 클라이언트에 내려줄 때 쓰는 토큰이다.
서버가 한 번 인증한 사용자에게 카드키를 준 거라고 생각하면 쉽다.
토큰을 받은 클라이언트는 다음에 따로 인증을 하지 않아도 토큰을 이용해 로그인한 상태로 웹에 접근할 수 있다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
참고: https://jwt.io/

빨간색 부분은 헤더로 어떤 알고리즘이 적용됐는지 등의 정보가 담겨 있다. 넘어가도 된다.
핑크색 부분은 payload로 실제적인 객체 데이터가 담겨 있다.

{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
}
// 핑크색

토큰을 받고 나서 클라이언트가 서버에 무엇인가 요청을 할 때
인증이 필요한 요청이라면 토큰을 보내고
서버에서는 사용자를 확인할 수 있다.
또한 토큰이 암호화 되어 있으니 사용자의 생일과 같은 정보를 넣어도 좋고
토큰에 사용자에 관한 충분한 정보를 넣었다면
서버에 별도의 요청을 하지 않아도 된다.
클라이언트에서 분홍색 부분을 디코드 하려면 jwt-decode 모듈을 쓰자.

하늘색 부분은 인증과 관련된다.
만약 누군가가 클라이언트에 저장된 토큰을 가로채 핑크색 사용자 정보를 조작한 뒤 서버에 접근한다 해도
전체적인 값이 달라지면 서버에 저장된 시크릿 키에 의해 하늘색 부분의 토큰도 달라지기 때문에 막힌다.
오직 서버에서만 유효한 토큰을 제공할 수 있다.

1. Token 생성하기

const jwt = require('jsonwebtoken');
const token = jwt.sign({ _id: 1, name: 'socratone' }, 'secretKey');
// 생성된 token을 클라이언트로 보내준다.
res.header('x-auth-token', token).send({/* ... */});

2. Token을 이용해 인증하기

미들웨어로 만들어서 쓴다.

const jwt = require('jsonwebtoken');
function auth(req, res, next) {
	const token = req.header('x-auth-token'); // 클라이언트에서 헤더로 보낸 토큰을 받는다.
	if (!token) return res.status(401).send('토큰이 없습니다.');
	try {
	const decoded = jwt.verify(token, 'secretKey');
	req.user = decoded; // 디코딩이 잘 되면 user 객체에 담아 다음으로 넘겨준다.
		next();
    } catch (ex) {
		res.status(400).send('유효하지 않은 토큰입니다.');
    }
}
module.exports = auth;

XSS : Cross Site Scripting

  • 사이트를 교차해서 스크립트를 발생시킴.

  • 게시판을 포함한 웹에서 자바스크립트같은 스크립트 언어를 삽입해 개발자가 의도하지 않은 기능을 작동시키는것.

  • 클라이언트측을 대상으로 한 공격


XSS의 등장 배경에대해 알아보자면 1995년 '넷스케이프' 사에 의해 자바스크립트가 도입된다.
과거에는 넷스케이프의 점유율이 80퍼센트 이상이었을때가 있었고, 그렇기 때문에 그당시 주류였던 넷스케이프에서
최초로 자바스크립트를 도입하게 되므로 다른 웹서비스들도 자바스크립트를 채택하게되었다.
2000년에 이르러 '마이스페이스'에서 XSS 공격이 최초로 발견되었다. '마이스페이스'는 미국판 싸이월드.. 정도
2005년에는 악성코드 형태로 발견되었고, 현재까지 다양한 변종들이 등장하게 된다.
일례로 '리그 오브 레전드(LOL)' 에서도 자바스크립트를 이용한 공격이 등장하였다.
웹에서 빠질수 없는 언어이기때문에, 없어지지않는 취약점 중에 하나라고 볼 수 있다.

이 문제에 대한 방어법중 하나는 dompurify 이다.

yarn add dompurify
yarn add -D @types/dompurify

코드에 적용시켜 안정성을 확보할 시간입니다!

하지만 지금은 발생하지 않지만 이렇게 작성해을 주면 Hydration Issue가 생긴다.

여기서 하이드레이션은 렌더링 결과물의 컴포넌트를 확인하고 각 컴포넌트의 이벤트들을 실제 DOM에 걸어주는데, 이 경우 SSR 시 렌더링되는 컴포넌트와 CSR 시 렌더링되는 컴포넌트가 있기에 DOM 에서 읽어주는 순서가 꼬이게 되어버린다. 이를 방지하기위해 SSR / CSR 렌더링 컴포넌트를 동일하기 주기 위해 빈값을 넣어주어 해결해 준다.

CSRF

CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격이다.

CSRF를 통해 해커는 희생자의 권한을 도용하여 중요 기능을 실행하는 것이 가능하다. 예를들어, 페이스북에 희생자의 계정으로 광고성 글을 올리는 것이 가능해진다. (물론 페이스북은 CSRF 공격에 대해 잘 대응을 하였겠지만, 이번 글에서 피해 서비스 = 페이스북으로 설명하겠다.)

조금 더 설명하자면, CSRF는 해커가 사용자의 컴퓨터를 감염시키거나 페이스북 서버를 해킹을 해서 이뤄지는 공격은 아니다. 그래서 CSRF 공격이 이뤄지려면 다음 조건이 만족되어야 한다.

  • 위조 요청을 전송하는 서비스(페이스북)에 희생자가 로그인 상태
  • 희생자가 해커가 만든 피싱 사이트에 접속

언뜻 보면 이 두 조건을 다 만족하기가 어려울 것 같지만 생각처럼 드문 일은 아니다. 예를들어 페이스북, 네이버, 구글 등의 유명 사이트는 보통 PC에서 자동 로그인을 해놓은 경우가 많고 피싱 사이트는 피싱 메일 등을 통해 접속될 수 있다. 또한 희생자가 해커가 만든 피싱 사이트를 하지 않더라도 해커가 XSS 공격을 성공한 정상 사이트를 통해 CSRF 공격이 수행될 수 도 있다.

profile
아토언니의 프론트엔드 개발자로서의 기록

0개의 댓글