curl -L -o webhook-sig-verifier.skill "https://aiskillstore.io/v1/agent/skills/019bba5f-e8e5-4deb-856a-704ba84c3a96/download?platform=ClaudeCode"
{
"tool": "download_skill",
"arguments": {
"skill_id": "019bba5f-e8e5-4deb-856a-704ba84c3a96",
"platform": "ClaudeCode"
}
}
{
"mcpServers": {
"skill-store": {
"url": "https://aiskillstore.io/mcp/"
}
}
}
Webhook signature verifier for 15+ providers (Stripe, GitHub, Slack, Toss Payments, Kakao Pay, Naver Pay, Iamport and more). HMAC-SHA256/SHA1/SHA512, timing-safe comparison, replay attack defense. Zero external dependencies.
Compatible Platforms any
Findings: ["메타데이터 경고: 권장 필드 없음: 'requirements' (SKILL.md v2 권장)", "메타데이터 경고: 권장 필드 없음: 'changelog' (SKILL.md v2 권장)"]
✅ No security risks found.
AI Review Stage
1. **Permissions Alignment**: 메타데이터에 선언된 `network: false`, `filesystem: false`, `subprocess: false` 권한과 제공된 `main.py` 코드 스니펫 및 'Zero external dependencies' 설명이 일치합니다. 외부 통신이나 파일 시스템 접근, 서브프로세스 실행 코드가 발견되지 않았습니다. 2. **Malicious Code**: 제공된 코드 스니펫에서 데이터 탈취, 시스템 파괴, 난독화 등 악의적인 목적의 코드는 발견되지 않았습니다. `hmac`, `hashlib` 등 표준 라이브러리를 사용하여 서명 검증 로직을 구현하고 있습니다. 3. **Undeclared External Communication**: `network: false`로 선언되었으며, 코드에서 `requests`, `urllib`, `socket` 등 외부 통신을 수행하는 모듈 사용 흔적이 없습니다. 4. **Unauthorized Data Collection/Transmission**: 스킬의 목적상 `payload`, `headers`, `secret`과 같은 사용자 데이터를 입력받지만, 이를 무단으로 수집하거나 외부로 전송하는 메커니즘이 없습니다. 출력 스키마는 검증 결과 및 관련 메타데이터만을 포함합니다. 5. **Code Quality**: 코드 구조가 명확하고, 주석 및 docstring이 잘 작성되어 있습니다. 다양한 웹훅 공급자를 지원하며, 리플레이 공격 방어 및 타이밍 안전 비교 등 보안 모범 사례를 포함하고 있습니다. `input_schema`, `output_schema`, `examples` 등 메타데이터가 매우 상세하고 잘 정의되어 있어 스킬의 기능과 사용법을 명확히 이해할 수 있습니다. 6. **Static Analysis**: 제공된 정적 분석 결과도 'approved' 상태이며, `red_flags_found`, `obfuscation_warnings`, `forbidden_exec_files_found` 항목이 모두 비어 있어 안전성을 뒷받침합니다. 종합적으로 판단할 때, 이 스킬은 보안적으로 안전하며 명확한 목적을 가지고 잘 구현된 것으로 보입니다.
Representative input/output examples for this skill. Agents can use these to understand how to invoke the skill and what output to expect.
Stripe의 Stripe-Signature 헤더를 검증합니다.
{
"action": "verify",
"headers": {
"Stripe-Signature": "t=1234567890,v1=abc123def456,v0=oldversion"
},
"payload": "{\"id\":\"evt_test\",\"type\":\"payment_intent.succeeded\"}",
"provider": "stripe",
"secret": "whsec_test_secret_key"
}
{
"action": "verify",
"error": {
"code": "INVALID_SIGNATURE",
"fix_hint": {
"action": "\uc2dc\ud06c\ub9bf \ud0a4\uc640 raw payload\ub97c \ud655\uc778\ud558\uc138\uc694. Stripe\ub294 JSON \uc7ac\uc9c1\ub82c\ud654 \uc2dc \uc11c\uba85 \ubd88\uc77c\uce58\uac00 \ubc1c\uc0dd\ud569\ub2c8\ub2e4.",
"doc_ref": "https://stripe.com/docs/webhooks/signatures",
"example": "raw body\ub97c \uadf8\ub300\ub85c \uc804\ub2ec\ud558\uc138\uc694 (JSON.parse \ud6c4 \uc7ac\uc9c1\ub82c\ud654 \uae08\uc9c0)",
"summary": "\uc11c\uba85\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4."
},
"message": "Stripe signature verification failed: computed HMAC does not match."
},
"meta": {
"algorithm": "HMAC-SHA256",
"replay_protected": true,
"timestamp_age_seconds": 999999
},
"provider": "stripe",
"valid": false
}
GitHub의 X-Hub-Signature-256 헤더를 검증합니다.
{
"action": "verify",
"headers": {
"X-GitHub-Event": "pull_request",
"X-Hub-Signature-256": "sha256=abc123"
},
"payload": "{\"action\":\"opened\",\"pull_request\":{\"number\":1}}",
"provider": "github",
"secret": "github_webhook_secret"
}
{
"action": "verify",
"error": {
"code": "INVALID_SIGNATURE",
"fix_hint": {
"action": "\uc2dc\ud06c\ub9bf \ud0a4\uc640 raw payload\ub97c \ud655\uc778\ud558\uc138\uc694.",
"doc_ref": "https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries",
"example": "X-Hub-Signature-256: sha256=\u003cHMAC-SHA256(secret, payload)\u003e",
"summary": "\uc11c\uba85\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4."
},
"message": "GitHub signature verification failed."
},
"meta": {
"algorithm": "HMAC-SHA256",
"replay_protected": false
},
"provider": "github",
"valid": false
}
Slack의 X-Slack-Signature 헤더를 검증합니다.
{
"action": "verify",
"headers": {
"X-Slack-Request-Timestamp": "1234567890",
"X-Slack-Signature": "v0=abc123"
},
"payload": "payload=test%3Ddata",
"provider": "slack",
"secret": "slack_signing_secret"
}
{
"action": "verify",
"error": {
"code": "INVALID_SIGNATURE",
"fix_hint": {
"action": "signing secret\uacfc canonical string v0:timestamp:body\ub97c \ud655\uc778\ud558\uc138\uc694.",
"doc_ref": "https://api.slack.com/authentication/verifying-requests-from-slack",
"example": "v0:timestamp:raw_body \ud615\ud0dc\uc758 canonical string \uc0ac\uc6a9",
"summary": "Slack \uc11c\uba85\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4."
},
"message": "Slack signature verification failed."
},
"meta": {
"algorithm": "HMAC-SHA256",
"replay_protected": true,
"timestamp_age_seconds": 999999
},
"provider": "slack",
"valid": false
}
Toss Payments의 Authorization Basic 헤더 방식으로 검증합니다.
{
"action": "verify",
"headers": {
"Authorization": "Basic dGVzdF9za19hYmMxMjM6"
},
"payload": "{\"eventType\":\"PAYMENT_STATUS_CHANGED\",\"data\":{\"paymentKey\":\"test_pk_123\"}}",
"provider": "toss",
"secret": "test_sk_abc123"
}
{
"action": "verify",
"meta": {
"algorithm": "Basic-Auth",
"replay_protected": false
},
"provider": "toss",
"valid": true
}
Kakao Pay의 Admin-Key 기반 검증을 수행합니다.
{
"action": "verify",
"headers": {
"Authorization": "KakaoAK mykakaoadminkey123"
},
"payload": "{\"payment_method_type\":\"MONEY\",\"item_name\":\"test_item\"}",
"provider": "kakaopay",
"secret": "mykakaoadminkey123"
}
{
"action": "verify",
"meta": {
"algorithm": "Admin-Key-Match",
"replay_protected": false
},
"provider": "kakaopay",
"valid": true
}
timestamp가 설정된 허용 범위를 초과할 때 replay attack으로 판정합니다.
{
"action": "verify",
"current_timestamp": 9999999999,
"headers": {
"Stripe-Signature": "t=1000000000,v1=somesig"
},
"payload": "{\"id\":\"evt_old\"}",
"provider": "stripe",
"secret": "whsec_secret",
"timestamp_tolerance_seconds": 300
}
{
"action": "verify",
"error": {
"code": "REPLAY_ATTACK",
"fix_hint": {
"action": "\uc694\uccad timestamp\ub97c \ud655\uc778\ud558\uc138\uc694. \uc624\ub798\ub41c \uc694\uccad\uc740 \uc7ac\uc804\uc1a1 \uacf5\uaca9\uc77c \uc218 \uc788\uc2b5\ub2c8\ub2e4.",
"doc_ref": "https://stripe.com/docs/webhooks/signatures#replay-attacks",
"example": "timestamp_tolerance_seconds\ub97c 300 (5\ubd84) \uc774\ud558\ub85c \uc124\uc815\ud558\uc138\uc694.",
"summary": "Timestamp\uac00 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4 \u2014 replay attack \uac00\ub2a5\uc131\uc774 \uc788\uc2b5\ub2c8\ub2e4."
},
"message": "Timestamp too old: 8999999999s ago (tolerance: 300s). Possible replay attack."
},
"meta": {
"algorithm": "HMAC-SHA256",
"replay_protected": true,
"timestamp_age_seconds": 8999999999
},
"provider": "stripe",
"valid": false
}
헤더에서 webhook 공급자를 자동으로 감지합니다.
{
"action": "detect_provider",
"headers": {
"X-GitHub-Event": "push",
"X-Hub-Signature-256": "sha256=abc"
}
}
{
"action": "detect_provider",
"detected_provider": "github",
"meta": {
"algorithm": "HMAC-SHA256"
}
}
지원하는 모든 webhook 공급자와 서명 방식을 조회합니다.
{
"action": "list_providers"
}
{
"action": "list_providers",
"providers": [
{
"algorithm": "HMAC-SHA256",
"category": "global_payment",
"header_pattern": "Stripe-Signature",
"name": "stripe",
"replay_protection": true
},
{
"algorithm": "HMAC-SHA256",
"category": "devtools",
"header_pattern": "X-Hub-Signature-256",
"name": "github",
"replay_protection": false
},
{
"algorithm": "Basic-Auth",
"category": "korean_payment",
"header_pattern": "Authorization",
"name": "toss",
"replay_protection": false
},
{
"algorithm": "Admin-Key-Match",
"category": "korean_payment",
"header_pattern": "Authorization",
"name": "kakaopay",
"replay_protection": false
}
]
}
All examples are also available via the agent API:
/v1/agent/skills/019bba5f-e8e5-4deb-856a-704ba84c3a96/schema
No reviews yet. Be the first to leave one!