
보안 연구 랩: CVE-2025-61584 (GHSA-9g7x-737f-5xpc) 재현 — pull_request_target 워크플로우(.github/workflows/pr.yml)에서 github.head_ref를 통한 명령어 주입
자동화된 연구 산출물 — 업스트림 프로젝트가 아님.
이 저장소는 Université Laval의 석사 논문을 위해 게시된 GitHub Actions 워크플로우 취약점 재현을 목적으로 자동화된 하네스가 구축한 일회용 실험실입니다. 이는 커밋
b0b1a1538aeb1991b5bc13dfe4e18e686913b12e(2025-04-26) 시점의serverless-dns/serverless-dns를 그대로 스냅샷한 것이며, 해당 프로젝트의 자체 라이선스에 따라 재배포되며, 해당 라이선스 파일은 이 스냅샷에 변경 없이 포함되어 있습니다.업스트림 프로젝트는 이와 관여하지 않으며, 결코 공격 대상이 아닙니다. 여기서 연구된 취약점은 이미 공개된 것입니다. 이 저장소의 모든 시크릿과 변수는 무작위로 생성된 더미 값입니다 — 실제 자격 증명은 존재하지 않습니다. 액션 참조와 러너 이미지는 2025-04-26에 확인된 값으로 고정되어 있습니다. 스냅샷에 적용된 모든 변경 사항은 하네스 출력의
pinning.md를 참조하세요.질문 또는 이의 제기: [email protected]
_serverless-dns_는 Pi-Hole 유사 콘텐츠 차단, 서버리스, 스텁 DNS-over-HTTPS(DoH) 및 DNS-over-TLS(DoT) 리졸버입니다. Cloudflare Workers, Deno Deploy, Fastly Compute@Edge, Fly.io에서 즉시 실행됩니다. 이러한 모든 서비스의 무료 티어는 월간 10~20개 기기의 DNS 트래픽을 충당하기에 충분합니다.
RethinkDNS는 다음 엔드포인트에서 프로덕션 환경에 serverless-dns를 실행합니다:
| 클라우드 플랫폼 | 서버 위치 | 프로토콜 | 도메인 | 사용법 |
|---|---|---|---|---|
| ⛅ Cloudflare Workers | 280+ (ping) | DoH | sky.rethinkdns.com | 구성 |
| 🦕 Deno Deploy | 30+ (ping) | DoH | 비공개 베타 | |
| ⏱️ Fastly Compute@Edge | 80+ (ping) | DoH | 비공개 베타 | |
| 🪂 Fly.io | 30+ (ping) | DoH 및 DoT | max.rethinkdns.com | 구성 |
서버 측 처리 시간은 0밀리초(ms)에서 2ms(중앙값)이며, 종단 간 지연 시간(지역 및 네트워크에 따라 다름)은 10ms에서 30ms(중앙값)입니다.
Fly.io의 Rethink DNS 리졸버는 FOSS United의 후원을 받습니다.
Cloudflare Workers는 serverless-dns를 설정하기 가장 쉬운 플랫폼입니다:
단계별 지침은 다음을 참조하세요:
| 플랫폼 | 난이도 | 런타임 | 문서 |
|---|---|---|---|
| ⛅ Cloudflare | 쉬움 | v8 Isolates | Cloudflare Workers에서 호스팅 |
| 🦕 Deno.com | 보통 | Deno Isolates | Deno.com에서 호스팅 |
| ⏱️ Fastly Compute@Edge | 쉬움 | Fastly JS | Fastly Compute@Edge에서 호스팅 |
| 🪂 Fly.io | 어려움 | Node MicroVM | Fly.io에서 호스팅 |
블록리스트를 설정하려면 브라우저에서 https://<my-domain>.tld/configure를 방문하세요(RethinkDNS의 configure 페이지와 유사한 화면이 로드되어야 합니다).
도움이나 지원이 필요하면 이슈를 열거나 패치를 제출하세요.
코드:
# 작업 디렉토리로 이동
cd /my/work/dir
# 이 저장소 클론
git clone https://github.com/serverless-dns/serverless-dns.git
# serverless-dns로 이동
cd ./serverless-dns
Node:
# 필요한 경우 nvm을 통해 node v22+ 설치
# https://github.com/nvm-sh/nvm#installing-and-updating
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
nvm install --lts
# 의존성 다운로드
npm i
# (선택 사항) 의존성 업데이트
npm update
# node에서 serverless-dns 실행
./run n
# clinicjs.org 프로파일러 실행
./run n [cpu|fn|mem]
Deno:
# deno.land v2+ 설치
# https://github.com/denoland/deno/#install
curl -fsSL https://deno.land/install.sh | sh
# deno에서 serverless-dns 실행
./run d
Fastly:
# 필요한 경우 nvm을 통해 node v22+ 설치
# Fastly CLI 설치
# https://developer.fastly.com/learning/tools/cli
# Fastly Compute@Edge에서 serverless-dns 실행
./run f
Wrangler:
# Cloudflare Workers (cli) aka Wrangler 설치
# https://developers.cloudflare.com/workers/cli-wrangler/install-update
npm i wrangler --save-dev
# Cloudflare Workers (cli)에서 serverless-dns 실행
# 먼저 Wrangler를 설정해야 합니다:
# https://developers.cloudflare.com/workers/cli-wrangler/authentication
./run w
# Chrome DevTools로 wrangler 프로파일링
# blog.cloudflare.com/profiling-your-workers-with-wrangler
이 저장소의 커밋은 Google JavaScript 스타일 가이드(.eslintrc.cjs 참조)를 준수합니다.
.js 파일에 린터(eslint)와 포맷터(prettier)를 실행하는 git pre-commit 훅이 있습니다. 이 훅을 우회하려면 git commit --no-verify를 사용하세요.
풀 리퀘스트도 코드 스타일 위반 여부를 확인하며 가능한 경우 자동으로 수정됩니다.
기본값을 조정해야 하는 경우 env.js를 구성하세요.
Cloudflare Workers의 경우 wrangler.toml에서 환경 변수를 설정하세요.
Fastly Compute@Edge의 경우 fastly.toml에서 환경 변수를 설정하세요.
src/server-[node|workers|deno] <-> doh.js <-> plugin.jsplugin.js 흐름: user-op.js -> cache-resolver.js -> cc.js -> resolver.jsserverless-dns는 DoH와 DoT 모두에 대해 영숫자 베어러 토큰 인증을 지원합니다. 토큰의 경우 msg-key(시크릿)를 사용하여 hex(hmac-sha256(msg-key|domain.tld), msg)의 출력을 ACCESS_KEYS 환경 변수에 csv 형식으로 추가하세요. 참고: msg는 현재 sdns-public-auth-info로 고정되어 있습니다.
msg-key를 블록스탬프 끝에 다음과 같이 배치합니다:
1:1:4AIggAABEGAgAA:<msg-key> (여기서 1은 버전, 1:4AIggAABEGAgAA
는 블록스탬프, <msg-key>는 인증 시크릿, :는 구분자입니다).msg-key를 블록스탬프가 포함된 SNI(도메인 이름) 끝에 배치합니다:
1-4abcbaaaaeigaiaa-<msg-key> (여기서 1은 버전, 4abcbaaaaeigaiaa
는 블록스탬프, <msg-key>는 인증 시크릿, -는 구분자입니다).DoT에서도 인증을 사용하려면 서브도메인은 총 63자로 제한되므로 msg-key를 더 짧게(8~24자) 유지하세요.
다음과 같이 max.rethinkdns.com에서 포크에 대한 액세스 키를 생성할 수 있습니다:
msgkey="ShortAlphanumericSecret"
domain="my-serverless-dns-domain.tld"
curl 'https://max.rethinkdns.com/genaccesskey?key='"$msgkey"'&dom='"$domain"
# 출력
# {"accesskey":["my-serverless-dns-domain.tld|deadbeefd3adb33fa2bb33fd3eadf084beef3b152beefdead49bbb2b33fdead83d3adbeefdeadb33f"],"context":"sdns-public-auth-info"}
serverless-dns는 Cloudflare Logpush를 통해 로그를 업로드하도록 설정할 수 있습니다.