
소스 트리와 배포된 웹 앱에서 유출된 API 키, 토큰, 자격 증명을 탐지하고 Supabase/Firebase 오구성 검사와 SARIF 출력을 제공하는 CLI 스캐너입니다.
바이브 코딩한 앱이 무엇을 유출하고 있는지 — 다른 누군가가 찾아내기 전에 확인하세요.
AI 앱 빌더(Lovable, Bolt, Cursor, v0, …)는 빠르게 배포하며, 종종 데이터베이스가 활짝 열린 채로, 또는 JavaScript 번들 안에 비밀 키가 들어간 채로 배포합니다. keydra는 배포된 앱을 외부인의 시각으로 바라보거나, 배포 전에 소스 트리를 살펴보고, 무엇이 노출되었는지와 복사해서 붙여넣기만 하면 되는 수정 방법을 알려줍니다.
[!IMPORTANT] keydra는 주로 독립 실행형 CLI 도구로 실행되도록 설계되었습니다. keydra를 공개적으로 접근 가능한 서비스로 실행하면 민감한 데이터가 노출되고 보안 위험이 발생할 수 있습니다. 주의해서 사용하고 적절한 보안 통제를 구현하세요.
$ keydra scan https://my-app.example.com
█▄
▄▄ ██ ▄
██ ▄█▀ ▄█▀█▄ ██ ██ ▄████ ████▄▄▀▀█▄
████ ██▄█▀ ██▄██ ██ ██ ██ ▄█▀██
▄██ ▀█▄▄▀█▄▄▄▄▄▀██▀▄█▀███▄█▀ ▄▀█▄██
██ v1.0.0
▀▀▀
Keydra — find what your vibe-coded app is leaking.
keydra: only scan apps you own or have permission to test.
url https://my-app.example.com
2 pages · 14 files scanned · 2.1s
1 [Supabase] Supabase table "profiles" is publicly readable
│ The table can be read with the public anon key. ...
│ evidence GET /rest/v1/profiles → 206, rows visible to anonymous role: 1204
│ fix alter table public.profiles enable row level security; …
1. Go를 설치합니다. Go 1.27 이상이 필요합니다(go version으로 확인, https://go.dev/dl 에서 다운로드). Go 1.21 이상에서는 go.mod에 따라 올바른 툴체인이 자동으로 가져와집니다.
2. 코드를 받아 빌드합니다.
unzip keydra.zip && cd keydra # or: git clone <your repo> && cd keydra
go build -o bin/keydra ./cmd/keydra # or: make build
Windows (PowerShell): go build -o bin\keydra.exe ./cmd/keydra
로컬에서 빌드하기 위해 모듈 이름을 바꿀 필요는 없습니다.
저장소를 게시할 때만(또는 go install github.com/<you>/keydra/cmd/keydra@latest가
작동하길 원할 때만) github.com/drau6/keydra를 자신의 경로로 바꾸세요.
3. 첫 스캔을 실행하세요.
# source code, before you deploy: safe, no network
./bin/keydra scan --repo .
# a deployed app you own (or have written permission to test)
./bin/keydra scan https://my-app.example.com
# also follow internal links, because secrets often hide on /admin or /dashboard
./bin/keydra scan https://my-app.example.com --depth 2
# see every check Keydra performs
./bin/keydra rules
4. 선택 사항: PATH에 설치합니다.
go install ./cmd/keydra # installs to $(go env GOPATH)/bin
keydra version
5. 선택 사항: 테스트 실행. go test ./... (또는 make test).
참고: 색상은 터미널에서 자동으로 활성화됩니다. 레거시 Windows cmd.exe에서는
원시 이스케이프 코드가 표시될 수 있으니, Windows Terminal/PowerShell 또는 --no-color를 사용하세요.
큰 배너는 출력이 파이프로 전달될 때, 터미널 너비가 배너보다 좁을 때(COLUMNS), 또는 --no-banner를 사용할 때 생략됩니다.
go install github.com/drau6/keydra/cmd/keydra@latest
(저장소에서 yourname을 교체하고 푸시한 후), 또는 make build를 실행하고
bin/keydra를 사용하세요.
keydra scan <url> [flags] # scan a deployed app
keydra scan --repo <dir> [flags] # scan source before you deploy
keydra scan --list <file> [flags] # scan every URL in the file, one per line (max 50)
keydra rules # list every check
keydra <url> # shortcut for scan
--repo <dir> scan a local source tree instead of a URL (no network)
--list <file> scan a list of URLs, one per line (# comments and blank lines ignored, max 50)
--format <fmt> text | json | sarif (default text); --json is a shortcut
--no-banner one-line title instead of the ASCII-art banner
--color <mode> auto|always|never (honors NO_COLOR and FORCE_COLOR; --no-color also works)
--no-probe static analysis only, never contact discovered backends
--validate opt-in: ask each provider (one read-only request) whether a detected secret is still active
--fail-on <sev> exit 1 at/above severity: info|low|medium|high|critical|never (default high)
--depth N page levels to crawl in URL mode: 1 = only the given page (default),
2 = also its internal links, up to 5
--max-pages N maximum HTML pages to fetch in URL mode (default 20, max 200)
--sitemap also scan pages listed in /sitemap.xml
--max-files N JS files to download in URL mode (default 40)
--third-party also scan scripts hosted on other origins
--timeout 15s per-request timeout
-v show full fix snippets
종료 코드: 0은 문제 없음, 1은 --fail-on 이상의 발견 사항 존재, 2는 오류. --list 사용 시 2는 "하나 이상의 대상 스캔 실패"를 의미하기도 한다(발견 사항으로 이미 종료 코드 1이 강제된 경우는 제외).
작은 바이브 코딩 앱에 대한 저장소 스캔 결과(--no-color --no-banner 사용; 대화형 터미널에서는 배너가 ASCII 아트로 표시되고 │ 거터는 심각도에 따라 색상이 지정된다 — 빨강 critical, 주황 high, 파랑 low):
KEYDRA v1.0.0
keydra: only scan apps you own or have permission to test.
repo my-app
3 files scanned · 1ms
1 [Supabase] Supabase service/secret key exposed in client code
│ This key bypasses Row Level Security. Whoever holds it has full read/write access to the whole database.
│ evidence eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiY2RlZmdoaWowMTIzNDU2Nzg5Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0OTgxODI0OSwiZXhwIjoyMDY1Mzk0MjQ5fQ.AAAAAAAAbbbbbbbbCCCCCCCCddddddddEEEEEEEE
│ fix Rotate the key in Supabase → Project Settings → API now, remove it from the frontend and use it only from server-side code.
2 [Repository] .env is not covered by .gitignore
│ Environment files normally hold server secrets. If this file is committed, every secret in it is in your git history.
│ where .env
│ fix Add ".env*" and "!.env.example" to .gitignore. If it was already committed: `git rm --cached .env`, then rotate every key inside and purge history.
3 [Secrets] Possible unnamed secret (high-entropy string) exposed in client code
│ This value ships to every visitor's browser and can be copied by anyone.
│ evidence eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiY2RlZmdoaWowMTIzNDU2Nzg5Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0OTgxODI0OSwiZXhwIjoyMDY1Mzk0MjQ5fQ.AAAAAAAAbbbbbbbbCCCCCCCCddddddddEEEEEEEE
│ where lib/api.js
│ fix Keydra found a long, random-looking string that matches no known key format. Check whether it is a credential: if so, rotate it and move it server-side. Build artifacts such as hashes or encoded assets can be ignored.
note: Supabase configuration found in source; run `keydra scan <deployed-url>` to test the live backend
모든 발견 항목은 일치하는 값을 전체 그대로(증거), 어디에서 발견되었는지, 그리고 복사-붙여넣기 가능한 수정 방법을 보여줍니다. 따라서 스캔 보고서 하나만 있으면 바로 수정 작업을 시작할 수 있습니다. 위의 값들은 예시이며 실제 키가 아닙니다.
기본적으로는 지정한 페이지만 스캔합니다(해당 페이지의 스크립트, 지연 로딩 청크, 소스 맵 포함). 내부 링크를 따라가려면 --depth를 사용하고, 사이트가 /sitemap.xml에 나열한 페이지를 추가하려면 --sitemap을 사용하세요:
keydra scan https://my-app.example.com --depth 3 --max-pages 40
keydra scan https://my-app.example.com --sitemap
--max-pages로 상한이 설정되며, 페이지 사이에 짧은 일시 정지를 두어 속도를 조절합니다.GET 요청만 전송됩니다. 동작처럼 보이는 링크(logout, sign-out, delete, remove, unsubscribe, cancel, …)와 정적 자산은 절대 따라가지 않습니다.--depth는 HTML에서 발견된 링크를 따라갑니다. 클라이언트 렌더링 앱(단순한 <div id="root">)에는 링크가 거의 없으며, 해당 앱의 라우트는 JavaScript 번들에 존재하는데 Keydra는 이미 이를 읽습니다. --depth가 링크를 찾지 못하면 안내가 표시되며, 다음으로 시도할 것은 --sitemap입니다. 서버 렌더링 사이트(Next.js SSR, Astro, Rails, PHP)가 가장 큰 이점을 얻습니다.대상 URL을 일반 텍스트 파일에 한 줄에 하나씩 넣으세요:
# staging and production for my-app
https://staging.my-app.example.com
https://www.my-app.example.com
https://admin.my-app.example.com
빈 줄과 # 주석 줄은 무시됩니다. 그런 다음 한 번에 모두 스캔합니다:
keydra scan --list urls.txt # text report, one section per target
keydra scan --list urls.txt --format json > report.json
keydra scan --list urls.txt --format sarif > report.sarif
keydra scan --list urls.txt --validate # also live-check the secrets it finds
일괄 모드의 작동 방식: