내가 쓰는 브라우저가 곧 취약점 스캐너가 된다면?

이군·2026년 4월 25일

일상의 호기심이 보안 도구가 되기까지

보안 엔지니어로 일하면서 늘 하나의 질문이 머릿속에 있었다.

"내가 매일 쓰는 브라우저로 웹 서핑하는 그 트래픽 자체를 분석하면, 실제로 취약점이 보일까?"

Burp Suite를 켜고, 타겟을 설정하고, 스코프를 잡고, 리피터로 요청을 하나하나 뜯어보는 전통적인 방식. 물론 강력하다. 하지만 그건 "테스트를 하겠다"고 마음먹은 순간에만 작동하는 방식이다. 나는 그냥 평소에 웹 서핑하다가, 뉴스를 보다가, 쇼핑몰을 둘러보다가 — 그 흐름 그대로 취약점을 발견할 수 있으면 어떨까 하는 생각이 들었다.

그래서 만들어봤다. LLM-HOOK-BROWSER.


아이디어의 출발점: dmass 스캐너

이미 나는 dmass라는 LLM 기반 자동화 보안 스캐너를 만들어 운영하고 있었다. dmass는 꽤 정교한 도구다. SQLi 5단계 탐지, SSTI 8개 엔진별 핑거프린팅, JWT 7가지 공격 벡터, WAF 벤더별 우회 전략, OOB 콜백 서버까지 — 본격적인 침투 테스트를 위한 풀스택 스캐너다.

그런데 dmass는 "스캔을 실행한다"는 행위가 전제된다. 타겟 URL을 넣고, 스코프를 정의하고, 프로필을 선택해서 돌린다. 이건 업무용이다.

내가 원했던 건 달랐다. 의식하지 않아도 작동하는 보안 센서. 내 브라우저가 곧 스캐너가 되는 것.

dmass에서 검증된 탐지 알고리즘들 — SQL 에러 시그니처 20여 종, NoSQL 연산자 인젝션 패턴, 컨텍스트별 XSS 페이로드, 클라우드 메타데이터 프로빙, CVSS v3.1 계산 공식 — 이것들을 가져와서, 브라우저 프록시 위에 얹으면 어떨까?


어떻게 동작하는가

구조는 단순하다.

크롬 브라우저 (프록시 설정)
    ↓
mitmproxy (HTTPS 트래픽 복호화)
    ↓
2단계 분석 파이프라인
├── Stage 1: 알고리즘 사전분석 (패턴 매칭)
└── Stage 2: Claude Sonnet 정밀분석
    ↓
실시간 대시보드

크롬을 프록시 모드로 띄우면, 내가 방문하는 모든 사이트의 HTTP/HTTPS 트래픽이 mitmproxy를 통과한다. 여기서 SecurityInterceptor가 의미 있는 요청(POST, 쿼리 파라미터가 있는 GET 등)을 골라서 DB에 저장한다.

저장된 각 요청은 2단계 파이프라인을 거친다.

Stage 1: 알고리즘 사전분석

LLM을 호출하기 전에, 20개의 패턴 매칭 검사기가 먼저 빠르게 스캔한다.

  • SQL 에러 시그니처 24종 (MySQL, MSSQL, Oracle, PostgreSQL, SQLite)
  • NoSQL 연산자 패턴 ($gt, $ne, $regex, $where)
  • XSS 반사 탐지 — 입력값이 응답에 이스케이프 없이 반영되는지
  • JWT 토큰 분석 — alg:none, 빈 서명, 약한 알고리즘
  • SSRF 지표 — 169.254.169.254, 내부 IP, file:// 프로토콜
  • 시크릿 패턴 13종 — AWS 키, GitHub 토큰, Stripe 키, DB 커넥션 스트링
  • 보안 헤더 6종 누락 검사
  • 쿠키 보안 속성 (HttpOnly, Secure, SameSite)
  • CORS 오류설정, CSRF 토큰 부재, 기술 핑거프린팅

