아카이브 / 개발
web-service-analyzer — 증거 기반 웹서비스 분석 도구
목차 — 프로젝트 요약 · 담당 범위 · 문제와 구현 접근 · 이 작업에서 한 일 · 결과물과 원문 · 구현 상세
프로젝트 요약
공개 서비스 URL을 read-only로 크롤링해 사이트 그래프·API 스키마를 근거로 Codex에게 서비스 분석을 요청하는 도구. 커버리지 검증 기준을 명시적으로 정의했다.
담당 범위
기획·설계·개발을 맡은 개인 프로젝트다. 공개 저장소에서 코드와 사용 방법을 확인할 수 있다.
문제와 구현 접근
Playwright로 서비스를 순회하며 관찰된 사이트 그래프를 구축하고, 프라이버시를 최소화한 API 스키마를 캡처한다. GET·HEAD·OPTIONS만 허용하는 읽기 전용 탐색이며, POST·폼 제출·로그인 라우트·다운로드는 차단된다.
'complete crawl'을 링크 프론티어 소진·깊이 제한 미적용·사이트맵 탐색 성공·페이지 한도 미도달 네 조건을 모두 만족할 때만 coverage_verified=true로 표기하도록 정의해, 통과한 실행이 곧 전체 커버리지의 증명이 아니라는 점을 코드로 구분해 남긴다.
이 포트폴리오 전체가 따르는 '공개/익명화/비공개 경계'와 같은 증거주의 원칙을 웹서비스 분석 도구로 구현한 결과물이다.
이 작업에서 한 일
아이디어를 실제로 작동하는 코드로 만들고, 다른 사람이 설치하고 사용할 수 있도록 설명서를 함께 작성했다.
결과물과 원문
관련 등록공보·논문·저장소는 아래 링크에서 볼 수 있다.
구현 상세
README공개 저장소의 구조·기능·실행 문서
Web Service Analyzer
Web Service Analyzer accepts public service URLs, visits each service in input order, builds an observed site graph, captures privacy-minimized API schemas, analyzes every fetched page's rendered HTML/DOM structure, and asks Codex for an evidence-linked service analysis.
The default collector uses Playwright because many services expose navigation and data only after JavaScript renders. It performs read-only browser navigation: only GET, HEAD, and OPTIONS requests are allowed. POST and other non-idempotent requests, WebSockets, downloads, login routes, and form submissions are blocked.
When a site requires login or human verification, explicit --human-assisted mode opens a visible browser. The operator completes that step manually, confirms resume in the terminal, and the crawler continues in the same in-memory browser session. The handoff traffic is excluded from evidence and the read-only network boundary is restored before automated traversal resumes.
What “complete crawl” means
The crawler follows every unique, same-origin, safe link observed in rendered pages, plus same-origin URLs found in robots.txt and XML sitemaps. Query strings and fragments are removed so tracking values and filter permutations do not create an unbounded crawl.
coverage_verified=true is reported only when all of these are true:
- the URL frontier is exhausted;
- no page was omitted by the depth limit;
- XML sitemap discovery succeeded and was not truncated; and
- the page limit was not reached.
If a service blocks or omits its sitemap, the analyzer can exhaust the observed link graph but cannot prove that it found unlinked pages. The manifest and report preserve that distinction; a passing run or a generated report is never treated as proof of whole-site coverage.
Artifacts
Each run creates an ignored runs/<run-id>/ directory:
manifest.json
01-example-com/
manifest.json
evidence/
page-001.json
screenshots/page-001.png
page-analysis/
page-001.json
api-inventory.json
sitemap.json
sitemap.md
analysis-input/evidence.json
analysis.json
report.md
codex-events.jsonl
Per-page analysis includes tag counts, headings, landmarks, forms, controls, scripts, language/canonical metadata, basic accessibility signals, and the APIs observed while that page loaded. The API inventory stores method, origin, path template, query-key names, first/third-party classification, status codes, and JSON field/type shapes. It never stores cookies, authorization headers, query values, or JSON values.
Requirements and install
- Python 3.11 or newer
- Codex CLI authenticated with
codex login - Playwright Chromium (installed separately from the Python package)
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
playwright install chromium
web-service-analyzer doctor
To use a locally installed Chrome instead, pass --browser-channel chrome to doctor and run.
Run
Run one service with the default 100-page, depth-8 boundary:
web-service-analyzer run --url https://example.com
Human-assisted access
Run this from an interactive terminal on a machine with a display:
web-service-analyzer run \
--url https://example.com \
--human-assisted \
--auth-artifact-mode structure-only
The flow is:
- A visible, isolated browser opens the service.
- The terminal pauses while the operator completes login, MFA, consent, or a
human-verification challenge directly in the browser.
- The operator returns to the target service and presses Enter in the terminal.
- The crawler automatically scrolls and follows safe same-origin links, preferring
real rendered-link clicks when available, then captures structure and observed API schemas.
- If another recognizable challenge appears, the crawler can request up to two more
operator handoffs by default.
The application never reads or stores credentials, CAPTCHA answers, cookies, authorization headers, or handoff request/response bodies. Session state is kept only in the browser process and is discarded at the end of the run.
Human-assisted evidence defaults to redacted. Use structure-only to omit page titles, body text, headings, link labels, and button labels while retaining structural counts, URLs, navigation edges, and API field/type schemas. Screenshots are disabled for human-assisted runs unless separately authorized with --auth-screenshots. Human-assisted run directories use owner-only permissions (0700 directories and 0600 files); review them before sharing.
Use a larger explicit boundary when the target permits it:
web-service-analyzer run \
--url https://example.com \
--max-pages 500 \
--max-depth 20 \
--delay 1
The hard safety ceiling is 10,000 pages per service. Every fetched page still receives its own deterministic page-analysis artifact. For runs above 100 pages, the global Codex synthesis automatically uses representative pages and complete site-wide counts so model input remains bounded; the manifest and model-input scope disclose that sampling separately from crawl coverage.
Repeat --url or use a newline-delimited file to process multiple services strictly in order:
web-service-analyzer run \
--url https://example.com \
--url https://example.org
web-service-analyzer run --urls-file services.txt
Useful modes:
--dry-run: validate URL syntax and show execution order without network calls.--collect-only: generate crawl, page, API, and sitemap artifacts without Codex.--engine http: legacy server-HTML collector; it cannot verify rendered coverage.--no-screenshots: omit page screenshots while retaining structural evidence.--human-assisted: pause a visible browser for operator login or verification.--auth-artifact-mode structure-only: minimize authenticated page text.--auth-screenshots: explicitly retain authenticated-session screenshots.
If collection succeeded but Codex analysis failed or was interrupted, retry from the saved artifacts without sending any new request to the target:
web-service-analyzer analyze-existing \
--service-dir runs/<run-id>/01-example-com
The command exits nonzero for partial as well as failed, so unattended automation cannot mistake bounded or unverifiable coverage for completion.
Safety and limitations
- Analyze only services you are authorized to access and follow their terms.
- Targets must resolve only to public IP addresses and use standard HTTP(S) ports.
- Top-level navigation stays on the canonical service origin; assets and observed APIs
may use other public origins.
- An available
robots.txtis enforced. Unavailable policy and sitemap endpoints are
explicit evidence gaps.
- Page content is untrusted input. The Codex analysis receives embedded evidence,
web search is disabled, and a per-run hook denies model-initiated local tools.
- Automated traversal performs navigation and scrolling but does not activate
application, purchase, save, delete, permission, or submission controls. APIs triggered only by state-changing interaction remain outside the evidence boundary.
- Human-assisted mode does not automate CAPTCHA, credential entry, MFA, consent, or
other identity assertions; the operator performs and owns those actions.
- DNS validation reduces SSRF risk but cannot eliminate DNS rebinding races. Use a
network-restricted runner for hostile targets.
- Output is product/UX/technical analysis, not a vulnerability assessment or proof of
product impact.
Development
PYTHONPATH=src python3 -m unittest discover -s tests -v
PYTHONPATH=src python3 -m compileall -q src
PYTHONPATH=src python3 -m web_service_analyzer doctor
PYTHONPATH=src python3 -m web_service_analyzer run \
--url https://example.com --max-pages 2 --dry-run
See docs/PLAN.md for the release boundary and validation gates.
License
MIT