Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

64 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

HTTP Analyzer

HTTP Analyzer๋Š” ๋ธŒ๋ผ์šฐ์ €/ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐœ์ƒํ•œ HTTP ํŠธ๋ž˜ํ”ฝ์„ ์บก์ฒ˜ํ•˜๊ณ , ์š”์ฒญ/์‘๋‹ต์„ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜๋ฉด์„œ ๋ณด์•ˆ ๊ด€์ ์—์„œ ๋น ๋ฅด๊ฒŒ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“  ๋กœ์ปฌ ๋ถ„์„ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ๋Š” ์„ธ ๊ฐ€์ง€ ์ถ•์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

  • mitmproxy๋กœ ์‹ค์‹œ๊ฐ„ ํŠธ๋ž˜ํ”ฝ์„ ๊ฐ€๋กœ์ฑ„๊ณ  ์ˆ˜์ •/๊ด€์ฐฐ
  • Node + Express ์„œ๋ฒ„๋กœ ์บก์ฒ˜ ์ƒํƒœ, HAR ๋ถ„์„, ๋ฆฌํ”Œ๋ ˆ์ด, Cloudflare R2 ํŒŒ์ผ ์ €์žฅ ์ฒ˜๋ฆฌ
  • React + Vite ํ”„๋ŸฐํŠธ์—”๋“œ๋กœ ์š”์ฒญ/์‘๋‹ต ํ™•์ธ, ๋ณด์•ˆ ํŒจํ„ด ๋ถ„์„, ๋ฆฌํฌํŠธ ์ถœ๋ ฅ

ํ•ต์‹ฌ ๊ธฐ๋Šฅ

  • ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด
  • ์‚ฌ์ด๋“œ ๋ฉ”๋‰ด ๊ธฐ๋ฐ˜ ๊ธฐ๋Šฅ ๋ถ„๋ฆฌ(Overview, Capture, Findings, HAR, Recent Data)
  • ์‹ค์‹œ๊ฐ„ HTTP ์š”์ฒญ/์‘๋‹ต ์บก์ฒ˜
  • Playwright ๋ธŒ๋ผ์šฐ์ € ๊ธฐ๋ฐ˜ ๊ฐ™์€ ๋„๋ฉ”์ธ ํฌ๋กค๋ง ์บก์ฒ˜
  • ํฌ๋กค๋ง ์™„๋ฃŒ ๋˜๋Š” idle ์ƒํƒœ ๊ฐ์ง€ ์‹œ ์ž๋™ ์บก์ฒ˜ ์ค‘์ง€
  • SQLMap ๊ธฐ๋ฐ˜ SQL Injection ํ›„๋ณด ์—”๋“œํฌ์ธํŠธ ์ ๊ฒ€ ๋ฉ”๋‰ด
  • OpenAI API ๊ธฐ๋ฐ˜ ํฌ๋กค๋ง ์™„๋ฃŒ Summary ์ƒ์„ฑ
  • ์š”์ฒญ/์‘๋‹ต ํ—ค๋” ๋ฐ ๋ฐ”๋”” ํ™•์ธ
  • ํŠน์ • ์š”์ฒญ ์žฌ์ „์†ก(Replay)
  • ์บก์ฒ˜ ํ๋ฆ„ ๊ธฐ๋ฐ˜ Mermaid ๋‹ค์ด์–ด๊ทธ๋žจ ์ƒ์„ฑ
  • HAR ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฐ ์„ฑ๋Šฅ/ํ˜ธ์ŠคํŠธ/์ƒํƒœ์ฝ”๋“œ ๋ถ„์„
  • ๋ณด์•ˆ ํŒจํ„ด ํƒ์ง€ ๋ฐ OWASP Top 10 ๊ธฐ์ค€ ์š”์•ฝ
  • ์—”๋“œํฌ์ธํŠธ ์šฐ์„ ์ˆœ์œ„ ์ •๋ฆฌ
  • Before / After ๋น„๊ต์šฉ Diff
  • HTML / PDF / JSON / Markdown / CSV ๋ฆฌํฌํŠธ ์ถœ๋ ฅ
  • ์บก์ฒ˜ ์ด๋ฒคํŠธ์™€ ์ ๊ฒ€ ์ด๋ ฅ์„ Cloudflare R2 JSON ํŒŒ์ผ๋กœ ์ €์žฅ
  • ์—…๋กœ๋“œ๋œ HAR ์›๋ณธ ํŒŒ์ผ์„ Cloudflare R2์— ์ €์žฅ

ํ˜„์žฌ UI์—์„œ ์ง€์›ํ•˜๋Š” ๋ณด์•ˆ ๋ถ„์„

ํ”„๋ŸฐํŠธ์—์„œ ์บก์ฒ˜๋œ ์š”์ฒญ/์‘๋‹ต์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์•„๋ž˜ ํ•ญ๋ชฉ๋“ค์„ ํƒ์ง€ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฏผ๊ฐ์ •๋ณด URL ๋…ธ์ถœ
  • ์‘๋‹ต ๋ณธ๋ฌธ ๋น„๋ฐ€๊ฐ’ ๋…ธ์ถœ
  • ์š”์ฒญ ๋ณธ๋ฌธ ๋ฏผ๊ฐ์ •๋ณด ํฌํ•จ
  • ์œ„ํ—˜ํ•œ CORS ์„ค์ •
  • ์„ธ์…˜ ์ฟ ํ‚ค ์†์„ฑ ๋ˆ„๋ฝ(HttpOnly, Secure, SameSite)
  • ๋ณด์•ˆ ํ—ค๋” ๋ˆ„๋ฝ(CSP, HSTS, X-Frame-Options, Referrer-Policy, X-Content-Type-Options)
  • ์„œ๋ฒ„ ๋ฐฐ๋„ˆ/๋ฒ„์ „ ๋…ธ์ถœ
  • ์ŠคํƒํŠธ๋ ˆ์ด์Šค/์ƒ์„ธ ์˜ค๋ฅ˜ ๋…ธ์ถœ
  • ๋””๋ ‰ํ„ฐ๋ฆฌ ์ธ๋ฑ์‹ฑ ๋…ธ์ถœ
  • ์บ์‹œ ์ •์ฑ… ๋ถ€์กฑ
  • SQLi / XSS / SSRF / Path Traversal / Command Injection / Open Redirect ํ”์ 
  • Basic ์ธ์ฆ ์‚ฌ์šฉ ํ”์ 

๊ฐ finding์€ ๋‹ค์Œ ์ •๋ณด๋ฅผ ํ•จ๊ป˜ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

  • ์‹ฌ๊ฐ๋„
  • OWASP ๋ถ„๋ฅ˜
  • Evidence
  • Guide
  • Remediation
  • Reproduction Checklist
  • PoC Template

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

.
โ”œโ”€ proxy/
โ”‚  โ”œโ”€ modify_request.py
โ”‚  โ”œโ”€ requirements.txt
โ”‚  โ””โ”€ rules.json
โ”œโ”€ server/
โ”‚  โ””โ”€ index.js
โ”œโ”€ samples/
โ”‚  โ”œโ”€ sample.har
โ”‚  โ”œโ”€ sample-errors.har
โ”‚  โ”œโ”€ sample-security.har
โ”‚  โ””โ”€ sample-large.har
โ”œโ”€ src/
โ”‚  โ”œโ”€ App.jsx
โ”‚  โ”œโ”€ main.jsx
โ”‚  โ”œโ”€ styles.css
โ”œโ”€ .env.example
โ”œโ”€ package.json
โ””โ”€ README.md

์ฃผ์š” ํŒŒ์ผ ์„ค๋ช…:

  • proxy/modify_request.py mitmproxy ์• ๋“œ์˜จ์ž…๋‹ˆ๋‹ค. proxy/rules.json ๊ทœ์น™์„ ์ฝ์–ด์„œ ์š”์ฒญ ๋ฐ”๋””๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์‘๋‹ต์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • server/index.js ํ”„๋ก ํŠธ API ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. ์บก์ฒ˜ ์ƒํƒœ ์กฐํšŒ, ๋ฆฌํ”Œ๋ ˆ์ด, HAR ๋ถ„์„, ์บก์ฒ˜ ์ด๋ฒคํŠธ ์ €์žฅ, ์ ๊ฒ€ ์ด๋ ฅ ์ €์žฅ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • src/App.jsx ๋ฉ”์ธ UI์ž…๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ, ์‚ฌ์ด๋“œ ๋ฉ”๋‰ด, ์‹ค์‹œ๊ฐ„ ์š”์ฒญ ๋ชฉ๋ก, ๋ณด์•ˆ finding, ๋ฆฌํฌํŠธ ์ถœ๋ ฅ, Diff, PoC ์ฃผ์ž…, ์ตœ๊ทผ ์ด๋ ฅ ํ™”๋ฉด ๋“ฑ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • samples/ HAR ์—…๋กœ๋“œ ํ…Œ์ŠคํŠธ์šฉ ์ƒ˜ํ”Œ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

์š”๊ตฌ ์‚ฌํ•ญ

  • Node.js 18+
  • npm
  • Python 3.9+
  • mitmproxy
  • Cloudflare R2 ๋ฒ„ํ‚ท
  • Firebase ํ”„๋กœ์ ํŠธ(Auth, ์„ ํƒ์  HAR ๋ถ„์„ ์ด๋ ฅ)
  • SQLMap(Optional, ๋กœ์ปฌ Injection ์ ๊ฒ€ ์‹œ ํ•„์š”)

๋น ๋ฅธ ์‹œ์ž‘

1. ์˜์กด์„ฑ ์„ค์น˜

npm install
pip install -r proxy/requirements.txt

2. ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •

cp .env.example .env

์˜ˆ์‹œ:

VITE_API_BASE_URL=https://http-analyzer-api.onrender.com
VITE_LOCAL_API_BASE_URL=http://127.0.0.1:5000
VITE_FIREBASE_API_KEY=<firebase-web-api-key>
VITE_FIREBASE_AUTH_DOMAIN=<project>.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=<project-id>
VITE_FIREBASE_STORAGE_BUCKET=<project>.firebasestorage.app
VITE_FIREBASE_MESSAGING_SENDER_ID=<messaging-sender-id>
VITE_FIREBASE_APP_ID=<firebase-app-id>
VITE_FIREBASE_MEASUREMENT_ID=<measurement-id>
PORT=4000
HOST=127.0.0.1
DISABLE_CAPTURE=false
DISABLE_SQLMAP=false
SQLMAP_BIN=sqlmap
OPENAI_API_KEY=<server-side-openai-api-key>
PLAYWRIGHT_HEADLESS=true
CAPTURE_READY_DELAY_MS=3000
CAPTURE_IDLE_AUTO_STOP_MS=10000
CAPTURE_CRAWL_ENABLED=true
CAPTURE_CRAWL_MAX_PAGES=8
CAPTURE_CRAWL_PAGE_DELAY_MS=1500
CAPTURE_LOGIN_WAIT_MS=3000
FIREBASE_SERVICE_ACCOUNT_JSON={"project_id":"<project-id>","client_email":"firebase-adminsdk@<project-id>.iam.gserviceaccount.com","private_key":"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n"}
# ๋˜๋Š” ๊ฐœ๋ณ„ ํ™˜๊ฒฝ๋ณ€์ˆ˜
FIREBASE_PROJECT_ID=<project-id>
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@<project-id>.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n
# ๋˜๋Š” ๋กœ์ปฌ ํŒŒ์ผ ๊ฒฝ๋กœ
FIREBASE_SERVICE_ACCOUNT_PATH=/absolute/path/to/firebase-service-account.json
CLOUDFLARE_R2_ACCOUNT_ID=<cloudflare-account-id>
CLOUDFLARE_R2_ACCESS_KEY_ID=<r2-access-key-id>
CLOUDFLARE_R2_SECRET_ACCESS_KEY=<r2-secret-access-key>
CLOUDFLARE_R2_BUCKET=http-analyzer-files
CLOUDFLARE_R2_PUBLIC_BASE_URL=https://<public-bucket-host>
R2_HAR_ANALYSIS_INDEX_KEY=har/recent-index.json
R2_HAR_ANALYSIS_INDEX_LIMIT=50
R2_INSPECTION_INDEX_KEY=inspections/recent-index.json
R2_INSPECTION_INDEX_LIMIT=100

