Webhook 테스터
Webhook 페이로드 분석 및 서명 검증
Webhook 테스터란?
페이로드 분석 탭은 붙여넣은 JSON을 파싱해 최상위 키 목록과 각 값의 타입(문자열/숫자/배열 길이 등)을 나열하고, action이나 event 같은 흔한 이벤트 식별 필드가 있으면 별도로 강조합니다. 서명 검증 탭은 Web Crypto API의 HMAC-SHA256으로 시크릿 키 + 원시 바디를 해시해 서명을 재계산한 뒤 입력한 수신 서명과 비교합니다. GitHub류(sha256=HEX)와 Stripe류(t=타임스탬프,v1=HEX) 두 형식을 자동 인식하는데, 특히 Stripe는 바디만 해시하는 게 아니라 "타임스탬프.바디" 문자열을 해시하도록 서명 스킴이 다르므로, 이 도구도 Stripe-Signature 헤더값을 넣으면 t 값을 읽어 body 앞에 이어붙인 뒤 재계산합니다. 비교는 문자열 길이가 다르면 즉시 false를 반환하고, 길이가 같으면 모든 문자를 XOR로 훑어 하나라도 다르면 diff가 0이 아니게 만드는 방식으로 처리해, 일치하는 접두사 길이에 비례해 응답 시간이 달라지는(===로 바로 비교할 때 발생할 수 있는) 타이밍 공격 여지를 줄입니다.
자주 묻는 질문
Webhook이란?
이벤트 발생 시 지정된 URL로 HTTP POST 요청을 전송하는 알림 메커니즘입니다. GitHub push, Stripe 결제 완료 등 외부 서비스의 이벤트를 실시간으로 수신할 때 사용합니다.
서명 검증이 필요한 이유는?
Webhook은 인터넷에 공개된 엔드포인트로 누구나 요청을 보낼 수 있어 발신자를 신뢰할 수 없습니다. 발신 서비스와 사전에 공유한 시크릿 키로 만든 HMAC 서명을 검증해야 진짜 GitHub/Stripe가 보낸 요청인지 확인할 수 있습니다.
GitHub Webhook 서명 형식은?
X-Hub-Signature-256 헤더에 sha256=HEX 형식으로 제공됩니다. HMAC 대상은 요청 원시 바디 전체입니다.
Stripe Webhook 서명은 GitHub와 어떻게 다른가요?
Stripe-Signature 헤더는 t=타임스탬프,v1=HEX,v0=HEX(구버전 호환용) 형태의 콤마 구분 목록입니다. HMAC 대상이 바디 자체가 아니라 "{타임스탬프}.{바디}" 문자열이라는 점이 GitHub와 다른 핵심 차이이며, 이 타임스탬프 결합 방식 덕분에 오래된 요청을 재전송하는 리플레이 공격도 감지할 수 있습니다.
서명 검증 로직은 구체적으로 어떻게 동작하나요?
입력한 시크릿 키를 HMAC-SHA256 키로 가져와 원시 바디(Stripe 형식이면 타임스탬프.바디)를 서명한 뒤 16진수 문자열로 변환하고, 입력된 수신 서명과 길이 우선 비교 후 전체 문자를 XOR 누적하는 방식으로 대조합니다. 단순 문자열 === 비교보다 타이밍 사이드채널에 안전한 방식입니다.
원시 바디(raw body)를 그대로 입력해야 하는 이유는?
HMAC은 바이트 단위로 계산되므로 공백 하나, 줄바꿈 하나, 키 순서 하나만 달라져도 완전히 다른 해시가 나옵니다. 웹훅 수신 서버에서 JSON.parse 후 다시 stringify한 값이나 보기 좋게 들여쓰기한 값을 붙여넣으면, 내용이 같아 보여도 서명이 절대 일치하지 않습니다. 반드시 발신자가 실제로 보낸 원본 바이트 그대로를 붙여넣어야 합니다.
시크릿 키는 서버로 전송되나요?
아니요. HMAC 계산은 브라우저 내장 Web Crypto API(crypto.subtle)로만 수행되며, 시크릿 키·바디·서명 모두 네트워크로 전송되지 않습니다.
실시간 Webhook 수신 테스트는 어떻게 하나요?
이 도구는 이미 받은 페이로드를 사후 분석하는 용도입니다. 실제로 외부 서비스가 로컬 개발 서버로 웹훅을 보내게 하려면 ngrok 같은 터널링 도구로 로컬 서버를 공개 URL로 노출한 뒤, 그 URL을 GitHub/Stripe 등의 Webhook 설정에 등록해야 합니다.