내 사이트가 다른 사이트에 삽입될까요?
클릭재킹은 실제 페이지를 다른 사이트의 보이지 않는 프레임 안에 숨겨, 방문자가 모르는 사이에 버튼을 누르게 만듭니다. URL을 붙여넣어 다른 사이트가 이 페이지를 프레임에 넣을 수 있는지, 그리고 그것이 방문자에게 위험한지 확인하세요.
- X-Frame-Options
- CSP frame-ancestors
공격자가 하듯이 저희 페이지의 프레임에 이 URL을 불러온 모습입니다. 페이지가 보인다면 어떤 사이트든 똑같이 할 수 있습니다. 프레임에 "refused to connect" 같은 오류가 표시되면 브라우저가 차단한 것입니다.
이 URL은 일반 http를 사용하므로 브라우저가 https 페이지 안에 불러오지 않아 프레임은 어느 경우든 비어 있습니다. 위의 헤더 판정 결과를 기준으로 판단하세요.
해결 방법
frame-ancestors가 포함된 Content-Security-Policy를 보내고, 구형 브라우저를 위해 X-Frame-Options도 함께 보내세요. 둘 다 사이트 앞단의 웹 서버에 추가합니다.
nginx
add_header Content-Security-Policy "frame-ancestors 'self'" always;
add_header X-Frame-Options "SAMEORIGIN" always;
Apache
Header always set Content-Security-Policy "frame-ancestors 'self'"
Header always set X-Frame-Options "SAMEORIGIN"
Odoo를 운영하시나요? 'none' 대신 'self'를 사용하세요. 웹사이트 편집기가 같은 도메인의 프레임 안에 자체 페이지를 표시하기 때문입니다. CICDoo는 배포하는 모든 인스턴스에서 이 헤더를 기본으로 켭니다.
공격 방식
내 페이지, 남의 클릭
보이지 않는 프레임
공격자는 실제 페이지를 투명한 iframe에 불러와 경품 버튼이나 동영상 플레이어 같은 미끼 위에 겹쳐 놓습니다.
진짜 클릭
방문자는 이미 사이트에 로그인한 상태입니다. 그 클릭은 결제 승인, 이메일 변경, 접근 권한 부여처럼 내 페이지에서 실행됩니다.
헤더 하나로 막습니다
frame-ancestors 또는 X-Frame-Options는 어떤 사이트가 나를 프레임에 넣을 수 있는지 브라우저에 알려 줍니다. 없으면 브라우저는 누구에게나 허용합니다.
자주 묻는 질문
질문에 답해 드립니다
이 테스트는 무엇을 확인하나요?
저희 서버에서 URL을 요청해 두 가지 응답 헤더, 즉 X-Frame-Options와 Content-Security-Policy의 frame-ancestors 지시어를 읽습니다. 또한 페이지가 URL을 프레임에 불러와 내 브라우저에서 직접 결과를 볼 수 있습니다.
어떤 헤더를 사용해야 하나요?
frame-ancestors가 현대 표준이며, 있으면 항상 우선 적용됩니다. 구형 브라우저를 위해 X-Frame-Options도 유지하세요. 내 도메인만 허용하려면 'self'를, 모든 프레임을 막으려면 'none'을 사용하세요.
프레임이 왜 비어 보이나요?
일부 사이트는 프레임 삽입을 막거나, 알 수 없는 방문자에게 빈 페이지를 보여 주거나, 브라우저가 https 페이지 안에서 불러오기를 거부하는 일반 http를 사용합니다. 헤더 판정 결과는 브라우저와 무관합니다.
사이트가 프레임에 삽입될 수 있으면 취약한 건가요?
꼭 그렇지는 않습니다. 클릭재킹이 성립하려면 결제나 설정 변경처럼 중요한 동작이 있는 페이지, 로그인한 방문자, 그리고 브라우저가 다른 사이트의 프레임 안에서도 보내는 세션 쿠키가 필요합니다. 최신 브라우저는 SameSite=None이 없는 쿠키를 보내지 않으므로, 프레임에 삽입된 페이지는 보통 로그아웃 상태로 열립니다. 그래도 헤더는 추가할 가치가 있습니다. 위험을 완전히 차단하고, 보안 감사에서도 확인하는 항목이기 때문입니다.
ALLOW-FROM은 아직 지원되나요?
아니요. 최신 브라우저는 X-Frame-Options ALLOW-FROM을 무시합니다. 특정 파트너 사이트를 허용하려면 대신 frame-ancestors에 나열하세요.
URL을 저장하나요?
요청 빈도 제한을 위한 기록만 남기며, URL이나 결과는 저장하지 않습니다.