๋กœ์ปฌ์—์„œ ํ”„๋ŸฐํŠธ์™€ ๋ฐฑ์—”๋“œ๋ฅผ ๊ฐ™์ด ์‹คํ–‰ํ•  ๋•Œ๋Š” VITE_API_BASE_URL=http://127.0.0.1:5000์œผ๋กœ ๋ฐ”๊ฟ”๋„ ๋ฉ๋‹ˆ๋‹ค. ์šด์˜ ํ”„๋ŸฐํŠธ์—์„œ ์ƒˆ์ฐฝ ์ˆ˜๋™ ์บก์ฒ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์‚ฌ์šฉ์ž PC์˜ ๋กœ์ปฌ ๋ฐฑ์—”๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋ฏ€๋กœ VITE_LOCAL_API_BASE_URL=http://127.0.0.1:5000 ๊ฐ’์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์„ค๋ช…:

  • VITE_* ํ”„๋ŸฐํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค. VITE_FIREBASE_*๋Š” Firebase Auth์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • FIREBASE_SERVICE_ACCOUNT_JSON ๋˜๋Š” FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, FIREBASE_PRIVATE_KEY, FIREBASE_SERVICE_ACCOUNT_PATH ์„œ๋ฒ„์—์„œ Firebase Admin์„ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์บก์ฒ˜/๋ถ„์„ ๊ฒฐ๊ณผ ์ €์žฅ์—๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • CLOUDFLARE_R2_* ์บก์ฒ˜ ์ด๋ฒคํŠธ, ์ ๊ฒ€ ์ด๋ ฅ, HAR ์›๋ณธ ํŒŒ์ผ์„ Cloudflare R2์— ์—…๋กœ๋“œํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • HOST ๋กœ์ปฌ์€ ๋ณดํ†ต 127.0.0.1, Render ๊ฐ™์€ ๋ฐฐํฌ ํ™˜๊ฒฝ์€ 0.0.0.0์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • DISABLE_CAPTURE ๋ฐฐํฌ ๋ฐฑ์—”๋“œ์—์„œ Playwright ์บก์ฒ˜ API๋ฅผ ๋ง‰๊ณ  ์ €์žฅ/์กฐํšŒ API๋งŒ ์šด์˜ํ•˜๋ ค๋ฉด true๋กœ ๋‘ก๋‹ˆ๋‹ค.
  • DISABLE_SQLMAP SQLMap ์‹คํ–‰ API๋ฅผ ๋ง‰์„์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฐœ ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ๋Š” ์•…์šฉ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด true๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
  • SQLMAP_BIN ๋กœ์ปฌ์— ์„ค์น˜๋œ SQLMap ์‹คํ–‰ ํŒŒ์ผ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ sqlmap์ž…๋‹ˆ๋‹ค.
  • CAPTURE_READY_DELAY_MS ์ฒซ ํŽ˜์ด์ง€ ๋กœ๋“œ ํ›„ ์บก์ฒ˜ ์ค€๋น„๋ฅผ ์œ„ํ•ด ๋Œ€๊ธฐํ•˜๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 3000์ž…๋‹ˆ๋‹ค.
  • CAPTURE_IDLE_AUTO_STOP_MS ๋„คํŠธ์›Œํฌ ํ™œ๋™์ด ์—†์„ ๋•Œ ์ž๋™ ์ค‘์ง€ํ•˜๊ธฐ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 10000์ž…๋‹ˆ๋‹ค.
  • CAPTURE_CRAWL_ENABLED, CAPTURE_CRAWL_MAX_PAGES, CAPTURE_CRAWL_PAGE_DELAY_MS ์บก์ฒ˜ ์‹œ์ž‘ ํ›„ ๊ฐ™์€ ๋„๋ฉ”์ธ์˜ ๋งํฌ๋ฅผ ์ž๋™ ์ˆœํšŒํ• ์ง€, ์ตœ๋Œ€ ๋ช‡ ํŽ˜์ด์ง€๊นŒ์ง€ ๋ณผ์ง€, ํŽ˜์ด์ง€ ์‚ฌ์ด์— ์–ผ๋งˆ๋‚˜ ๊ธฐ๋‹ค๋ฆด์ง€ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • CAPTURE_LOGIN_WAIT_MS ID/PW ์ž๋™ ์ž…๋ ฅ ํ›„ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 3000์ž…๋‹ˆ๋‹ค.

์‹คํ–‰ ๋ฐฉ๋ฒ•

1. ํ”„๋ก์‹œ ์‹คํ–‰

mitmdump -s proxy/modify_request.py

ํ”„๋ก์‹œ ๊ธฐ๋ณธ ์ฃผ์†Œ:

  • Host: 127.0.0.1
  • Port: 8080

HTTPS๋ฅผ ๋ณด๋ ค๋ฉด mitmproxy ์ธ์ฆ์„œ๋ฅผ ๋Œ€์ƒ ํด๋ผ์ด์–ธํŠธ/๋ธŒ๋ผ์šฐ์ €์— ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2. ๋ถ„์„ ์„œ๋ฒ„ ์‹คํ–‰

npm run server

๊ธฐ๋ณธ ์ฃผ์†Œ:

  • http://127.0.0.1:4000

3. ํ”„๋ŸฐํŠธ ์‹คํ–‰

npm run dev

๊ธฐ๋ณธ ์ฃผ์†Œ:

  • http://localhost:5173

์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ํ๋ฆ„

๋กœ๊ทธ์ธ

  1. ํ”„๋ŸฐํŠธ ์ ‘์† ํ›„ ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฆ…๋‹ˆ๋‹ค.
  2. ํ˜„์žฌ ํ—ˆ์šฉ๋œ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•ด์•ผ ๋ฉ”์ธ ํ™”๋ฉด์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ํ—ˆ์šฉ ๊ณ„์ •:

  • totoriverce@gmail.com

์ฐธ๊ณ :

  • ๋กœ๊ทธ์ธ ์„ธ์…˜์€ Firebase Auth์˜ ๋ธŒ๋ผ์šฐ์ € ์ง€์†์„ฑ์œผ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
  • ์บก์ฒ˜/์ ๊ฒ€ ์ด๋ ฅ์€ ๋จผ์ € ๋กœ์ปฌ ์ €์žฅ์†Œ์— ์ ์žฌ๋œ ๋’ค, ๋ฐฑ์—”๋“œ ๋˜๋Š” Firestore์— ๋™๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.

