초보자를 위한 코드 품질 리포트 읽기 2편 – Bandit이 싫어하는 MD5 SHA-256으로 바꿔야 하는 이유?

MD5 SHA-256 변경 이미지

1편에 이어서 이번 포스트에서는 MD5 SHA-256으로 바꿔야 하는 이유에 대해 알아보겠습니다.

“왜 MD5가 밉상이 되었는지”와 “그래서 SHA-256으로 어떻게, 어디까지 바꿔야 하는지”를 초보자 관점에서 천천히 풀어보려 합니다.

1. 품질 리포트에서 MD5가 High로 뜨는 이유

실제 품질 리포트에서 Bandit 결과를 보면 이런 문장이 나옵니다.

  • High 경고 3건 – MD5 사용 위치
    • 어떤 유틸 함수에서 식별자 해싱
    • 뷰 로직에서 data_hash 생성에 MD5 사용

Bandit 입장에서는 “MD5 = 기본적으로 위험 후보”입니다.
심지어 “약한 해시 알고리즘”이라서 High로 분류하는 경우가 많아요.

그럼 왜 이렇게까지 MD5를 싫어할까요?

2. 해시 함수, 아주 빠르게 개념만 잡고 가기

해시 함수 참고 이미지

먼저 해시 함수 자체를 한 줄로 정리하면

“어떤 데이터를 고정 길이의 지문(해시)으로 바꿔주는 함수”

예를 들면

  • 비밀번호 저장할 때
  • 이메일 주소를 직접 저장하지 않고, 통계용으로만 쓸 때
  • URL에 짧은 토큰을 쓰고 싶을 때
    (예: /invite/abc123xyz/ 이런 느낌)

등등에 자주 씁니다.

좋은 해시 함수는

  1. 역추적이 매우 어려워야 하고 (원문을 추측하기 힘듦)
  2. 충돌(서로 다른 입력인데 같은 해시)이 거의 안 나야 in the file.

여기서 문제가 되는 게 MD5예요.

3. MD5는 왜 이제 “안전하지 않다”고 할까?

MD5는 한때 엄청 인기 많던 해시 함수였지만,
지금은 보안 업계에서 이렇게 취급됩니다.

“속도는 빠르지만,
보안용으로는 더 이상 쓰지 말자.”

그 이유는 크게 두 가지입니다.

1️⃣ 충돌 공격이 가능

  • 서로 다른 두 데이터가 같은 MD5 값을 가지도록
    인위적으로 만드는 공격이 이미 연구·실제 시연까지 되었음.

2️⃣ 너무 넓게 알려진 알고리즘 + 빠른 속도

  • 공격자가 무차별 대입(brute force)이나
    레인보우 테이블(사전 계산된 해시 목록)을 통해
    특정 해시가 어떤 값인지 비교적 쉽게 유추할 수 있음.

즉, 비밀번호, 인증 토큰, 서명, 보안에 중요한 값에
MD5를 계속 쓰는 건 지금 시점에서는 위험한 선택Answer.

그래서 Bandit MD5 경고를 보면 바로

  • “이건 High 레벨 보안 이슈일 수 있다”
    라고 경고를 띄워주는 거죠.

4. SHA-256은 뭐가 다를까?

SHA-256은 SHA-2 계열 해시 함수 중 하나입니다.

  • 출력 길이: 256비트 (보통 64자리 16진수 문자열)
  • 현재 기준으로는 보안상 훨씬 강한 해시 함수로 인정받고 있음
  • 비밀번호, 토큰, 서명, 메시지 무결성 등에서 널리 사용

당연히 “완전 영원히 안전” 같은 건 없지만,
지금 시점에서 MD5를 쓸 이유는 거의 없고,
MD5 SHA-256로 교체하는 것이 기본 선택
.

그래서 우리가 실제로 해야 할 일은

기존 코드에서 MD5 SHA-256으로 교체
하고, 그게 어떤 의미인지 이해하는 것

5. 실전 예시 – Python 코드에서 MD5 SHA-256으로 바꾸기

Python 코드에서 MD5를 SHA-256으로 바꾸기 이미지

초보자 입장에서 가장 궁금한 건 이거죠.

“그래서 실제 코드는 어떻게 고치는 건데요?”

아주 단순한 패턴부터 보면

5-1. 기존 MD5 코드 (예시)

import hashlib

def make_token(value: str) -> str:
    return hashlib.md5(value.encode("utf-8")).hexdigest()[:8]
  • 문자열을 받아서 md5 해시를 만들고
  • 그 중 앞의 8자리만 잘라서 토큰으로 쓰는 경우입니다.

5-2. MD5 SHA-256 변경 예시

import hashlib

def make_token(value: str) -> str:
    # SHA-256으로 변경
    return hashlib.sha256(value.encode("utf-8")).hexdigest()[:8]

