한양과학기술고등학교

에듀테크 프로젝트 대시보드

클릭재킹 (Clickjacking)

🖱️ 클릭재킹 (Clickjacking)

"네가 누른 건 이 버튼이 아니야." — 투명하게 만든 다른 사이트를 미끼 버튼 위에 겹쳐 두고, 사용자의 클릭을 가로채(hijack) 원하지 않는 행동을 시키는 UI 공격.

공격자 페이지 evil.example

🎁 축하합니다! 무료 상품 당첨

아래 버튼을 누르면 최신 스마트폰을 무료로 받을 수 있어요.
딱 한 번만 누르면 끝!

* 이벤트는 예고 없이 종료될 수 있습니다.
🔒 sns.example — 계정 설정

정말 계정을 삭제할까요?

이 작업은 되돌릴 수 없으며 모든 게시물이 사라집니다.

이 페이지는 프레임에 표시할 수 없습니다
Refused to display in a frame
(X-Frame-Options / frame-ancestors)
0
몰래 삭제됨
0
차단/자각됨
// 미끼 버튼을 눌러 보세요…
공격 조정 & 방어
공격자는 이 값을 0% 로 낮춰 iframe을 눈에 안 보이게 만듭니다.
숨긴 버튼을 미끼 버튼 바로 위로 옮기면 클릭이 정확히 가로채집니다.
공격 시나리오
  1. 공격자가 evil.example 에 화려한 미끼 버튼("지금 받기")을 만든다.
  2. 그 위에 <iframe> 으로 피해자 사이트(로그인된 sns.example)를 얹는다.
  3. iframe 을 opacity:0 으로 투명하게, 위험 버튼을 미끼 위에 정렬한다.
  4. 사용자가 "지금 받기"를 누르면 실제로는 계정 삭제 버튼이 눌린다.
  5. 이미 로그인된 세션 쿠키가 자동 전송돼 서버는 정상 요청으로 처리한다.

방어 ① 프레임 차단 헤더 권장

서버가 응답에 "나를 다른 사이트의 프레임 안에 넣지 마"라고 지시하는 헤더를 붙입니다. 브라우저가 강제합니다.

  • X-Frame-Options: DENY — 어떤 사이트도 프레임 금지 (구형·호환용)
  • Content-Security-Policy: frame-ancestors 'none' — 최신 표준, 세밀한 허용 목록 가능
  • frame-ancestors 'self' https://admin.example — 특정 출처만 허용
# FastAPI: 모든 응답에 프레임 차단 헤더 추가 from starlette.middleware.base import BaseHTTPMiddleware class FrameGuard(BaseHTTPMiddleware): async def dispatch(self, request, call_next): resp = await call_next(request) resp.headers["X-Frame-Options"] = "DENY" resp.headers["Content-Security-Policy"] = \ "frame-ancestors 'none'" return resp app.add_middleware(FrameGuard)

보조 방어 & 흔한 오해

  • SameSite=Lax/Strict 쿠키 — iframe 안 요청에 쿠키가 안 실려 많은 공격을 막지만, 같은 사이트 내 클릭재킹이나 GET 기반 동작은 못 막음.
  • 중요 동작에 확인 단계 — "정말 삭제할까요? 비밀번호 입력" 같은 재인증은 한 번의 클릭 탈취를 무력화.
  • 프레임 버스팅 JS (if (top !== self) top.location = self.location) — sandbox 속성으로 우회 가능. 헤더가 정답.
  • "HTTPS 쓰니까 안전" — 클릭재킹은 암호화와 무관. UI 계층 공격이다.

변종: 좋아요를 가로채는 Likejacking, 커서 위치를 속이는 Cursorjacking, 드래그로 데이터를 빼내는 Drag&Drop 재킹 등.