์‹ค์‹œ๊ฐ„ ์บก์ฒ˜

  1. Capture ํ™”๋ฉด์—์„œ ๋ถ„์„ ๋Œ€์ƒ URL์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  2. ํ•„์š”ํ•˜๋ฉด ์ถ”๊ฐ€ ์ œ์™ธ ํŒจํ„ด์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  3. ๋กœ๊ทธ์ธ ํ•„์š”ํ•œ ์‚ฌ์ดํŠธ๋ผ๋ฉด ID, PW๋ฅผ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ Session์— ์ฟ ํ‚ค ๊ฐ’์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  4. ์บก์ฒ˜ ์‹œ์ž‘์„ ๋ˆ„๋ฅด๋ฉด ์„œ๋ฒ„๊ฐ€ Playwright ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์—ด๊ณ  ๋Œ€์ƒ URL๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  5. Session ๊ฐ’์ด ์žˆ์œผ๋ฉด ์ฟ ํ‚ค๋กœ ๋จผ์ € ์ ์šฉํ•˜๊ณ , ์—†์œผ๋ฉด ID/PW๋กœ ์ฒซ ํ™”๋ฉด์˜ ๋กœ๊ทธ์ธ ํผ์„ ์ž๋™ ๊ฐ์ง€ํ•ด ์ž…๋ ฅ/์ œ์ถœํ•ฉ๋‹ˆ๋‹ค.
  6. ์ฒซ ํŽ˜์ด์ง€ ๋กœ๋“œ ํ›„ 3์ดˆ ๋Œ€๊ธฐํ•œ ๋’ค ๊ฐ™์€ ๋„๋ฉ”์ธ์˜ ๋งํฌ๋ฅผ ์ตœ๋Œ€ CAPTURE_CRAWL_MAX_PAGES๊ฐœ๊นŒ์ง€ ์ž๋™ ์ˆœํšŒํ•ฉ๋‹ˆ๋‹ค.
  7. ํฌ๋กค๋ง์ด ์™„๋ฃŒ๋˜๋ฉด ์บก์ฒ˜๊ฐ€ ์ž๋™ ์ค‘์ง€๋˜๊ณ , ์‚ฌ์ด๋“œ๋ฐ” ์ง„ํ–‰ ์ƒํƒœ๊ฐ€ complete๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค.
  8. ์š”์ฒญ/์‘๋‹ต ๋ชฉ๋ก์„ ๋ณด๋ฉด์„œ finding๊ณผ Diff๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ :

  • ์ด๋ฏธ์ง€ ์š”์ฒญ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•ญ์ƒ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค.
  • Excluded ์ž…๋ ฅ์นธ์€ ์ถ”๊ฐ€ ์ œ์™ธ ๊ทœ์น™๋งŒ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • ID, PW, Session์€ ์ธ์ฆ ์ž๋™ํ™”์—๋งŒ ์‚ฌ์šฉํ•˜๋ฉฐ ์•ฑ ์ €์žฅ์†Œ์—๋Š” ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • Session์€ SESSIONID=... ๋˜๋Š” SESSIONID=...; other=... ๊ฐ™์€ Cookie ๋ฌธ์ž์—ด์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’๋งŒ ๋„ฃ์œผ๋ฉด session=<๊ฐ’> ์ฟ ํ‚ค๋กœ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Capture ์‚ฌ์ด๋“œ๋ฐ”์—๋Š” ์บก์ฒ˜๋œ ์š”์ฒญ ์ˆ˜, ์ „์ฒด ์š”์ฒญ ์ˆ˜, ํฌ๋กค๋ง ํŽ˜์ด์ง€ ์ˆ˜, ์˜ค๋ฅ˜ ์ˆ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  • ์ˆ˜๋™์œผ๋กœ ์ค‘์ง€ํ•˜๊ณ  ์‹ถ์œผ๋ฉด ์บก์ฒ˜ ์ค‘์ง€๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
  • Capture ํ™”๋ฉด์—์„œ๋Š” ์š”์ฒญ๋ณ„ ๋ณด์•ˆ finding ์š”์•ฝ๋งŒ ๋ณด์—ฌ์ฃผ๊ณ , ์ƒ์„ธ ๋‚ด์šฉ์€ Findings ๋ฉ”๋‰ด์—์„œ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • Findings์—์„œ ๋ณด๊ธฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ์š”์ฒญ์˜ finding๋งŒ ํ•„ํ„ฐ๋˜์–ด ๋ฐ”๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ์ข…๋ฃŒ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•œ net::ERR_ABORTED๋Š” ์ข…๋ฃŒ์„ฑ ๋…ธ์ด์ฆˆ๋กœ ๊ฐ„์ฃผํ•ด UI์™€ Recent Data์—์„œ ์ˆจ๊น๋‹ˆ๋‹ค.

๋ฆฌํ”Œ๋ ˆ์ด

  1. ์š”์ฒญ ์นด๋“œ๋ฅผ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  2. Replay ๋ชจ๋‹ฌ์—์„œ URL, ํ—ค๋”, ๋ฐ”๋””๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
  3. ์š”์ฒญ ๋ฒ„ํŠผ์œผ๋กœ ๋‹ค์‹œ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

๋ณด์•ˆ finding์ด ์žˆ๋Š” ๊ฒฝ์šฐ:

  • PoC๋ฅผ Replay์— ์ฃผ์ž… ๋ฒ„ํŠผ์œผ๋กœ ์žฌํ˜„ ํ…œํ”Œ๋ฆฟ์„ ๋ฐ”๋กœ ๋ชจ๋‹ฌ์— ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธด ์‘๋‹ต์€ ๋ชจ๋‹ฌ ๋‚ด๋ถ€์—์„œ ์Šคํฌ๋กค๋ฉ๋‹ˆ๋‹ค.

Mermaid ์ƒ์„ฑ

Capture ํ™”๋ฉด์˜ Generate Mermaid ๋ฒ„ํŠผ์œผ๋กœ ํ˜„์žฌ ์บก์ฒ˜๋œ ์š”์ฒญ์„ ๊ธฐ๋ฐ˜์œผ๋กœ Mermaid ํ๋ฆ„๋„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฒฐ๊ณผ๋Š” ๋ณธ๋ฌธ์ด ์•„๋‹ˆ๋ผ ์ „์šฉ ํŒ์—…์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  • ํŒ์—… ์šฐ์ธก ์ƒ๋‹จ ๋ณต์‚ฌ ๋ฒ„ํŠผ์œผ๋กœ Mermaid ์ฝ”๋“œ๋ฅผ ๋ฐ”๋กœ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ณต์‚ฌ ํ›„ ํŒ์—…์€ ์ž๋™์œผ๋กœ ๋‹ซํž™๋‹ˆ๋‹ค.

