개인 프로젝트2026.10 — 진행 중

문단속

기업 외부 노출 점검 서비스

회사 도메인을 넣으면 공격자가 밖에서 먼저 보게 될 약점을 찾아 쉬운 말로 알려 주는 외부 노출 점검 서비스다. 요구사항 · 역할 · 일정을 기획 산출물로 먼저 설계하고, 이슈 · 마일스톤 · PR 단위로 개발하고 있다.

GitHub ↗서비스 보기 ↗

문단속 키 비주얼 — 점검 리포트(점수 50/100): 점검 5종 탭과 보안 헤더 상세(HSTS · nosniff · Referrer-Policy 통과, CSP · X-Frame-Options 없음과 설정 예시)

한눈에 보기

기간
2026.10 — 진행 중
형태
개인 프로젝트
진행
M1 점검 엔진 완료 — WBS 이슈 21개 중 10개 완료
기술
Java 21 · Spring Boot 4.1 · Spring Data JPA · Flyway · PostgreSQL(테스트 H2) · GitHub Actions

직접 만든 기능

  • 도메인 등록과 DNS TXT 소유 인증
  • 점검 요청 10분 제한 · 커밋 뒤 비동기 실행
  • 점검 5종 — TLS 인증서 · HTTPS 전환 · 보안 헤더 · 민감 파일 노출 · SPF/DMARC
  • 내부망 주소 차단(SSRF 가드)
  • 점수(100점 감점제)와 위험도순 결과 API
  • 기획 산출물 10종 — 헌장 · R&R · 요구사항 · 유저 스토리 · 아키텍처 · ERD · API · WBS · 리스크 · 협업 규칙

화면

화면(Next.js)은 다음 단계에서 만든다. 지금은 기획 산출물(docs/planning)을 이미지로 정리했다

  • 시스템 아키텍처

    구성도와 설계 결정

  • 점검 흐름

    요청 → 비동기 점검 → 결과 시퀀스

  • ERD

    domain · scan · finding

  • WBS · 8주 일정

    스프린트 4개 · 마일스톤 4개

  • 역할 R&R

    역할 5개 · RACI

시스템 아키텍처1 / 5

문단속 시스템 구성도 — 사용자 · Next.js · Spring Boot API(DomainService · ScanService · ScanRunner) · AddressGuard · 점검 대상 · DNS · PostgreSQL · LLM

구성도와 설계 결정

흐름

점검 상태 흐름

  1. QUEUED점검 대기
  2. RUNNING점검 5종 실행
  3. DONE점수 · 결과 저장
  • 소유 인증 전 → 403 DOMAIN_NOT_VERIFIEDTXT 레코드로 인증한 도메인만 점검
  • 10분 안 재요청 → 429 SCAN_COOLDOWN남은 시간을 알려 줌
  • RUNNING → FAILED인증 뒤 DNS가 내부 IP로 바뀌면 점검 전체를 멈춤
  • 점검 하나 실패 → INFO 항목나머지 점검은 계속하고 결과에 "점검을 끝내지 못함"으로 남김

점검 요청은 바로 202로 응답하고, 실제 점검은 트랜잭션이 커밋된 뒤 별도 스레드 풀에서 돈다.

문제 해결 과정

공격 도구가 되지 않게 — 소유 인증 · 내부망 차단

  1. 문제

    점검 서비스는 그대로 남의 사이트를 정찰하는 도구가 될 수 있고, 점검 요청이 내부망 주소를 향하면 SSRF가 된다

  2. 해결 — 무엇을 바꿨나

    DNS TXT 레코드로 소유를 인증한 도메인만 점검하고, 요청 직전 호스트가 풀리는 모든 IP를 검사해 사설 · 루프백 · 링크 로컬 · CGNAT · IPv6 ULA면 막았다. 리다이렉트는 따라가지 않고 본문은 앞 2KB만 읽는다

  3. 결과

    인증 전 점검은 403, 내부 주소는 등록 단계에서 거절하고, 점검 중 내부 IP로 바뀌면 점검 전체를 멈춘다(테스트로 확인)

오탐 줄이기 — 상태 코드가 아니라 본문으로 판정

  1. 문제

    모든 주소에 200과 안내 페이지를 주는 SPA에서 /.env가 200이라는 이유로 노출로 보면 오탐이 된다

  2. 해결 — 무엇을 바꿨나

    경로마다 실제 파일 형식(ref: refs/, KEY=값 줄, propertySources 등)이 본문에 있어야 노출로 판정했다. DNS 조회가 실패하면 "레코드 없음"이 아니라 "확인 실패"로 따로 알린다

  3. 결과

    SPA처럼 응답하는 사이트에서 오탐 없음, 노출 결과에는 비밀 값을 담지 않는다(테스트로 확인)

점검을 늘려도 흔들리지 않는 구조

  1. 문제

    점검 항목은 계속 늘어나는데, 외부 네트워크에 기대는 코드는 테스트가 느리고 불안정하다

  2. 해결 — 무엇을 바꿨나

    점검 하나를 Check 인터페이스 하나로 두고, HTTP · TLS · DNS 접근은 인터페이스 뒤로 숨겨 테스트에서 가짜 구현으로 바꿨다. 점검은 트랜잭션 커밋 뒤 별도 스레드 풀에서 돌려 API 응답과 분리했다

  3. 결과

    네트워크 없이 테스트 51개가 돌고, 등록 → 인증 → 점검 → 결과 흐름까지 통합 테스트로 확인한다

설계 결정

  • 판정은 규칙, AI는 설명만

    같은 응답이면 같은 점수가 나오도록 판정은 규칙으로 하고, AI는 4단계에서 결과를 쉬운 말로 풀어 주는 데만 쓴다.

  • 기획 · 일정 관리

    역할 5개(RACI) · 마일스톤 4개 · WBS 이슈 21개로 나누고, PR 템플릿에 점검 윤리 체크리스트를 넣었다.

검증

  • 단위 · 통합 테스트

    점검마다 정상 · 문제 · 오탐 사례를 가짜 HTTP · DNS · TLS로 검증하고, H2 + Flyway 위에서 MockMvc로 등록부터 결과까지 돌린다. GitHub Actions에서 PR마다 실행한다.

← 프로젝트 목록으로