본문 바로가기
서비스 웹 서비스 개발 앱 개발 AI 알고리즘 개발 AI 컨설팅 AI 마케팅 프로젝트 인사이트 회사소개 고객게시판
보안 엔지니어링 8 MIN READ

웹훅 URL을 아는 사람이 누구나 호출할 수 있다면: 서명 검증과 재전송 방어

웹훅 주소를 비밀로 숨기는 것만으로는 보안이 되지 않습니다. 원본 본문 서명 검증, 시각·이벤트 ID 확인, 비밀 키 교체와 테넌트 연결을 설계합니다.

Category
보안 엔지니어링
Published
Read
8분
Author
네이처프랙탈
웹훅 URL을 아는 사람이 누구나 호출할 수 있다면: 서명 검증과 재전송 방어 대표 이미지

결제 완료, 배송 상태, 코드 저장소 이벤트를 받기 위해 웹훅 URL을 열었습니다. 주소를 복잡하게 만들었으니 안전할까요? 주소가 로그나 설정 파일에서 새면 누구나 POST 요청을 보낼 수 있습니다. 공격자가 “결제 완료”처럼 생긴 JSON을 만들어 보내도, 서버가 출처를 확인하지 않으면 실제 업무 상태를 바꿀 수 있습니다. 웹훅 수신은 단순한 API 공개가 아니라 외부 시스템의 이벤트가 내부 결정을 바꾸는 신뢰 경계입니다.

첫 관문은 공급자가 서명한 원본 바이트

많은 공급자는 공유 비밀 키로 요청 본문에 대한 HMAC 서명을 계산해 헤더로 보냅니다. 수신 서버는 같은 비밀로 원본 본문 바이트의 서명을 다시 계산하고 안전한 비교 함수로 검증합니다. JSON을 먼저 파싱하고 다시 직렬화하면 공백이나 필드 순서가 바뀌어 서명이 달라질 수 있습니다. 따라서 미들웨어가 본문을 변환하기 전에 원본 바이트를 확보해야 합니다. GitHub 웹훅 서명 검증 문서는 원본 페이로드 기반 HMAC과 일정 시간 비교의 중요성을 안내합니다.

서명 방식은 공급자마다 다릅니다. 헤더 이름, 알고리즘, 인코딩, 서명 대상에 시각이 포함되는지 확인해야 합니다. 예시 코드를 다른 공급자에 그대로 복사하면 성공하는 것처럼 보여도 실제로는 중요한 검사를 빠뜨릴 수 있습니다. 비밀 키는 코드와 저장소에 넣지 않고 안전한 비밀 관리 경로에서 읽습니다. 키 교체 기간에는 기존 키와 새 키를 제한적으로 함께 허용하고, 어느 키로 검증했는지 기록한 뒤 옛 키를 폐기합니다.

외부 웹훅의 원본 본문과 서명을 검증해 위조된 요청을 차단하는 관문
파싱하거나 저장하기 전에 공급자가 정한 방식으로 서명을 확인합니다.

정상 서명도 오래된 요청일 수 있다

공격자가 유효하게 서명된 요청을 가로채 다시 보낸다면 서명만으로는 새 이벤트인지 구분하지 못합니다. 공급자가 서명에 시각을 포함한다면 허용 가능한 시간 창을 검증하고 서버 시각을 정확히 유지합니다. 공급자가 제공하는 고유 이벤트 ID도 저장해 이미 처리한 이벤트인지 확인합니다. 두 기능은 목적이 다릅니다. 시각 검사는 오래된 요청의 재사용을 막고, 이벤트 ID는 정상 재전달이나 짧은 시간의 중복 호출이 업무를 두 번 실행하지 않게 합니다. 외부에서 일부러 다시 보내는 기능이 있을 수 있으므로 정상 재처리 절차와 보안 검사도 구분해야 합니다.

수신한 이벤트가 어느 고객의 것인지도 서명 결과만 보고 결정해서는 안 됩니다. 공급자 계정·엔드포인트 비밀·이벤트의 소유자 식별자를 서버에 저장한 연결 정보와 대조합니다. 다중 테넌트 서비스에서 “유효한 공급자 이벤트”와 “이 고객에게 적용할 수 있는 이벤트”는 별도 검증입니다. 이벤트 속 고객 ID 하나만 믿고 다른 테넌트 데이터를 수정하는 구현은 위험합니다.

서명 검증 실패를 운영에서 빠르게 구별하는 방법도 준비합니다. 진짜 공격 시도뿐 아니라 잘못된 비밀 키 배포, 프록시가 본문을 변형한 경우, 공급자의 재시도 시각이 허용 창을 벗어난 경우도 실패로 보입니다. 실패 요청의 원문 전체를 보관하기보다 본문 길이, 해시, 이벤트 헤더, 수신 시각, 실패 이유를 기록하면 원인을 조사하면서 민감 정보 노출을 줄일 수 있습니다. 공급자별 검증 방식과 키 버전을 설정으로 분리해야 여러 연동이 서로의 보안 규칙을 덮어쓰지 않습니다.

검증과 실제 처리를 분리한다

웹훅 핸들러는 본문 크기 제한, 서명 검증, 시각·이벤트 ID 확인, 기본 스키마 점검을 한 뒤 안전하게 작업을 저장하고 빠르게 응답하는 편이 좋습니다. 무거운 업무 처리는 별도 작업자가 맡습니다. 그러나 응답을 먼저 보내고 이벤트를 저장하지 못하면 공급자는 성공으로 판단하는데 우리 시스템은 이벤트를 잃습니다. 저장이 확정된 뒤 성공 응답을 보내야 합니다. GitHub의 운영 권고도 비밀 키 검증과 HTTPS 사용을 강조합니다.

서명 확인, 시각 검증, 이벤트 중복 확인, 테넌트 연결, 비동기 처리의 순서
유효한 서명만으로 재전송과 권한 범위까지 해결되지는 않습니다.

테스트에는 정상 서명뿐 아니라 본문 한 글자 변경, 잘못된 키, 오래된 시각, 같은 이벤트 ID의 재호출, 다른 고객 계정의 이벤트를 포함합니다. 실패 시에는 민감한 원문을 로그에 그대로 남기지 않고 공급자·요청 ID·검증 실패 종류만 기록합니다. URL을 숨기는 것은 보조 수단일 뿐입니다. 서명·신선도·중복·테넌트 권한을 순서대로 확인해야 웹훅이 신뢰 가능한 입력 경로가 됩니다.

#웹훅보안 #서명검증 #HMAC #재전송공격 #Webhook #API보안 #이벤트처리 #시스템연동 #비밀키관리 #네이처프랙탈

API 보안 시스템 통합

/ 다음 단계

이런 문제, 직접 겪고 계신가요?

글로 정리한 방법을 실제 환경에 맞춰 적용하는 일까지 함께 하겠습니다.

영업일 기준 3일 이내 회신 · 상담 및 범위 견적 무료