SQLMap Injection Scan

SQLMap ๋ฉ”๋‰ด๋Š” ์บก์ฒ˜๋œ ์š”์ฒญ ์ค‘ SQL Injection ์ ๊ฒ€ ํ›„๋ณด๋ฅผ ๊ณจ๋ผ sqlmap์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋กœ์ปฌ ์ ๊ฒ€ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ ํ๋ฆ„:

  1. Capture ๋˜๋Š” Recent Data์—์„œ ์š”์ฒญ์„ ํ™•๋ณดํ•ฉ๋‹ˆ๋‹ค.
  2. SQLMap ๋ฉ”๋‰ด๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  3. Captured Candidates์—์„œ ์š”์ฒญ์„ ์„ ํƒํ•˜๋ฉด URL, Method, Headers, Body๊ฐ€ ์ž๋™ ์ž…๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  4. ํ•„์š”ํ•˜๋ฉด Level, Risk, Header, Body ๊ฐ’์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. SQLMap Scan์„ ๋ˆŒ๋Ÿฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜:

  • ๋ฐ˜๋“œ์‹œ ๋ณธ์ธ ์†Œ์œ  ๋˜๋Š” ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ๊ฐ€๋ฐ›์€ ๋Œ€์ƒ์—๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋กœ์ปฌ ์„œ๋ฒ„์—์„œ sqlmap ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฏ€๋กœ ๋กœ์ปฌ์— SQLMap์ด ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • macOS Homebrew ๊ธฐ์ค€ ์„ค์น˜ ์˜ˆ์‹œ๋Š” brew install sqlmap์ž…๋‹ˆ๋‹ค.
  • ๊ณต๊ฐœ Render ๋ฐฑ์—”๋“œ์—์„œ๋Š” DISABLE_SQLMAP=true๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ SQLMap์„ ์—ด์–ด๋‘๋ฉด ์ž„์˜ ์™ธ๋ถ€ ๋Œ€์ƒ ์Šค์บ”์— ์•…์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

OpenAI Summary Settings

Settings ๋ฉ”๋‰ด์—์„œ ํฌ๋กค๋ง ์™„๋ฃŒ ํ›„ ์ž๋™ ์ƒ์„ฑํ•  Summary ์„ค์ •์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ํ™˜๊ฒฝ๋ณ€์ˆ˜ OPENAI_API_KEY๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์— ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜์ง€ ์•Š์•„๋„ ์„œ๋ฒ„ ํ‚ค๋กœ Summary๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ž…๋ ฅ ํ•ญ๋ชฉ:

  • OPENAI KEY: ์„ ํƒ ์ž…๋ ฅ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ OPENAI_API_KEY๊ฐ€ ์—†์„ ๋•Œ๋งŒ ๋ธŒ๋ผ์šฐ์ € localStorage ํ‚ค๋กœ Summary๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • MODEL: Summary ์ƒ์„ฑ์— ์‚ฌ์šฉํ•  ๋ชจ๋ธ๋ช…์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ gpt-4.1-mini์ž…๋‹ˆ๋‹ค.
  • PROMPT: HTTP ์บก์ฒ˜ ๊ฒฐ๊ณผ๋ฅผ ์–ด๋–ค ๊ด€์ ์œผ๋กœ ์š”์•ฝํ• ์ง€ ์ •ํ•˜๋Š” ํ”„๋กฌํ”„ํŠธ์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ํ”„๋กฌํ”„ํŠธ๋Š” ๋‹ค์Œ ๊ด€์ ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

  • ์ „์ฒด ์š”์•ฝ
  • ์œ„ํ—˜๋„ ์šฐ์„  ์—”๋“œํฌ์ธํŠธ
  • SQL Injection, XSS, ์ธ์ฆ/์„ธ์…˜, CORS, ๋ฏผ๊ฐ์ •๋ณด ๋…ธ์ถœ ๊ทผ๊ฑฐ
  • ์บก์ฒ˜ ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ฆ๊ฑฐ์™€ ์ถ”๊ฐ€ ํ™•์ธ ํ•„์š” ํ•ญ๋ชฉ ๋ถ„๋ฆฌ
  • SQLMap ์ ๊ฒ€ ํ›„๋ณด URL/ํŒŒ๋ผ๋ฏธํ„ฐ ์ œ์•ˆ
  • ๊ฐœ๋ฐœ์ž ๋‹ค์Œ ์กฐ์น˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

ํฌ๋กค๋ง์ด crawl-complete๋กœ ์ž๋™ ์ค‘์ง€๋˜๋ฉด, API Key๊ฐ€ ์ž…๋ ฅ๋œ ๊ฒฝ์šฐ ํ˜„์žฌ ์บก์ฒ˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ Summary๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ˆ˜๋™์œผ๋กœ๋Š” ํ˜„์žฌ ๋ฐ์ดํ„ฐ๋กœ Summary ์ƒ์„ฑ ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

HAR ๋ถ„์„

HAR ํ™”๋ฉด์—์„œ ํŒŒ์ผ์„ ์„ ํƒํ•ด ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์•„๋ž˜ ํ•ญ๋ชฉ์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

  • ์ด ์š”์ฒญ ์ˆ˜
  • ํ‰๊ท  ๋Œ€๊ธฐ ์‹œ๊ฐ„
  • ๊ฐ€์žฅ ๋А๋ฆฐ ์š”์ฒญ
  • ๋ฉ”์„œ๋“œ ๋ถ„ํฌ
  • ์ƒ์œ„ ํ˜ธ์ŠคํŠธ
  • ์ƒํƒœ์ฝ”๋“œ ๋ถ„ํฌ
  • ์ฝ˜ํ…์ธ  ํƒ€์ž… ๋ถ„ํฌ
  • ์‹คํŒจ ์š”์ฒญ ๋ชฉ๋ก

๋ถ„์„ ์ž์ฒด๋Š” Firebase ์—†์ด๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๊ฒฐ๊ณผ ํŒŒ์ผ์„ ์„œ๋ฒ„์— ์ €์žฅํ•˜๋ ค๋ฉด Cloudflare R2 ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Recent Data

