일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 설계
- 커밋 메시지
- 우테코
- 프리코스
- 클린코드
- 객체지향설계
- 구글 플레이 스토어 배포 방법
- 플레이스토어 비공개 테스트
- 기능명세서
- git
- 객체지향
- 구글 플레이 비공개 테스트
- 운영체제 #CS지식
- 구글 비공개 테스트 20명
- 플레이 스토어 20명
GYUD-TECH
[해피에이징] 수평적 권한 상승 문제 본문
해피에이징 프로젝트를 하며 데이터의 인가 부분에서 예상치 못한 보안 문제가 발생했다.
보안 문제가 발생한 데이터베이스의 부분은 아래와 같다.
인증을 위해 JWT 토큰 내부에 userId를 추가하여 해당 user가 존재하는지 여부를 작성하는 코드를 작성했다.
만약 user가 생성한 senior 정보에 접근하고 싶다면, 따로 userId를 보내서 유효성 여부를 확인하는 것이 아니라 token 내부에 있는 userId에 연결된 senior를 조회하는 방식으로 서버의 부담이 줄였다.
하지만 survey 데이터에 접근하는 경우에는 다른 유저의 survey 데이터도 접근 가능해지는 문제가 발생했다.
survey 접근 요청이 들어오면, 해당 토큰이 만료되었는지 여부만 판단하고, 조회하고자 하는 survey 데이터가 해당 유저가 생성한 데이터 인지를 검증하는 절차가 없었기 때문에 발생하는 문제였다.
애플리케이션 단에서는 위와 같은 요청이 발생하지 않았기 때문에 문제를 확인할 수 없었지만, postman으로 API 테스트를 하면서 위와 같은 보안 문제가 발생하는 것을 확인하였다.
이를 해결하기 위해서는 survey와 연결된 senior를 찾고, senior의 user가 토큰 내에 저장된 userId와 일치하는지 여부를 판단해야만 했다.
survey의 경우에는 두단계 참조만이 필요하지만, user 테이블과 더 멀리 존재하는 result나 reponse 테이블은 더 많은 참조가 필요했기 때문에 어떻게 서버의 부하와 응답 시간을 줄이면서, 인가여부를 확인할 수 있는지 고민하였다.
IDOR 취약점
IDOR 취약점이란 Insecure Direct Object Reference의 약자로 부절절한 인가라는 뜻의 보안 취약점이다.
이는 애플리케이션 보안을 위해 힘쓰는 비영리 단체인 OWASP가 조사한 2021년 가장 위협적인 웹 취약점 Top 10 중 1위를 차지한 Broken Access Control과도 연관된 심각한 문제이다.
JWT는 stateless한 Token이기 때문에 서버에서 검증 작업을 따로 수행하지 않아도 된다는 장점을 가지고 있어 많은 애플리케이션에서 사용한다.
하지만 서버에서 검증 작업을 수행 할 필요가 없는 점이 보안의 측면에서는 단점으로 작용하여 IDOR 취약점과 같은 문제가 발생한다.
인가 검증 작업을 수행하지 않기 때문에 특정 사용자가 동일한 권한을 가진 사용자 데이터에 접근요청을 보내더라도 토큰이 유효하기만 하면 요청이 수락되는 것이다.
이는 수평적 권한 상승문제 라고 불리기도 한다.
해결방안
어떻게 하면 수평적 권한 상승 문제를 해결할 수 있을까?
UserId 일치 여부 확인
가장 먼저 떠오른 방법은 매 검증마다 조회하고자 하는 데이터의 소유자와와 토큰에 포함된 userId가 일치하는지 여부를 판단하는 것이다.
하지만 이 방법은 user 테이블과 멀어질 수록 더 많은 작업을 수행해야 하기 때문에 비효율적이라고 생각했다.
매 테이블마다 UserId를 추가
첫번째 방법의 문제는 해당 데이터를 소유한 user 데이터가 필요하여 조인연산이 발생하여 시간이 오래 걸린다는 점이다.
이를 해결하기 위해서 테이블마다 userId를 추가하여 조인 없이 바로 검증이 가능하도록 하는 방법이 떠올랐다.
조인 없이 소유권을 직접 확인할 수 있다는 장점이 있어 서버의 부하를 줄이고, 응답 시간을 개선할 수 있다.
성능 최적화
쿼리 최적화나 캐싱 기법을 도입하여 조회 연산의 성능 자체를 개선하는 방안도 고려할 수 있다.
쿼리 최적화를 활용하여 쿼리 응답 시간 자체를 개선하거나, 캐시를 활용해서 한번 조회한 데이터는 캐시에서 빠르게 가져오는 방식으로 서버의 부하를 줄이고 절약할 수 있다.
느낀점
다양한 방법을 대표님과 함께 논의하며 어떤 방법이 좋을지 함께 고민하였다.
캐시와 쿼리 최적화는 추가적으로 공부를 해야 했기 때문에 다가온 개발 마감 일정에 적용하기 어렵다고 판단하였고 추가적인 서버 비용도 발생하였기 때문에 도입하지 못했다.
비용 및 일정을 고려하여 애플리케이션의 운영은 별다른 검증 없이 jwt를 통해서 인증과 인가를 모두 수행하는 방식으로 구현하였다.
서비스의 사용자가 많지 않기 때문에 보안적인 측면 보다는 개발 일정과 사용자가 빠르게 응답을 받을 수 있는 사용성을 우선적으로 고려하여 결정하였다.
자료를 찾아보며 학습했던 다양한 해결책을 적용하지는 못했지만, 프로젝트가 끝난 후 캐시와 쿼리 최적화 및 테스팅에 대해 공부해서, 이를 적용해보고 최선의 방법이 무엇일지 고민할 계획이다.
'프로젝트' 카테고리의 다른 글
[뉴젯] Redis 도입과 분산 락을 활용한 동시성 문제 해결 (0) | 2025.02.01 |
---|---|
[뉴젯] 도커를 활용한 CI 구축 (0) | 2025.01.15 |
[뉴젯] 유저 지표에서 시작된 쿼리 성능 최적화 (1) | 2025.01.06 |
[뉴젯] 메일 수신 처리 속도 및 AWS Throttling 지표 개선 (1) | 2025.01.03 |
[해피에이징] User 데이터 삭제 (0) | 2024.01.08 |