치춘짱베리굿나이스
로그인, 인증, 인가 본문
로그인, 인증, 인가
로그인
대부분의 회원제 사이트에서 회원 각각이 자신의 계정을 이용하며, 모든 사람이 같은 데이터를 공유하여 접근하지 않고, 개인별로 할당된 리소스만 접근할 수 있는 방법이다
사용자들은 로그인을 통해 ID랑 비밀번호 (또는 OAuth같은 경우 서드파티 계정 정보 등…) 를 서버에 전달하여 내가 누군지 인증 절차를 거치고, 서버에서는 유저 검증 후 그에 맞는 유저 정보, 또는 권한을 인가한다
웹 사이트를 만들면서 로그인을 구현할 때는, 고려해야 할 점이 두 가지가 있다
- 보안 문제
- 아이디와 비밀번호를 탈취당한다면 다른 사람이 내 정보에 접근할 수 있다는 치명적인 문제가 존재한다
- 완벽하게 해킹을 막는 방법은 거의 존재하지 않고, 최선의 방법으로 예방 정도만 할 수 있다
Refresh Token
, 2차 인증이나 OTP 등이 보안 문제의 대안으로 등장한 것들이다- 인증 및 인가 절차에서 일어날 수 있는 보안 이슈로 CSRF 공격과 XSS 공격이 있다
- 로그인 유지 문제
- 페이지를 이동할 때마다 로그인이 풀려버리면 사용자 입장에선 매우 귀찮아진다 (사용자 경험이 매우… 낮아진다)
- 위의 보안 문제를 신경쓰면서 사용자가 한번 로그인하면 어느 정도는 로그인을 유지할 수 있도록 (매번 인증할 필요 없이 권한 인가가 가능하도록) 구현해야 한다
- 쿠키와 세션,
Access Token
이 로그인 유지를 위해 도입된 것들이다 (쿠키와 세션은 로그인에서만 사용되는 것은 아니긴 한다)
인증
Authentication
특정 클라이언트가 나 치춘이임 ㅇㅇ
이라고 주장한다면 그게 진짜 치춘인지 치춘이인 척 하는 이상한 사람인지 검증하는 과정이다
- 만약 본인이 치춘이랍시고 서버에 아이디와 비밀번호를 제출했는데 비밀번호가 틀렸다면? 그것은 짝퉁 치춘이다 (인증 실패)
- 아이디와 비밀번호가 맞았거나, 토큰이 유효하거나, 그 외 기타 방법으로 치춘이임을 증명에 성공했다면 그것은 인증에 성공한 것이다
- 학교 도서관에 갔을 때, 이 학교 학생이 맞는지 확인하기 위해 학생증을 내미는 과정이 인증 과정이라 할 수 있다
지문 인식이나 비밀번호를 통한 잠금 해제, OTP나 2차 인증 앱 등이 인증 관련 프로세스에 속하며, 클라이언트에서 넘긴 데이터를 서버가 검증하는 방식으로 이루어진다
웹앱에서 최초로 로그인하여 토큰을 지급받는 과정이 인증에 속한다
인가
Authorization
일단 이 사람이 진짜 치춘이라는 건 밝혀졌으니, 치춘이가 할 수 있는 행동들이나 접근할 수 있는 자원에만 접근을 허용할 수 있도록 확인하는 절차이다
- 치춘은 치춘 블로그 (https://blog.chichoon.com/) 에 글을 적을 수 있으므로, 치춘임이 확인된 클라이언트에 글 작성 권한을 부여한다
- 하지만 치춘은 홍길동이 아니므로, 홍길동 블로그의 글 작성 권한은 부여하지 않는다
- 학생증을 이용 (인증) 하여 학교 도서관에 들어간 후, 도서관 안의 도서관 자치위원회실 출입 권한이나 일반 열람실 출입 권한은 학생의 역할에 따라 부여된다 (인가)
인증에 성공한 뒤 해당 계정 (사용자) 정보를 기반으로 서버 측에서 일방적으로 부여한다
토큰을 이용하여 웹앱의 다양한 기능에 대한 권한을 부여하는 과정이 인가에 속한다
CSRF 공격
Cross-site Request Forgery: 사이트 간 요청 위조
특정 악성 코드를 실행시키는 순간 내 쿠키를 사용하여 내가 원치 않은 요청을 보내 데이터를 탈취하는 방식의 공격이다
- 티스토리에 로그인하고, 티스토리 서버로부터 쿠키를 받아 저장하여 자동 로그인이 되도록 하였다
- 다른 블로그를 구경하다가 아차! 악성 코드가 삽입된 링크를 클릭하고 말았다
- 악성 코드는 나의 티스토리 쿠키를 이용하여 나도 모르는 사이에 티스토리 측에 요청을 마구 보낸다
- 티스토리 서버 측에서는 쿠키를 확인 후 이 요청이 (당연하게도) 나에게서 온 요청으로 판단하고, 요청을 정상적으로 처리 후 응답을 보낸다
- 나도 모르는 사이에 블로그가 광고 글, 온갖 똥글로 도배가 된다!
내 쿠키, 내 정보를 이용하여 요청을 위조하기 때문에 ‘사이트 간 요청 위조’ 공격이다
이 공격을 막기 위해서는
- Referrer (출처) 검증을 진행한다
- 요청이 서버에 도착했을 때, 이 요청이 우리가 의도한 웹 사이트 도메인으로부터 온 요청이 맞는지 검증하는 것이다
- 만약 티스토리 블로그에 글을 작성하는 요청인데 요청 URL이
tistory.com
이 아니라면? 어 이자식 수상하네~ 하고 방어하는 것이다 - 물론 XSS와 협업하면 마치 티스토리 웹사이트에서 요청을 보낸 것처럼 위장할 수 있기 때문에 삽시간에 무력해질 가능성이 높다
- 또한 이 값도 얼마든지 조작하려면 조작할 수 있어서, 가장 간단하긴 하지만 확실한 대책은 아니다
- CSRF 토큰을 사용한다
- CSRF 토큰은 서버에서 생성한 임의의 난수값이다
- 세션에 저장해 두며, 사용자에게서 요청이 왔을 때 요청에 포함된 CSRF 토큰과 세션에 저장되어 있는 값을 비교하여 일치하지 않을 경우 요청을 처리하지 않는 방식이다
- CAPTCHA, 나는 로봇이 아닙니다… 등의 인증 방식이 이를 이용하여 부적절한 요청을 걸러낸다
- 마찬가지로, XSS와 협업하여 마치 정상적인 페이지에서 보낸 요청인 척 전송하면 CSRF 토큰마저도 위조하여 사용할 수 있기 때문에 완벽하진 않다
- 세션 대신 쿠키를 사용하여 (쿠키가 도메인마다 별도로 저장된다는 점을 이용하여) 도메인 검증을 시도하는 방식도 있다
XSS 공격
Cross-Site Scripting: 사이트간 스크립팅
Cross를 C 대신 진짜 십자 모양인 X로 적는 것이 특징이다 (CSS로 적으면 스타일시트 같으니까,,)
웹 페이지에 비정상적인 코드를 삽입하여 사용자가 의도치 않은 행동을 수행하는 공격이다
쉽게 말해 블로그 글쓰기 창과 같이 평범한 텍스트 입력기에 html
코드, 특히 <script>
태그를 이용해서 자바스크립트 코드를 작성하면 실제로 그 코드가 동작하고, 심한 경우 모든 유저에 대해 코드가 동작해버리면서 보안이 뚫려버리는 것이다
옛날 몇몇 커뮤니티에서 프로그래밍 실수로 댓글 html
작성이 가능해지는 바람에 악질 사용자들이 사이트 배경을 바꿔버리거나, 스타일을 조작해서 웹 페이지를 좌우반전 시켜버리거나, 심하면 혐짤 테러나 정보 탈취를 시도한 적이 있었다고 한다
SQL injection과 같이 엄청나게 단순한 - 전문 지식 없이도 코드 작성만 조금 할 줄 알면 손쉽게 실행 가능한 - 공격 방식이기 때문에, 현대의 웹 페이지 대다수에는 막혀있다고 보면 된다… 만 내가 웹 페이지를 만들 때가 되면 신경써야 하는 취약점 공격법 중 하나이다
CSRF 공격을 시도할 때 XSS와 함께하면 효과가 배가 된다
세션 기반 인증
Session-based Authentication
로그인의 방식 중 하나이다
말 그대로 세션을 사용하며, 로그인 (인증) 에 성공하면 사용자의 인증 정보가 세션에 저장되고 클라이언트에게는 세션 ID를 발급한다
클라이언트는 서버에 요청을 보낼 때마다 이 세션 ID를 헤더에 포함시키고, 서버는 헤더로부터 세션 ID를 읽어 세션에 사용자의 정보가 저장되어 있는지 (인증을 마쳤는지) 판단한다
- OT 참가를 신청하고 OT비를 지불하면 (인증 성공) 학생회는 학생의 학번 (세션 ID) 을 스프레드시트 등 (세션) 에 저장한다
- OT 당일, 학생은 본인의 학번 (세션 ID) 을 학생회 임원에게 말하고, 학생회 임원은 스프레드시트 (세션) 를 체크하여 학생의 참석 여부 (인증 정보) 가 기록되어 있는지 판단한다
세션 기반 인증은 세션 ID만 주고받으면 되기 때문에 탈취당해도 피해가 적고 토큰에 비해 용량이 작아 트래픽 부담이 덜어진다
세션을 사용하는 방식이 다 그렇듯, 서버에 데이터를 저장하므로 보안성이 좋긴 하지만 서버 저장 공간을 차지해야 하고 매번 세션 데이터베이스에서 정보를 읽어와야 하므로 유저가 많아질 수록 서버의 부담이 심해질 수 있다
또한 서버가 분산될 경우 어느 서버에 어떤 세션이 저장되어 있는지 명확하지 않아, 별도의 처리 과정이 없다면 인증 과정에 문제가 발생할 수 있다
토큰 기반 인증
Token-based Authentication
마찬가지로 로그인 방식 중 하나이다
로그인 (인증) 에 성공하면, 서버는 특정 알고리즘으로 암호화된 문자열 (토큰) 을 클라이언트에게 발급하며, 그 안에는 사용자의 로그인 정보와 함께 우리 서버가 발급했음을 증명하는 서명이 들어있다
클라이언트는 서버에 요청을 보낼 때마다 토큰을 헤더에 포함시키고, 서버는 헤더로부터 토큰을 읽고 복호화해 이 유저가 누구인지, 우리 서버에서 만든 토큰이 맞는지 정보와 서명을 체크한다
- KTX 티켓을 예매하기 위해 금액을 지불하면, 당신의 정보 (사용자 로그인 정보) 와 탑승 체크용 바코드 (서버의 서명) 가 담긴 기차표 (토큰) 를 받는다 (인증 성공)
- 승객 (클라이언트) 은 기차표 (토큰) 를 지니고 다니다가 검표하는 역무원 (서버) 을 마주칠 때마다 기차표를 제시하여 본인이 KTX에 탑승할 자격이 있음을 보인다
서버의 저장 공간 부담이 상대적으로 적고, 인증에 필요한 모든 정보 (토큰) 를 서버가 아닌 사용자가 가지고 있으므로 토큰 복호화 및 해석 로직만 있다면 서버를 확장하기도 용이하다
다만 세션 ID에 비해 무거운 토큰을 매번 주고받아야 하며, 심지어 Access Token과 Refresh Token을 둘 다 사용하는 경우 용량이 두 배가 된다
또한 토큰을 모두 탈취당할 경우 내부에 서버 서명과 로그인 정보가 들어있기 때문에 세션 기반에 비해 위험하다
서버 확장의 용이성 덕분에 토큰 기반 인증이 널리 쓰이게 되었다고 볼 수 있다
참고자료
로그인, 인증, 인가
https://www.okta.com/kr/identity-101/authentication-vs-authorization/
'이론적인 부분들 > 웹' 카테고리의 다른 글
DOM과 웹 렌더링 (0) | 2023.05.19 |
---|---|
JWT (0) | 2022.10.10 |
쿠키와 세션 (0) | 2022.10.08 |
HTTP 기본 (0) | 2022.08.04 |
HTTP 응답 코드 종류 (2) | 2022.08.04 |