Recent Data ํ™”๋ฉด์—์„œ๋Š” ์•„๋ž˜ ๋‚ด์šฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ตœ๊ทผ ์ ๊ฒ€ ์ด๋ ฅ
  • ์ตœ๊ทผ ์บก์ฒ˜ ์ด๋ฒคํŠธ
  • ์ตœ๊ทผ 7์ผ / 30์ผ ๊ธฐ์ค€ ํ†ต๊ณ„ ๋Œ€์‹œ๋ณด๋“œ
  • ์ ๊ฒ€ ์ด๋ ฅ ์ƒ์„ธ ๋ชจ๋‹ฌ
  • ์ ๊ฒ€ ์ด๋ ฅ๋ณ„ HTML / PDF ๋ฆฌํฌํŠธ ์žฌ๋‹ค์šด๋กœ๋“œ
  • ํ•ญ๋ชฉ๋ณ„ ์ €์žฅ ์ถœ์ฒ˜(Cloudflare R2)

์ค‘์š”:

  • ์บก์ฒ˜ ๊ฒฐ๊ณผ๋Š” Cloudflare R2 ํŒŒ์ผ ์ €์žฅ์ด ์„ฑ๊ณตํ•ด์•ผ Recent Data์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์ผ ์ €์žฅ์ด ์‹คํŒจํ•˜๋ฉด ๋กœ์ปฌ ๋Œ€๊ธฐ ํ•ญ๋ชฉ์œผ๋กœ ํ‘œ์‹œํ•˜์ง€ ์•Š๊ณ  ์ €์žฅ ์‹คํŒจ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
  • Recent Data๋Š” R2์˜ inspections/recent-index.json ์ธ๋ฑ์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

Firebase / Cloudflare ์ €์žฅ ๊ตฌ์กฐ

Firestore

  • ํ˜„์žฌ ์บก์ฒ˜/๋ถ„์„ ๊ฒฐ๊ณผ ์ €์žฅ์—๋Š” Firestore ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • Firebase๋Š” ์ธ์ฆ๊ณผ ๊ธฐ์กด ํ”„๋กœ์ ํŠธ ํ˜ธํ™˜ ๋ชฉ์ ์œผ๋กœ๋งŒ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค.

Cloudflare R2

  • ์บก์ฒ˜ ์ด๋ฒคํŠธ: inspections/events/YYYY-MM-DD/<session-id>.json
  • ์ ๊ฒ€ ์ด๋ ฅ / ๋ฆฌํฌํŠธ ์Šค๋ƒ…์ƒท: inspections/runs/YYYY-MM-DD/<run-id>.json
  • Recent Data ์ธ๋ฑ์Šค: inspections/recent-index.json
  • HAR ๋ถ„์„ ๊ฒฐ๊ณผ: har/analyses/YYYY-MM-DD/<analysis-id>.json
  • HAR ๋ถ„์„ ์ธ๋ฑ์Šค: har/recent-index.json
  • HAR ์›๋ณธ ํŒŒ์ผ๊ณผ ์ƒ์„ฑ ๋ฆฌํฌํŠธ ์ฒจ๋ถ€ ํŒŒ์ผ๋„ Cloudflare R2์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜:

  • FIREBASE_SERVICE_ACCOUNT_JSON๊ณผ CLOUDFLARE_R2_SECRET_ACCESS_KEY๋Š” ์„œ๋ฒ„ ์ „์šฉ์ž…๋‹ˆ๋‹ค.
  • ํ”„๋ŸฐํŠธ ์ฝ”๋“œ์— ์ง์ ‘ ๋…ธ์ถœํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

GitHub Actions + Render ๋ฐฐํฌ

์ด ์ €์žฅ์†Œ๋Š” ํ”„๋ŸฐํŠธ์™€ ๋ฐฑ์—”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ๋ฐฐํฌํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ”„๋ŸฐํŠธ: GitHub Pages
  • ๋ฐฑ์—”๋“œ: Render Web Service
  • DB: Firebase Firestore
  • File Storage: Cloudflare R2

GitHub Actions ์„ค์ •

GitHub ์ €์žฅ์†Œ Settings > Secrets and variables > Actions์— ์•„๋ž˜ ๊ฐ’์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋ŸฐํŠธ API URL์€ ์ €์žฅ์†Œ ๋ณ€์ˆ˜(Variables)๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์„ ๋“ฑ๋กํ•˜์ง€ ์•Š์œผ๋ฉด GitHub Actions๋Š” ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ https://http-analyzer-api.onrender.com์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

VITE_API_BASE_URL=https://http-analyzer-api.onrender.com
VITE_LOCAL_API_BASE_URL=http://127.0.0.1:5000

Render ์ž๋™ ๋ฐฐํฌ ํŠธ๋ฆฌ๊ฑฐ์šฉ:

RENDER_DEPLOY_HOOK_URL=<render-deploy-hook-url>

RENDER_DEPLOY_HOOK_URL์€ Render ์„œ๋น„์Šค์˜ Settings > Deploy Hook์—์„œ ์ƒ์„ฑํ•œ URL์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ’์ด ์—†์œผ๋ฉด ํ”„๋ŸฐํŠธ ๋ฐฐํฌ๋งŒ ์ง„ํ–‰๋˜๊ณ  ๋ฐฑ์—”๋“œ ๋ฐฐํฌ ํŠธ๋ฆฌ๊ฑฐ ๋‹จ๊ณ„๋Š” ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

Render ํ™˜๊ฒฝ๋ณ€์ˆ˜

Render Web Service์—๋Š” ์•„๋ž˜ ๊ฐ’์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

NODE_ENV=production
HOST=0.0.0.0
DISABLE_CAPTURE=false
PLAYWRIGHT_HEADLESS=true
DISABLE_SQLMAP=true
FIREBASE_PROJECT_ID=<project-id>
FIREBASE_CLIENT_EMAIL=<firebase-client-email>
FIREBASE_PRIVATE_KEY=<firebase-private-key>
CLOUDFLARE_R2_ACCOUNT_ID=<cloudflare-account-id>
CLOUDFLARE_R2_ACCESS_KEY_ID=<r2-access-key-id>
CLOUDFLARE_R2_SECRET_ACCESS_KEY=<r2-secret-access-key>
CLOUDFLARE_R2_BUCKET=<r2-bucket-name>
CLOUDFLARE_R2_PUBLIC_BASE_URL=<public-bucket-host>
R2_HAR_ANALYSIS_INDEX_KEY=har/recent-index.json
R2_HAR_ANALYSIS_INDEX_LIMIT=50
R2_INSPECTION_INDEX_KEY=inspections/recent-index.json
R2_INSPECTION_INDEX_LIMIT=100

