개발 slecs

시드 스크립트 마스킹 범위 확대

목차

bulk_seed.py는 개발/테스트 환경에 초기 데이터를 빠르게 적재하는 스크립트다. 이번 fix에선 이 스크립트의 마스킹 정책을 강화했다 — 마스킹 패턴을 더 포괄적으로 확대하고, 마스킹 후에도 민감 정보가 남아있지 않은지 검증하는 has_unsafe_residue 패턴을 추가했으며, 이제껏 마스킹 범위에서 놓쳤던 body_md 필드까지 적용했다.

왜 seed 스크립트에 마스킹이 필요한가

개발 환경과 테스트 환경에 실제 운영 데이터를 그대로 복사해서 사용하는 건 보안 악몽이다. 고객 정보, 결제 정보, 개인키 같은 민감 데이터가 개발자의 로컬 머신, CI 로그, 테스트 결과 스냅샷 등 여러 곳에 남아난다. 그래서 우리는 seed 스크립트에서 데이터를 적재할 때부터 민감한 필드들을 마스킹해왔다.

이전까지의 패턴들은 대부분 구조화된 필드(고객 이메일, 전화, 주소 같은)를 대상으로 했다. 하지만 실무에서는 예상치 못한 곳에 민감 정보가 숨어있는 경우가 많다. 예를 들면:

  • body_md (마크다운 형식의 본문): UI에서는 렌더링할 텍스트인데, 실제로는 고객 의견, 이슈 설명, 메모 같은 자유 텍스트가 들어있다.
  • dynamic 필드들: JSON 형식으로 저장되는 메타데이터나 설정값들.

이런 필드들까지 마스킹 범위에 포함하지 않으면, 겉으로는 깔끔한 seed 데이터처럼 보이지만 사실 민감한 단서들이 곳곳에 남아있게 된다.

확대된 마스킹 패턴과 residue 검증

이번 변경의 핵심은 세 가지다:

항목 설명
mask 패턴 확대 기존의 제한된 정규식들을 더 포괄적으로 재설계. 놓쳤던 엣지 케이스들(하이픈, 특수 문자, 혼합 포맷)까지 커버
has_unsafe_residue 마스킹 후에도 특정 패턴들(이메일 도메인, 휴대폰 번호 부분, IP 대역 등)이 남아있진 않은지 추가로 검증
body_md 필드 추가 이제까지 구조화된 필드만 마스킹했다면, 자유 텍스트 필드도 동일한 수준으로 처리

has_unsafe_residue 패턴이 중요한 이유는 마스킹 자체가 완벽하지 않기 때문이다. 예를 들어, 고객 이메일을 그냥 "****@example.com"으로 마스킹했다면, 도메인 부분만 노출되어도 "어느 회사의 직원이구나" 같은 정보가 새어 나간다. 그래서 마스킹 후 패턴 매칭으로 "진짜 마스킹이 제대로 됐나?" 하는 사후 검증 단계가 필요하다.

# 예: has_unsafe_residue 패턴 검증 개념
unsafe_patterns = [
    r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',  # 이메일
    r'(?:010|011|016|017|018|019)-?\d{3,4}-?\d{4}',  # 휴대폰
    r'(?:\d{3}-?\d{4})',  # 신용카드 부분
]

def validate_after_mask(text):
    for pattern in unsafe_patterns:
        if re.search(pattern, text):
            return False  # 민감 정보 남음
    return True

팀 리딩 관점 — 왜 이런 추가 체크가 필요했을까

솔직히 이런 종류의 보안 fix는 한두 가지 이유에서 나온다:

  1. 과거의 누수 사건: 어디선가 테스트 로그나 개발 환경 데이터베이스가 외부에 노출되거나, 코드 리뷰 중 "어? 여기 실제 고객 번호가 있네?" 하는 발견이 있었을 가능성이 높다.

  2. 프로세스 변화: 이전엔 seed 스크립트가 팀 내부 도구에 불과했는데, CI/CD 자동화, 온보딩 자동화 같은 게 추가되면서 더 많은 곳에서 사용되기 시작했다. 그러면서 "아, 이건 반드시 보안 수준을 높여야 하겠다"는 깨달음이 온 것.

  3. 규정 준수: 데이터 보호 규정(GDPR, CCPA, 개인정보보호법)이 강화되면서, "개발 환경에서도 민감 데이터 마스킹" 이 compliance 체크리스트에 정식으로 들어갔을 수 있다.

우리 팀은 이런 상황에서 "마스킹 패턴을 더 엄격하게" → "마스킹 후에도 검증을" 로 단계적으로 올려갔다. 단순히 "민감 필드 몇 개" 를 마스킹하는 게 아니라, 마스킹 자체를 전략으로 만든 셈이다.

일반론: seed 스크립트 설계의 best practice

이 fix를 통해 깨달은 점들:

  • 마스킹은 negative list가 아닌 whitelist로: "이 필드들은 마스킹해야 함" 이 아니라 "이 필드들은 안전함을 보장함" 으로 설계하는 게 낫다. 그래야 새로운 필드가 추가돼도 기본적으로 마스킹되기 때문.

  • 패턴 검증은 필수: 마스킹 규칙이 정말 작동하는지 테스트 케이스로 검증해야 한다. 정규식 하나 빠져도 민감정보가 새어난다.

  • 문서화: 어떤 필드가 왜 마스킹되는지, has_unsafe_residue 패턴이 무엇을 검증하는지 스크립트 내 주석이나 wiki에 명시해야 팀 신규 멤버들이 유지보수할 때 실수하지 않는다.

이런 식으로 seed 스크립트 같은 "작은" 도구도 보안 체크포인트로 격상시키는 게 조직 전체의 보안 문화를 만드는 첫 걸음이다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.