이 단계는 밀리초 단위로 끝난다. 여기서 나온 힌트들은 다음 단계의 LLM에게 "이쪽을 집중해서 봐"라는 가이드가 된다.

Stage 2: LLM 정밀분석

Claude Sonnet이 HTTP 트랜잭션 전체(요청 헤더, 바디, 응답 헤더, 바디)를 읽고, 35개 취약점 카테고리에 대해 정밀하게 판단한다. 단순히 "취약점이 있다/없다"가 아니라:

  • 구체적인 공격 시나리오 (step-by-step)
  • CVSS v3.1 벡터와 점수
  • OWASP Top 10 2021 매핑
  • CWE ID
  • 실제 증거 (요청/응답에서 추출)
  • 구체적인 수정 방법

사전분석의 힌트와 LLM의 판단을 신뢰도 병합 공식으로 결합한다. 둘 다 독립적으로 탐지했으면 신뢰도가 올라가고, 한쪽만 탐지했으면 적절히 가중된다.


실제로 돌려본 결과

샘플사이트를 타겟으로 설정하고, 크롬으로 평소처럼 사이트를 둘러봤다. 메인 페이지를 보고, 몇 개 상품을 클릭하고, 검색을 해봤다. 특별한 공격 시도 없이, 그냥 일반 사용자처럼.

18개 요청이 캡처되었고, 33개 취약점이 발견되었다.

심각도건수발견 내용
MEDIUM12IDOR/BOLA (예측 가능한 stayId), Insecure Cookies, Security Header 누락
LOW14CORS 설정 이슈, Sentry DSN 노출, 내부 메타데이터 노출
INFO7보안 헤더 미설정

흥미로웠던 것들:

1. IDOR/BOLA 가능성 — URL에 순차적 정수 ID(xxxId)가 노출되어 있어서, ID를 변경하면 다른 상품의 비공개 정보에 접근할 수 있는지 추가 검증이 필요한 상태.

2. Sentry DSN 공개키 노출 — Cloudflare RUM 요청 헤더에 Sentry DSN이 포함되어 있었다. 공개키 자체는 치명적이지 않지만, 내부 프로젝트 구조를 유추할 수 있는 정보.

3. 세션 쿠키 보안 속성테스트사이트의 sid 쿠키에 HttpOnly, Secure, SameSite 속성이 불완전할 가능성이 탐지됨.

4. CORS with Credentials — Origin 반영 동작이 감지되어, 악의적 사이트에서 인증된 요청을 보낼 수 있는지 추가 확인 필요.

이 모든 게 그냥 웹 서핑만 했을 뿐인데 나온 결과다.


200개가 넘는 내장 페이로드

dmass의 attack playbook에서 가져온 페이로드 데이터베이스가 내장되어 있다.

  • SQLi 30종 — 에러 기반, 불린 블라인드, 타임 블라인드(DB별), UNION, WAF 우회
  • XSS 컨텍스트별 — HTML body, attribute, script block, URL, JSON 각각 다른 페이로드
  • SSTI 엔진별 — Jinja2, Twig, Freemarker, Velocity, Spring EL, ERB, Mako
  • JWT 7가지 공격 — alg:none, RS256→HS256, kid injection/traversal, jku injection
  • SSRF 클라우드별 — AWS IMDSv1/v2, GCP, Azure, ECS, K8s
  • Command Injection — 인라인, 타임 블라인드, OOB, 마커 기반

취약점이 발견되면, 이 페이로드 DB에서 적절한 것을 선택해 LLM에게 "이런 페이로드로 검증해봐"라고 제안하고, 안전한 시뮬레이션을 실행할 수 있다.


CVSS가 자동으로 붙는다

모든 취약점에 CVSS v3.1 점수가 자동 산출된다. dmass의 CVSS 계산기를 그대로 포팅했다.

SQL Injection  → CVSS 9.8 (Critical)
SSRF           → CVSS 8.6 (High)
SSTI           → CVSS 9.8 (Critical)
JWT alg:none   → CVSS 9.1 (Critical)
IDOR           → CVSS 7.1 (High)
XSS            → CVSS 6.1 (Medium)

