"오픈소스는 거인의 어깨 위에 서는 가장 빠른 방법이다."
— 리누스 토르발스 (Linus Torvalds, Linux 창시자)🎯 오늘의 학습 목표- 웹훅 URL이 인증 없이 공개되는 위험을 설명할 수 있다.
- 헤더 인증, 서명 검증, Rate Limiting 3가지 방법을 적용할 수 있다.
- GitHub 웹훅 서명 검증 코드를 작성할 수 있다.
웹훅 보안이 필요한 이유웹훅 URL을 아는 사람은 누구든 n8n에 신호를 보낼 수 있습니다. 악의적인 요청으로 워크플로우가 무한 실행되거나, 스팸 데이터가 DB에 쌓이거나, 악성 코드가 처리될 수 있어요.
방법 1 — 헤더 인증 (가장 간단, 권장)n8n Webhook 노드 설정에서 Authentication → Header Auth를 선택합니다. Header Name을 X-Secret-Token으로, Header Value를 비밀 토큰으로 설정합니다.
헤더 인증 테스트
bash
curl -X POST https://n8n.mycompany.com/webhook/my-workflow \
-H "X-Secret-Token: my_secret_token_abc123" \
-H "Content-Type: application/json" \
-d '{"name": "홍길동", "email": "hong@company.com"}'
방법 2 — 서명 검증 (GitHub, Stripe 등 연동 시)웹훅 트리거 바로 다음 Code 노드에 아래 코드를 배치합니다.
GitHub 웹훅 서명 검증 코드
javascript
const crypto = require('crypto');
const secret = process.env.GITHUB_WEBHOOK_SECRET;
const signature = $input.first().headers['x-hub-signature-256'];
const payload = JSON.stringify($input.first().body);
const expectedSignature = 'sha256=' +
crypto.createHmac('sha256', secret).update(payload).digest('hex');
if (signature !== expectedSignature) {
throw new Error('Invalid signature - 검증 실패. 요청이 차단됩니다.');
}
return $input.all();
방법 3 — Nginx Rate Limiting
nginx
# /etc/nginx/nginx.conf의 http 블록에 추가
limit_req_zone $binary_remote_addr zone=webhook:10m rate=10r/s;
# 웹훅 location에 적용
location /webhook/ {
limit_req zone=webhook burst=20 nodelay;
proxy_pass http://localhost:5678;
}
🛠️ DAY 11 실습Step 1헤더 인증 설정
- 기존 웹훅 워크플로우 1개 선택
- Webhook 노드 → Authentication → Header Auth 설정
- curl 로 인증 헤더 포함/미포함 요청 각각 테스트
Step 2GitHub 서명 검증 구현
- .env에 GITHUB_WEBHOOK_SECRET 추가
- Webhook 트리거 다음 Code 노드에 서명 검증 코드 추가
- GitHub 저장소에서 웹훅 설정 및 테스트 ping 발송
Step 3Rate Limiting 설정
- /etc/nginx/nginx.conf http 블록에 limit_req_zone 추가
- 웹훅 location에 limit_req 적용
- nginx -t → systemctl reload nginx
🚀 DAY 11 미션운영 중인 웹훅 워크플로우에 헤더 인증을 적용하고, 인증 없이 호출했을 때 거부되는 것을 확인하세요.
☑️ 미션 체크리스트- Webhook 노드 Header Auth 설정 완료
- 인증 헤더 포함 요청 → 성공 확인
- 인증 헤더 없는 요청 → 거부 확인
- Nginx Rate Limiting 설정 완료
💡 힌트: 헤더 인증 토큰은 openssl rand -hex 32 로 생성한 랜덤 문자열을 사용하세요.
🎯 성공 기준: 인증 헤더 없이 웹훅을 호출하면 401 또는 403 응답이 오는 상태