문서
모니터링 및 변경 알림
AppSafe는 인증된 사이트의 모든 스캔을 이전 스캔과 비교해 무엇이 바뀌었는지 알려 줍니다. 예약 스캔이나 배포 시 재스캔과 함께 사용하면, 이메일, Slack, Discord 또는 서명된 웹훅 알림을 통한 지속적인 모니터링이 됩니다.
변경 알림은 Pro, Agency, Team 플랜에 포함되어 있습니다. 예약 스캔은 Pro와 Agency에서는 매일 또는 매주, Team에서는 매시간 실행됩니다.
AppSafe가 비교하는 항목
- 새 발견 항목과 해결된 발견 항목.
- 추가, 제거 또는 약화된 보안 헤더(예: 제거된 Content-Security-Policy나 짧아진 HSTS max-age).
- TLS 인증서 교체, 그리고 인증서 만료 14일 전과 3일 전의 만료 경고.
- 새 서드파티 스크립트 도메인과 Subresource Integrity(SRI)가 없는 외부 스크립트.
- Certificate Transparency 로그(crt.sh)에 나타난 내 도메인의 새 서브도메인과, CNAME이 호스팅 서비스의 삭제된 리소스를 가리키는 서브도메인. 이 검사는 수동 DNS 조회만 사용합니다.
- SPF, DMARC, CAA, MX 레코드 변경.
알림은 예약 스캔과 배포 시 스캔에서 문제마다 한 번 전송됩니다. 그대로 남아 있는 문제는 다음 스캔에서 다시 알리지 않습니다. 문제가 사라졌다가 다시 나타나면 다시 알림을 받습니다.
알림 설정하기
대시보드에서 인증된 사이트를 열고 모니터링 및 알림에서 채널을 추가하세요. 각 채널에는 최소 심각도와 테스트 알림 보내기 버튼이 있습니다.
- 이메일: 모든 이메일 주소. 알림은 계정 언어로 작성됩니다.
- Slack: Slack 앱의 Incoming Webhook URL(https://hooks.slack.com/services/…).
- Discord: 채널 웹후크 URL(서버 설정 → 연동 → 웹후크).
- 웹훅: 모든 https 엔드포인트. AppSafe는 아래 JSON 페이로드를 POST로 보내며, 채널을 만들 때 한 번만 표시되는 시크릿으로 서명합니다.
웹훅 페이로드
일반 웹훅은 이 JSON을 받습니다(Content-Type: application/json). 테스트 알림은 monitoring.test 이벤트를 사용하며 scan은 null로 설정됩니다.
{
"event": "monitoring.changes",
"deliveryId": "5f2c9a0e41b7d3a8c6e1f0b2",
"createdAt": "2026-10-26T12:00:00.000Z",
"site": {
"domain": "myapp.com"
},
"scan": {
"id": "3f1c2b9e-1111-4222-8333-944455556666",
"grade": "C",
"score": 67,
"reportUrl": "https://appsafe.dev/report/…"
},
"summary": "2 changes on myapp.com",
"changes": [
{
"type": "header_removed",
"severity": "high",
"subject": "content-security-policy",
"message": "content-security-policy header removed"
},
{
"type": "finding_new",
"severity": "critical",
"subject": "baas-supabase-table-readable",
"title": "Supabase tables readable without logging in",
"message": "New issue: Supabase tables readable without logging in"
}
]
}변경 유형: finding_new, finding_resolved, header_added, header_removed, header_weakened, header_changed, tls_changed, tls_expiring(days 포함), script_domain_new, sri_missing, subdomain_new, subdomain_dangling, dns_changed. 심각도: low, medium, high, critical. 알림에는 악화된 변경만 포함되므로, finding_resolved와 header_added는 대시보드와 리포트에는 표시되지만 그 자체로는 알림을 보내지 않습니다.
서명 검증하기
모든 웹훅 요청에는 X-AppSafe-Signature 헤더가 있습니다. 타임스탬프, 점, 원본 요청 본문을 이어 붙인 값에 대해 채널 시크릿으로 HMAC-SHA256을 계산하고, 상수 시간 비교로 v1과 비교하세요. 타임스탬프가 5분보다 오래된 요청은 거부하세요.
X-AppSafe-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
X-AppSafe-Event: monitoring.changes | monitoring.testimport { createHmac, timingSafeEqual } from "node:crypto";
// header: the X-AppSafe-Signature value, e.g. "t=1761480000,v1=5d41…"
// body: the raw request body (string), before JSON.parse
export function verifyAppSafeSignature(secret, header, body) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const timestamp = Number(parts.t);
if (!parts.v1 || Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const expected = createHmac("sha256", secret).update(`${timestamp}.${body}`).digest();
const given = Buffer.from(parts.v1, "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
}AppSafe는 각 알림을 한 번만 보내고 재시도하지 않습니다. 8초 이내에 2xx 상태로 응답하세요. 대시보드에 채널의 마지막 전송 오류가 표시됩니다.
알림에 절대 포함되지 않는 것
알림 페이로드에는 변경 유형, 심각도, 발견 항목 제목, 헤더 이름, 스크립트 및 서브도메인 호스트 이름, 리포트 링크가 포함됩니다. 발견 항목의 세부 정보, 시크릿(가려진 것도 포함), 개인 데이터는 절대 포함되지 않습니다.