๋ฐฐํฌ ๋ฐฑ์—”๋“œ์—์„œ๋„ ์บก์ฒ˜ API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก DISABLE_CAPTURE=false๋กœ ๋‘ก๋‹ˆ๋‹ค.

  • ๋™์ž‘: /api/health, /api/capture/start, /api/capture/status, /api/capture/stop, /api/replay-request, /api/recent-analyses, /api/inspection-runs, /api/capture-events/batch, /api/analyze-har
  • Render์—์„œ๋Š” PLAYWRIGHT_HEADLESS=true๋กœ ์„œ๋ฒ„ ๋‚ด๋ถ€ headless Chromium์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • Render์—์„œ๋Š” SQLMap API๋ฅผ ๊ธฐ๋ณธ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. render.yaml์˜ DISABLE_SQLMAP=true๋Š” ์˜๋„๋œ ๋ณด์•ˆ ์„ค์ •์ž…๋‹ˆ๋‹ค.

์ฃผ์˜: Render์—์„œ ์‹คํ–‰๋˜๋Š” ๋ธŒ๋ผ์šฐ์ €๋Š” ์‚ฌ์šฉ์ž PC๊ฐ€ ์•„๋‹ˆ๋ผ Render ์„œ๋ฒ„ ๋‚ด๋ถ€ ๋ธŒ๋ผ์šฐ์ €์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ์ด ์ง์ ‘ ๋กœ๊ทธ์ธํ•˜๊ณ  ์กฐ์ž‘ํ•˜๋Š” ์„ธ์…˜ ์บก์ฒ˜๋Š” ๋กœ์ปฌ ์•ฑ์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค.

Render Blueprint

render.yaml์ด ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ Render์—์„œ Blueprint๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Service Name: http-analyzer-api
  • Build Command: npm ci
  • Start Command: npm run start
  • Health Check Path: /api/health
  • ์˜ˆ์ƒ ๋ฐฑ์—”๋“œ URL: https://http-analyzer-api.onrender.com

Render์—์„œ ์„œ๋น„์Šค ์ด๋ฆ„์ด ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ด๋ฉด ์‹ค์ œ ์ƒ์„ฑ๋œ URL์„ GitHub Actions ๋ณ€์ˆ˜ VITE_API_BASE_URL์— ๋‹ค์‹œ ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ์‚ฌ์ดํŠธ ๋™์ž‘

๋ฐฐํฌ ์‚ฌ์ดํŠธ์—์„œ๋„ ๊ธฐ์กด ๋ฉ”๋‰ด๋Š” ๊ทธ๋Œ€๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  • Overview, Capture, Findings, HAR, Recent Data ๋ฉ”๋‰ด ํ‘œ์‹œ
  • HAR ์—…๋กœ๋“œ, Replay, ๋ฆฌํฌํŠธ ์ถœ๋ ฅ์€ ๋ฐฑ์—”๋“œ API URL์„ ํ†ตํ•ด ์‹คํ–‰
  • Render ํ™˜๊ฒฝ์—์„œ๋Š” headless Chromium์œผ๋กœ ์บก์ฒ˜๊ฐ€ ์‹คํ–‰๋จ
  • ์‹ค์ œ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ๋„์›Œ ์„ธ์…˜์„ ์ด์–ด๊ฐ€๋Š” ์บก์ฒ˜๋Š” ๋กœ์ปฌ ์•ฑ์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ

ํ˜„์žฌ ์›Œํฌ์ŠคํŽ˜์ด์Šค ์ƒํƒœ

์ด ์ €์žฅ์†Œ๋Š” ์„œ๋ฒ„์—์„œ ๋‹ค์Œ Cloudflare R2 ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • har/analyses/YYYY-MM-DD/... ๊ฒฝ๋กœ์— HAR ๋ถ„์„ ๊ฒฐ๊ณผ ์ €์žฅ
  • har/recent-index.json ๊ฒฝ๋กœ์— HAR ์ตœ๊ทผ ์ด๋ ฅ ์ธ๋ฑ์Šค ์ €์žฅ
  • inspections/events/YYYY-MM-DD/... ๊ฒฝ๋กœ์— ์บก์ฒ˜ ์ด๋ฒคํŠธ ์ €์žฅ
  • inspections/runs/YYYY-MM-DD/... ๊ฒฝ๋กœ์— ์ ๊ฒ€ ์ด๋ ฅ๊ณผ ๋ฆฌํฌํŠธ ์Šค๋ƒ…์ƒท ์ €์žฅ
  • inspections/recent-index.json ๊ฒฝ๋กœ์— Recent Data ์ธ๋ฑ์Šค ์ €์žฅ

๋ฆฌํฌํŠธ ์ถœ๋ ฅ

์ƒ๋‹จ Export ๋ฉ”๋‰ด์—์„œ ๋‹ค์Œ ํฌ๋งท์„ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • HTML
  • PDF
  • JSON
  • Markdown
  • CSV

๋ฆฌํฌํŠธ์—๋Š” ๋‹ค์Œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • ํ‘œ์ง€
  • ์ ๊ฒ€์ž
  • ์ ๊ฒ€ ์ผ์‹œ
  • ๊ฒฐ๋ก 
  • ์š”์ฒญ/์‘๋‹ต ๋ชฉ๋ก
  • ๋ณด์•ˆ finding
  • OWASP ์š”์•ฝ
  • ์—”๋“œํฌ์ธํŠธ ์œ„ํ—˜๋„ ์š”์•ฝ

Mask Secrets๊ฐ€ ์ผœ์ ธ ์žˆ์œผ๋ฉด ๋ฏผ๊ฐ์ •๋ณด๋Š” ๋งˆ์Šคํ‚น๋œ ์ƒํƒœ๋กœ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

์ƒ˜ํ”Œ HAR ํŒŒ์ผ

ํ…Œ์ŠคํŠธ์šฉ HAR ํŒŒ์ผ์€ samples์— ๋“ค์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • samples/sample.har ๊ธฐ๋ณธ ์—…๋กœ๋“œ/์ €์žฅ ๋™์ž‘ ํ™•์ธ์šฉ
  • samples/sample-errors.har ์˜ค๋ฅ˜ ์‘๋‹ต๊ณผ ์‹คํŒจ ์š”์ฒญ ํ™•์ธ์šฉ
  • samples/sample-security.har ๋ณด์•ˆ ํŒจํ„ด ํƒ์ง€ ํ™•์ธ์šฉ
  • samples/sample-large.har ๋Œ€๋Ÿ‰ ์š”์ฒญ ํ๋ฆ„ ํ™•์ธ์šฉ
  • samples/sample-vulnerable.har ๋ฏผ๊ฐ์ •๋ณด ๋…ธ์ถœ, ๋ณด์•ˆ ํ—ค๋” ๋ˆ„๋ฝ, ์ฃผ์ž… ํ”์  ๋“ฑ ์ทจ์•ฝ ์ง•ํ›„ ํ…Œ์ŠคํŠธ์šฉ

