[주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스] 10강 — [Day 10] 불충분한 인증 절차
안녕하세요! Hackerstory 공부방의 IT/보안 튜터 정다은입니다. 👋
어느덧 **[주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스]**의 반환점, Day 10에 도달했습니다! 매일 하나씩 차근차근 따라와 주시는 여러분, 정말 대단합니다.
오늘 우리가 배워볼 10번째 주제는 바로 **'불충분한 인증 절차(Insufficient Authentication)'**입니다.
웹 사이트에 들어갈 때 "내가 누구인지" 증명하는 과정이 바로 **인증(Authentication)**이죠. 그런데 만약 집 출입문 도어락은 단단히 잠가두고 정작 옆쪽 창문을 열어두었다면 어떻게 될까요? 오늘 배울 취약점이 바로 그런 상황을 말합니다.
원리부터 실무 대책까지 자세히 알아보겠습니다!
[Day 10] 불충분한 인증 절차 (Insufficient Authentication)
1. 개념 이해하기
💡 '불충분한 인증 절차'란 무엇인가요?
로그인이나 개인정보 수정, 금융 이체, 비밀번호 변경 등 중요한 비즈니스 로직을 수행할 때 사용자의 식별 및 인증 절차가 누락되어 있거나, 공격자가 이를 우회할 수 있는 취약점을 의미합니다.
정상적인 서비스라면 모든 보호된 페이지와 API는 "이 요청을 보낸 사람이 로그인된 사용자가 맞는가?"를 서버에서 확인해야 합니다. 하지만 개발 과정에서 특정 페이지의 인증 검증 코드를 누락하거나, 클라이언트(브라우저)에서 전달되는 파라미터만 믿고 처리할 때 이 취약점이 발생합니다.
❓ '인증(Authentication)'과 '인가(Authorization)'의 차이
많은 분들이 헷갈려하시는 개념이라 살짝 짚고 넘어가겠습니다.
- 인증 (Authentication): "당신은 누구인가요?" (신원 확인, 예: 로그인)
- 인가 (Authorization): "당신은 이 행동을 할 권한이 있나요?" (권한 확인, 예: 일반 유저가 관리자 페이지 접근)
오늘 다루는 불충분한 인증은 "아예 로그인조차 하지 않았는데(신원 불명) 중요 기능에 접근이 가능한 문제"를 집중적으로 다룹니다. (불충분한 인가는 다음 시간인 Day 11에 다룰 예정입니다!)
2. 취약점 동작 원리 및 예시
공격자가 인증 절차를 우회하는 대표적인 2가지 패턴을 예시로 살펴봅시다.
패턴 1. 인증 단계 건너뛰기 (Step Bypassing)
다단계로 진행되는 서비스(예: 회원가입, 비밀번호 재설정, 본인인증 후 송금)에서 중간 단계를 거치지 않고 최종 단계 URL/API를 직접 호출하는 경우입니다.
🚨 취약한 시나리오 (비밀번호 변경 로직)
- 1단계 (
/reset/step1): 아이디 입력 - 2단계 (
/reset/step2): 휴대폰 SMS 인증번호 입력 - 3단계 (
/reset/step3): 새로운 비밀번호 입력 및 변경 처리
<!-- 공격자의 요청: 1단계, 2단계를 모두 건너뛰고 3단계 API를 직접 호출 -->
POST /api/v1/reset-password HTTP/1.1
Host: vulnerable-bank.com
Content-Type: application/json
{
"target_user": "victim_id",
"new_password": "HackedPassword123!"
}
원인: 서버가 /api/v1/reset-password 요청을 받았을 때, "이 사용자가 2단계 SMS 인증을 성공했는가?"에 대한 세션 상태를 검증하지 않고 전달받은 target_user의 비밀번호를 바로 변경해버린 것입니다.
패턴 2. 서버 측 세션/토큰 검증 누락 (Direct Page Access)
로그인해야만 접근할 수 있는 마이페이지나 결제 완료 페이지의 URL을 로그인하지 않은 상태(비회원/공격자)에서 직접 주소창에 입력하여 접근하는 경우입니다.
❌ 취약한 서버 코드 예시 (PHP)
<?php
// mypage.php - 마이페이지
// 세션 검증 로직이 전혀 없음!
$user_id = $_GET['user_id'];
$user_info = getUserDataFromDB($user_id);
echo "<h1>안녕하세요, " . $user_info['name'] . "님!</h1>";
echo "<p>이메일: " . $user_info['email'] . "</p>";
?>
위 코드는 사용자가 로그인했는지($_SESSION['is_logged_in']) 전혀 확인하지 않고, 단지 URL 쿼리스트링으로 전달된 user_id 값만으로 개인정보를 보여줍니다.
3. 진단 방법 (진단원 관점)
실무에서 보안 진단원들은 다음과 같은 방법으로 불충분한 인증 절차를 진단합니다.
- 로그인 후 주요 기능 URL 및 API 수집:
- 프록시 툴(Burp Suite 등)을 활용해 로그인 상태에서 접근하는 모든 URL 및 API 엔드포인트를 수집합니다.
- 인증 정보 제거 후 재요청:
- 요청 헤더에서 Cookie(Session ID), Authorization(JWT 토큰 등)을 제거하거나 무효화된 토큰으로 교체한 뒤 동일한 요청을 전송합니다.
- 응답 결과 확인:
401 Unauthorized또는로그인이 필요합니다라는 리다이렉트 응답 대신, 정상 데이터(HTTP 200 OK)가 반환되면 취약한 것으로 판단합니다.
- 다단계 프로세스 우회 테스트:
- 프로세스 중간 단계(예: OTP 입력)를 생략하고 최종 결과 제출 API를 직접 호출해 봅니다.
4. 실무 대응 및 보안 대책
불충분한 인증 절차를 방지하기 위해서는 **"모든 요청은 기본적으로 신뢰하지 않는다"**는 제로 트러스트(Zero Trust) 관점의 개발이 필요합니다.
1. 모든 보호된 엔드포인트에 대한 서버 측 인증 검증 강제
웹 애플리케이션의 모든 비공개 페이지 및 API는 호출될 때마다 서버 세션 또는 유효한 JWT 토큰을 반드시 검증해야 합니다.
⭕ 안전한 서버 코드 예시 (Node.js / Express 미들웨어 패턴)
// 인증 검증 미들웨어
function requireAuth(req, res, next) {
// 서버 세션에 로그인 정보가 있는지 확인
if (!req.session || !req.session.userId) {
return res.status(401).json({
success: false,
message: "인증이 필요합니다. 로그인 후 이용해주세요."
});
}
// 인증 성공 시 다음 로직 진행
next();
}
// 마이페이지 조회 API - 미들웨어를 거치도록 설정
app.get('/api/user/profile', requireAuth, (req, res) => {
const userId = req.session.userId; // URL 파라미터가 아닌 세션에서 ID를 가져옴
const userInfo = getUserProfile(userId);
res.json(userInfo);
});
2. 다단계 프로세스의 상태(State) 검증
여러 단계를 거치는 비즈니스 로직(예: 본인인증 ➔ 비밀번호 변경)은 서버 세션에 현재 단계의 진행 상태를 저장하고 검증해야 합니다.
# Python / Flask 예시
@app.route('/api/reset-password', methods=['POST'])
def reset_password():
# 2단계(SMS 인증)가 완료되었는지 서버 세션 상태 확인
if not session.get('is_sms_verified'):
return jsonify({"error": "본인 인증이 완료되지 않았습니다."}), 403
# 비밀번호 변경 로직 수행
update_password(session['reset_target_user'], request.json['new_password'])
# 사용 완료된 세션 상태 즉시 파기 (재사용 방지)
session.pop('is_sms_verified', None)
return jsonify({"message": "비밀번호가 성공적으로 변경되었습니다."})
3. 다중 요소 인증(MFA, Multi-Factor Authentication) 적용
금융 거래, 비밀번호 변경, 회원 탈퇴, 개인정보 대량 조회 등 고위험 기능 수행 시에는 단순 로그인 세션 외에 OTP, SMS, Bio 인증 등 추가 인증을 재요청하도록 설계합니다.
📝 10일차 핵심 요약
- 불충분한 인증 절차는 중요 로직 실행 시 서버에서 사용자의 로그인 상태나 인증 단계를 제대로 검증하지 않아 발생하는 취약점입니다.
- 클라이언트의 입력값(파라미터, 쿠키 등)은 언제든 변조 및 우회가 가능하므로, 반드시 서버 측 세션/토큰을 기준으로 인증 상태를 판별해야 합니다.
- 다단계 프로세스는 단계별 진행 상태(State)를 서버 세션에 기록하여 중간 과정을 건너뛰는 공격을 차단해야 합니다.
- 중요 비즈니스 로직에는 **MFA(다중 요소 인증)**를 추가하여 보안성을 극대화합니다.
오늘 강의도 수고 많으셨습니다! 인증(Authentication)은 웹 보안의 가장 기본이 되는 첫 번째 방어선인 만큼, 실무에서 코드를 작성하거나 진단할 때 빠뜨린 곳이 없는지 항상 더블 체크하는 습관이 중요합니다.
다음 시간 **[Day 11]**에는 인증을 통과한 사용자가 타인의 자원에 접근하거나 권한을 오남용할 때 발생하는 **'불충분한 권한 검증 (Insufficient Authorization)'**에 대해 알아보겠습니다.
궁금한 점이 있으시다면 언제든 댓글로 질문 남겨주세요! 다음 챕터에서 만나요! 🚀
댓글 0
로그인하면 댓글을 작성할 수 있습니다.