겉으로 보기에는
딱 한 줄만 바뀐 것 같지만, 의미는 꽤 큽니다.

  • 해시 알고리즘이 바뀌었기 때문에
    같은 입력 값이라도 완전히 다른 값이 나오고,
  • 기존에 저장해 둔 토큰과는 호환되지 않습니다.

그래서 여기서 중요한 질문이 하나 나옵니다.

“이 토큰, 어디에 저장돼 있고,
이 값을 믿고 있는(의존하는) 시스템이 따로 있나?”

6. MD5 SHA-256 변경 전에 꼭 체크해야 할 것들

해시 교체는 코드 한 줄 수정처럼 보이지만,
데이터와 외부 시스템에 영향을 줄 수 있는 변경.

아래 네 가지를 꼭 체크해 보세요.

✅ 1) 이 해시는 어디에 쓰이나요?

  • 단순히 “화면에서만 잠깐 쓰는 값”인지
  • DB에 저장돼서 중복 체크, 캐시 키, 초대코드 등으로 쓰이는지
  • 외부 시스템과 API 파라미터/링크로 주고받는 값인지

✅ 2) 기존 값과 “연결된” 게 있는지

  • 이미 발급해 둔 링크(URL)
  • 이미 사용자에게 발송된 초대코드, 인증코드
  • 외부 시스템이 이 값을 키로 삼고 있는지

이게 하나라도 있으면,
MD5 SHA-256 변경을 할 때 전환 전략is required.

✅ 3) 교체 전략 예시

전략 A – 당장 교체 (내부용/캐시용)

  • 내부 캐시 키, 통계용 익명 식별자 등
    “새로 만들어도 상관 없는 값”이면 그냥 바꿔도 됩니다.
  • Example:
    • “이 해시는 오늘부터 새로 찍는 데이터에만 쓸게요”
    • 예전 데이터는 안 써도 상관없거나, 자동으로 갱신됨

전략 B – 점진 교체 (사용자에게 노출된 토큰)

  • 초대코드처럼 이미 사용자에게 나간 값이면
    • 일정 기간 동안은
      • “MD5로 만든 코드도 받기 + 새 코드는 SHA-256로 발급”
    • 이후에는 MD5 코드는 만료시키고
      SHA-256만 받도록 정책 변경

전략 C – 버전 정보 추가

  • 해시를 저장할 때 “버전” 컬럼을 추가해서
    • version = 'md5'
    • version = 'sha256'
  • 인증/검증 시
    • 버전을 보고 어떤 알고리즘으로 검증할지 결정
    • 나중에 md5 버전만 따로 제거 가능

7. Bandit MD5 경고를 실제 작업 계획으로 바꾸는 법

Bandit MD5 경고를 실제 작업 계획으로 바꾸는 법 이미지

Bandit MD5 경고를 실제 작업 계획으로 바꾸는 법으로 브랜치 생성-머지 전략을 제안드립니다.

  • MD5 → SHA-256 교체용 별도 브랜치 생성 (예: quality/security-md5-change)
  • MD5 사용하는 모든 위치를 찾아서
    • SHA-256으로 교체
    • 해시 길이/토큰 길이(슬라이싱)를 어떻게 할지 정리
  • 그 후에
    • flake8, bandit, 테스트(manage.py check 등)를 실행
    • 문제가 없는지 확인 후 메인 브랜치에 머지

이 방식은 초보자에게도 정말 안전한 패턴.

“보안 관련 큰 변경은 항상
👉 별도 브랜치 → 체크 → 리뷰 → 머지
이 루틴을 타는게 좋다.”

특히 Bandit가 High로 찍는 경우는
“그냥 지나가면 언젠가 사고 난다”에 가까워요.

MD5 SHA-256 변경 작업은
“귀찮지만 피하면 안 되는 최소한의 보안 투자”라고 생각하면 됩니다.

8. 용어 정리

  • MD5
    예전에 많이 쓰이던 해시 함수.
    지금은 충돌 공격 등으로 인해
    비밀번호·토큰 등 보안 민감 용도에는
    사용하지 말라고 권고되는 알고리즘입니다.
  • SHA-256
    SHA-2 계열 해시 함수 중 하나.
    현재 기준으로는 안전성이 검증되어
    토큰, 서명, 무결성 검증 등에 널리 사용됩니다.
  • 해시 충돌
    서로 다른 두 데이터가
    같은 해시 값을 가지는 현상.
    보안 관점에서는 치명적입니다.
  • 토큰(Token)
    사용자를 구분하거나,
    특정 요청을 인증하기 위해 쓰는
    짧은 문자열(키 값).
  • Bandit MD5 경고
    Bandit가 MD5 사용을 발견했을 때
    보안 이슈 가능성이 높다고 판단해 띄우는 High 레벨 경고.

다음 포스트에서는 mark_safe, raw SQL, urllib 관련 보안 경고를 실제 Django 관점에서 어떻게 이해하고, 어떤 기준으로 “위험/안전”을 구분할지 정리해볼게요.

Similar Posts