UI ๋ณด์กฐ ๊ธฐ๋Šฅ

Mask Secrets

๋ฏผ๊ฐ๊ฐ’์„ ๊ธฐ๋ณธ ๋งˆ์Šคํ‚นํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ:

  • Authorization
  • Cookie
  • Set-Cookie
  • ํ† ํฐ/JWT/API Key
  • Private Key ํ˜•์‹ ๋ฌธ์ž์—ด

์˜คํƒ ์ฒ˜๋ฆฌ(Suppress)

finding๋งˆ๋‹ค ๋‹ค์Œ ๋ฒ”์œ„๋กœ ์–ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์„ธ์…˜ ์˜คํƒ
  • ์—”๋“œํฌ์ธํŠธ ์˜คํƒ
  • ํ˜ธ์ŠคํŠธ ์˜คํƒ
  • ์ „์—ญ ์˜คํƒ

Diff

๊ฐ™์€ ์—”๋“œํฌ์ธํŠธ์˜ ์ด์ „ ์š”์ฒญ๊ณผ ํ˜„์žฌ ์š”์ฒญ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒํƒœ์ฝ”๋“œ
  • ๋ฐ”๋€ ์š”์ฒญ ํ—ค๋”
  • ๋ฐ”๋€ ์‘๋‹ต ํ—ค๋”
  • ์š”์ฒญ ๋ฐ”๋””
  • ์‘๋‹ต ๋ฐ”๋””

๊ธฐ๋ณธ ์ƒํƒœ๋Š” ์ ‘ํž˜์ž…๋‹ˆ๋‹ค.

Endpoint Priority

finding์ด ๋งŽ์ด ๋ชฐ๋ฆฐ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์šฐ์„ ์ˆœ์œ„๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋ˆ„์  ์ ์ˆ˜
  • finding ๊ฐœ์ˆ˜
  • ์ตœ๊ณ  ์‹ฌ๊ฐ๋„
  • ์ž์ฃผ ๊ฑธ๋ฆฐ OWASP ์นดํ…Œ๊ณ ๋ฆฌ

๊ธฐ๋ณธ ์ƒํƒœ๋Š” ์ ‘ํž˜์ž…๋‹ˆ๋‹ค.

Recent Data ์ €์žฅ ์ •์ฑ…

์ตœ๊ทผ ์ ๊ฒ€ ์ด๋ ฅ๊ณผ ์บก์ฒ˜ ์ด๋ฒคํŠธ๋Š” Cloudflare R2 ํŒŒ์ผ ์ €์žฅ ์„ฑ๊ณต ๊ธฐ์ค€์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ์บก์ฒ˜ ์ด๋ฒคํŠธ: R2 JSON ํŒŒ์ผ๋กœ ์ €์žฅ
  • ์ ๊ฒ€ ์ด๋ ฅ: R2 JSON ํŒŒ์ผ๋กœ ์ €์žฅ
  • HAR ๋ถ„์„ ๊ฒฐ๊ณผ: R2 JSON ํŒŒ์ผ๋กœ ์ €์žฅ
  • Recent Data: R2 ์ธ๋ฑ์Šค ํŒŒ์ผ์—์„œ ์ตœ๊ทผ ์ ๊ฒ€ ์ด๋ ฅ๋งŒ ์กฐํšŒ

ํŒŒ์ผ ์ €์žฅ์ด ์‹คํŒจํ•˜๋ฉด Recent Data์— ๋กœ์ปฌ ๋Œ€๊ธฐ ํ•ญ๋ชฉ์„ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์ €์žฅ ์‹คํŒจ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ํŒ

๋นŒ๋“œ ํ™•์ธ

npm run build

์„œ๋ฒ„๋งŒ ์‹คํ–‰

npm run server

ํ”„๋ŸฐํŠธ๋งŒ ์‹คํ–‰

npm run dev

์ฃผ์˜ ์‚ฌํ•ญ

  • ์ด ๋„๊ตฌ์˜ finding์€ ํ™•์ • ์ทจ์•ฝ์ ์ด ์•„๋‹ˆ๋ผ ํŒจํ„ด ๊ธฐ๋ฐ˜ ํƒ์ง€์ž…๋‹ˆ๋‹ค.
  • ์‹ค์ œ ์ทจ์•ฝ ์—ฌ๋ถ€๋Š” ์žฌํ˜„ ํ…Œ์ŠคํŠธ์™€ ์„œ๋ฒ„ ์ฝ”๋“œ/์ธํ”„๋ผ ์„ค์ • ๊ฒ€ํ† ๋กœ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Firebase ์„œ๋น„์Šค ๊ณ„์ • ํ‚ค์™€ Cloudflare R2 ๋น„๋ฐ€ํ‚ค๋Š” ์ ˆ๋Œ€ ๋ธŒ๋ผ์šฐ์ €๋‚˜ ๊ณต๊ฐœ ์ €์žฅ์†Œ์— ๋…ธ์ถœํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์•ž์œผ๋กœ ํ™•์žฅํ•˜๊ธฐ ์ข‹์€ ๋ฐฉํ–ฅ

  • finding ๊ฒฐ๊ณผ์˜ ํ”„๋กœ์ ํŠธ๋ณ„ ์ €์žฅ/์กฐํšŒ ํ™”๋ฉด
  • replay ๊ฒฐ๊ณผ ์ž๋™ ๋น„๊ต
  • finding๋ณ„ ์ฝ”๋ฉ˜ํŠธ ๋ฐ triage ์ƒํƒœ
  • ํŒ€ ๊ณต์œ ์šฉ ๋ณด๊ณ ์„œ ํ…œํ”Œ๋ฆฟ
  • ํŠน์ • finding ๋ฐœ์ƒ ์‹œ Slack/์ด๋ฉ”์ผ ์•Œ๋ฆผ

Releases

Packages

Contributors

Languages