C.W.K.
Stream
Lesson 02 of 05 · published

Origin 과 localhost 함정

~22 min · origin, localhost, dns-rebinding, cors

Level 0호기심 많은 독자
0 XP0/48 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

http://127.0.0.1:port 에 도는 로컬 MCP server 가 무해해 보임. 안 무해. 명시적 방어 없으면 — 어떤 브라우저 탭의 웹페이지가 — 로컬 MCP server 와 대화해 데이터 빼갈 수 있어. DNS rebinding, 악의적 origin header, sloppy CORS 통해.

MCP spec 명시: localhost 에 bound 된 server 는 모든 request 의 Origin header 검증 MUST, allowlist 외 거 거절. Default allowlist 비어있음. 없으면 https://evil.example.com 페이지가 fetch('http://127.0.0.1:1234/mcp', {…}) 할 수 있고 — server 가 user install 한 모든 tool 충실히 제공.

DNS rebinding 이 더 정교한 공격. 공격자가 — DNS response 가 외부 IP (초기 페이지 로드용) 와 127.0.0.1 (낮은 TTL 후) 사이 깜빡이는 — 도메인 등록. 브라우저 cached origin 은 여전히 'evil.example.com' 인데 네트워크 호출은 user 의 로컬 server 에 도착. Host header 를 — allowlist (e.g. localhost127.0.0.1 만) 에 — 검증하면 막힘; Origin 만 의존해선 안 막힘.

로컬 server 는 명시적으로 127.0.0.1 에 bind, 절대 0.0.0.0 X. 모든 request 에 OriginHost 검증. CORS preflight 아닌 path 에 Origin 빠진 거 거절. 대략 6 줄 middleware 고 그 중 어느 것도 optional 아님.

Code

엄격한 origin & host 검증 (FastAPI middleware)·python
from fastapi import Request, HTTPException

ALLOWED_ORIGINS = {"app://claude-desktop", "https://localhost:5173"}
ALLOWED_HOSTS = {"127.0.0.1", "localhost"}

@app.middleware("http")
async def origin_host_guard(request: Request, call_next):
    origin = request.headers.get("origin", "")
    host = request.url.hostname or ""
    if origin and origin not in ALLOWED_ORIGINS:
        raise HTTPException(403, "origin not allowed")
    if host not in ALLOWED_HOSTS:
        raise HTTPException(403, "host not allowed")
    return await call_next(request)
127.0.0.1 에 bind, 0.0.0.0 X·python
# 맞음
uvicorn.run(app, host="127.0.0.1", port=1234)

# 잘못 — 로컬 네트워크와 모든 인터페이스에 server 노출
uvicorn.run(app, host="0.0.0.0", port=1234)

External links

Exercise

Origin/Host 검증 없이 0.0.0.0:port 에 작은 로컬 MCP server 돌려. 완전 무관한 사이트 (file:// 또는 control 가능 public 사이트) 의 별도 브라우저 탭에서 devtools 열고 fetch('http://127.0.0.1:port/mcp') 시도. 성공하는 거 봐. 그 다음 127.0.0.1 에 bind 하고 middleware 추가. 실패하는 거 봐. 연습이 교훈.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.