🔐 적절한 인증 없는 중요기능 허용 - 실습 시뮬레이터

보안기능 취약점 실습 & 금융권 회원정보 수정 공격 체험

✅ 학습 진행도
  • 취약점 진단 완료
  • 요청 사용자 ID 가져오기
  • userId 일치 검증
  • 불일치 시 에러 처리
  • 검증 통과
✏️ 코드 에디터 취약한 코드
MemberController.java 💡 사용자 일치 검증 추가
@RequestMapping(value = "/modify.do", method = RequestMethod.POST)
public ModelAndView memberModifyProcess(
    @ModelAttribute("MemberModel") MemberModel memberModel,
    BindingResult result,
    HttpServletRequest request,
    HttpSession session) {
    
    ModelAndView mav = new ModelAndView();
    
    //1. 로그인한 사용자를 불러온다.
    String userId = (String) session.getAttribute("userId");
    String passwd = request.getParameter("oldUserPw");
    
    //2. 회원정보를 실제 수정하는 사용자와 로그인 사용자와 동일한지 확인한다.
    // TODO: 여기에 검증 로직 추가
    
    ...
    
    //3. 동일한 경우에만 회원정보를 수정해야 안전하다
    if (service.modifyMember(memberModel)) {
        mav.setViewName("redirect:/board/list.do");
        session.setAttribute("userName", memberModel.getUserName());
        return mav;
    } else {
        mav.addObject("errCode", 2);
        mav.setViewName("/board/member_modify");
        return mav;
    }
}
💡 수정 가이드
Step 1: 요청 사용자 ID 가져오기
String requestUser = memberModel.getUserId();
Step 2: 사용자 불일치 검증 (null 체크 포함)
if (userId != null && requestUser != null && !userId.equals(requestUser)) { // 불일치 시 처리 }
Step 3: 불일치 시 에러 반환 (3가지 필수)
mav.addObject("errCode", 1); mav.addObject("member", memberModel); mav.setViewName("/board/member_modify"); return mav;
완성 예시:
//2. 회원정보를 실제 수정하는 사용자와 로그인 사용자와 동일한지 확인한다. String requestUser = memberModel.getUserId(); if (userId != null && requestUser != null && !userId.equals(requestUser)) { mav.addObject("errCode", 1); mav.addObject("member", memberModel); mav.setViewName("/board/member_modify"); return mav; } ... //3. 동일한 경우에만 회원정보를 수정해야 안전하다 if (service.modifyMember(memberModel)) { ... }
📊 실시간 피드백
🎯 목표

회원정보 수정 시 로그인한 사용자와 요청 사용자가 동일한지 검증하세요.

  • String requestUser = memberModel.getUserId()
  • userId와 requestUser null 체크
  • !userId.equals(requestUser) 검증
  • mav.addObject("errCode", 1)
  • mav.addObject("member", memberModel) 추가
  • 불일치 시 return mav 처리
⚠️ 취약점

현재 코드는 사용자 검증이 없습니다!

공격자가 다른 사용자의 ID를 파라미터로 전달하면 타인의 회원정보를 수정할 수 있습니다.

📖 적절한 인증 없는 중요기능 허용이란?

적절한 인증과정 없이 중요정보(계좌이체 정보, 개인정보 등)를 열람하거나 변경할 때 발생하는 보안 취약점입니다.

  • IDOR 연계: 다른 사용자의 ID로 권한 없는 접근
  • 권한 상승: 일반 사용자가 관리자 기능 수행
  • 개인정보 유출: 타인의 민감 정보 조회/수정
✅ 학습 진행도
  • 취약점 진단 완료
  • @login_required 데코레이터 추가
  • 현재 비밀번호 입력받기
  • 현재 비밀번호 해시 비교
  • 검증 통과
🐍 Python 코드 에디터 취약한 코드
views.py (Django) 💡 인증 및 현재 비밀번호 검증 추가
from django.shortcuts import render
from re import escape
import hashlib

def change_password(request):
    new_pwd = request.POST.get('new_password',"")
    
    # 로그인한 사용자 정보
    user = '%s' % escape(request.session['userid'])
    
    # 현재 password와 일치 여부를 확인하지 않고 수정함
    sha = hashlib.sha256(new_pwd.encode())
    update_password_from_db(user, sha.hexdigest())
    
    return render(request, '/success.html')
💡 수정 가이드
Step 1: login_required 데코레이터 import
from django.contrib.auth.decorators import login_required
Step 2: @login_required 데코레이터 추가
@login_required def change_password(request):
Step 3: 현재 비밀번호 입력받기
new_pwd = request.POST.get('new_password',"") crnt_pwd = request.POST.get('current_password',"")
Step 4: 현재 비밀번호 해시 비교
crnt_h = hashlib.sha256(crnt_pwd.encode()) h_pwd = crnt_h.hexdigest() # DB에서 저장된 비밀번호와 비교 if h_pwd != get_password_from_db(user): return render(request, '/error.html')
완성 예시:
from django.contrib.auth.decorators import login_required from django.shortcuts import render from re import escape import hashlib @login_required def change_password(request): new_pwd = request.POST.get('new_password',"") crnt_pwd = request.POST.get('current_password',"") user = '%s' % escape(request.session['userid']) crnt_h = hashlib.sha256(crnt_pwd.encode()) h_pwd = crnt_h.hexdigest() # 현재 비밀번호 검증 if h_pwd != get_password_from_db(user): return render(request, '/error.html') # 검증 통과 후 비밀번호 변경 sha = hashlib.sha256(new_pwd.encode()) update_password_from_db(user, sha.hexdigest()) return render(request, '/success.html')
📊 실시간 피드백
🎯 목표

비밀번호 변경 시 로그인 검증과 현재 비밀번호를 확인하세요.

  • @login_required 데코레이터 추가
  • current_password 파라미터 받기
  • 현재 비밀번호 해시값 생성
  • DB 저장값과 비교 검증
  • 불일치 시 에러 반환
⚠️ 취약점

현재 코드는 2가지 취약점이 있습니다!

1. 로그인 검증 없음 (@login_required 누락)
2. 현재 비밀번호 확인 없이 변경 가능

📖 Python/Django 인증 우회 취약점

Django에서 비밀번호 변경 등 중요 기능 수행 시 적절한 인증 없이 처리하면 발생하는 보안 취약점입니다.

  • @login_required 누락: 비로그인 사용자도 접근 가능
  • 현재 비밀번호 미검증: 세션만 탈취하면 비밀번호 변경
  • 재인증 없음: 중요 작업에 추가 인증 없음