LLM이 CVSS 벡터를 직접 제시하면 그걸 쓰고, 아니면 취약점 유형에 매핑된 기본 벡터로 계산한다. 30개 이상의 취약점 유형에 대한 기본 벡터가 내장되어 있다.


기술적으로 재미있었던 점들

mitmproxy와 asyncio의 충돌

mitmproxy 11은 자체 이벤트 루프를 요구하는데, FastAPI(uvicorn)도 자체 루프를 돌린다. 별도 스레드에서 mitmproxy를 돌리되, DumpMaster에 이벤트 루프를 명시적으로 주입하는 방식으로 해결했다.

사전분석의 오탐 제어

처음에는 응답 본문에서 /usr/bin/ 같은 경로가 보이면 Command Injection으로 잡았는데, 일반 HTML 페이지에서도 이런 문자열이 나올 수 있다. 요청에 공격 패턴이 없으면 응답에서만 탐지된 결과는 무시하도록 수정했다. "입력에 원인이 있어야 출력의 결과를 의심한다"는 원칙.

Bearer Token 인증

AWS Bedrock을 쓰는데, 일반적인 AWS Signature V4가 아닌 Bearer Token 방식이었다. Anthropic SDK가 이걸 직접 지원하지 않아서, httpx로 Bedrock REST API를 직접 호출하는 경로를 추가했다.

신뢰도 병합

사전분석(알고리즘)과 LLM이 독립적으로 판단한 신뢰도를 어떻게 합칠 것인가? 단순 평균이 아니라, 독립 사건의 결합 확률 공식을 사용했다:

merged = 1 - (1 - conf_llm) × (1 - conf_pre)

둘 다 0.8이면 0.96으로 올라간다. 한쪽이 0이면 다른 쪽 값 그대로. 직관적이면서도 수학적으로 타당하다.


이 시대에 우리가 할 수 있는 것

솔직히 말하면, 이 도구를 만드는 데 걸린 시간은 놀라울 정도로 짧았다.

dmass에서 검증된 알고리즘이 있었고, LLM이 복잡한 프롬프트 엔지니어링을 대신 소화해줬고, mitmproxy라는 훌륭한 오픈소스가 HTTPS 인터셉트를 해결해줬다. 내가 한 것은 이것들을 "내 브라우저로 서핑하면서 취약점을 찾고 싶다"라는 하나의 아이디어로 연결한 것뿐이다.

우리는 지금 일상의 아이디어가 하루 만에 동작하는 도구가 되는 시대에 살고 있다.

"이거 되면 좋겠다"라는 생각이 드는 순간, 그걸 실제로 만들어볼 수 있는 환경이 갖춰져 있다. LLM이 코드를 짜고, 오픈소스가 인프라를 제공하고, 클라우드가 컴퓨팅을 댄다. 우리에게 필요한 건 딱 하나 — "이거 해보면 어떨까?"라는 호기심이다.

그 호기심을 코드로 옮기는 속도가, 지금 이 시대가 우리에게 준 가장 강력한 무기다.

보안이든, 데이터든, 자동화든 — 당신이 매일 하는 일에서 "이거 자동으로 되면 좋겠다"라고 느끼는 그 순간이 있다면, 그게 다음 도구의 시작점이다. 더 이상 "나중에"가 아니라 "지금 바로" 시도해볼 수 있다.

내 브라우저가 취약점 스캐너가 된 것처럼, 당신의 일상 도구도 무언가 더 될 수 있다.


링크

  • GitHub: github.com/lufianlee/LLM-HOOK-BROWSER
  • 기술 스택: Python, FastAPI, mitmproxy, Claude Sonnet (AWS Bedrock), SQLAlchemy, WebSocket
  • 탐지 범위: 35종 취약점, 200+ 페이로드, CVSS v3.1 자동 산출, OWASP Top 10 2021 매핑
profile
이군의 보안, 그리고 생각을 다룹니다.

0개의 댓글