사용자를 속이고 경고를 우회하는 현대식 SVG 클릭재킹 공격
(lyra.horse)- SVG 필터를 이용한 새로운 클릭재킹 기법이 제시되며, 기존 단순 클릭 유도 공격을 복잡한 상호작용형 공격으로 확장함
-
feColorMatrix,feDisplacementMap등 SVG 필터 요소들이 cross-origin iframe에도 적용 가능함이 확인되어, 이를 통해 시각적 조작과 데이터 추출이 가능함 - 필터 조합으로 픽셀 판독, 논리 연산, 조건 기반 UI 조작이 가능해져, 다단계 클릭재킹이나 입력 유도형 공격을 구현할 수 있음
- 실제 사례로 Google Docs 취약점을 이용한 공격이 성공해, 연구자는 Google VRP로부터 $3133.70 보상을 받음
- 이 기법은 브라우저 보안 모델의 새로운 공격면을 드러내며, SVG 필터의 논리적 활용이 보안 위협으로 발전할 수 있음을 보여줌
SVG 클릭재킹의 개요
- 기존 클릭재킹은 iframe을 덮어 사용자가 의도치 않게 클릭하도록 유도하는 단순한 공격 구조
- 새로 제시된 SVG 클릭재킹은 SVG 필터를 이용해 복잡한 상호작용과 데이터 유출을 가능하게 함
-
feColorMatrix와feDisplacementMap같은 필터가 cross-origin 문서에도 적용되어, 외부 콘텐츠를 시각적으로 조작할 수 있음
SVG 필터의 구성 요소
- 주요 필터 요소로 <feImage> , <feFlood> , <feOffset> , <feDisplacementMap> , <feGaussianBlur> , <feTile> , <feMorphology> , <feBlend> , <feComposite> , <feColorMatrix> 등이 있음
- 이들은 입력 이미지를 조합·변형해 새로운 이미지를 생성하며, 체인 형태로 연결 가능
- 이러한 조합을 통해 공격자가 시각적 효과, 마스킹, 색상 조작 등을 자유롭게 구현 가능
공격 예시
-
가짜 캡차(fake captcha) :
feDisplacementMap을 이용해 텍스트를 왜곡시켜 사용자가 민감한 코드를 입력하도록 유도 -
회색 텍스트 숨기기(grey text hiding) :
feComposite와feMorphology로 입력창의 안내문이나 오류 문구를 제거해 사용자가 공격자가 지정한 비밀번호를 입력하도록 유도 - 픽셀 판독(pixel reading) : 특정 픽셀의 색상을 감지해 필터 동작을 제어함으로써, 버튼 클릭·호버·입력 상태 감지 등 동적 반응형 공격 구현
논리 연산과 복합 공격
-
feBlend와feComposite를 조합해 AND, OR, XOR, NOT 등의 논리 게이트 구현 가능 - 이를 통해 SVG 필터 내에서 완전한 논리 회로를 구성할 수 있으며, 다단계 클릭재킹 시나리오를 자동화 가능
- 예시로 ‘Securify’ 앱 공격에서는 대화상자 열림, 체크박스 클릭, 버튼 클릭 등 여러 단계를 논리적으로 제어해 사용자를 속이는 구조를 구현
실제 사례: Google Docs 취약점
- Google Docs에서 “Generate Document” 버튼 클릭 후 나타나는 팝업과 입력창을 SVG 필터 기반 논리로 감지·조작
- 입력창의 포커스 상태, 회색 텍스트, 로딩 화면 등을 실시간으로 감지해 공격 흐름을 제어
- 이 공격으로 Google에 보고되어 $3133.70의 버그 바운티 지급
QR 코드 응용
- SVG 필터 내에서 QR 코드 생성 로직을 구현해, 픽셀 데이터를 URL로 인코딩 후 QR 형태로 표시 가능
- 사용자가 QR을 스캔하면 공격자가 제어하는 서버로 데이터가 전송됨
-
feDisplacementMap과 Reed–Solomon 오류 정정을 이용해 스캔 가능한 QR 코드 생성
추가 활용 가능성
- 텍스트 판독, 클릭 기반 데이터 유출, 가짜 마우스 커서 삽입 등 다양한 공격 응용 가능
- JavaScript 없이 CSS/SVG만으로도 공격 구현 가능해 CSP 우회 가능성 존재
연구적 의의
- SVG 필터를 이용한 논리 연산 기반 클릭재킹은 기존 연구에서 다루지 않은 새로운 공격 기법
- 과거 연구들은 SVG를 단순 시각적 가림 용도로만 언급했으나, 본 연구는 논리 실행과 상호작용 제어를 입증
- 연구자는 이를 새로운 취약점 클래스로 제시하며, 브라우저 보안 체계의 재검토 필요성을 강조
마무리
- 본 연구는 SVG 필터를 프로그래밍 언어처럼 활용한 첫 보안 공격 사례로 평가됨
- 저자는 2025년 말 39c3 및 Disobey 2026에서 관련 발표 예정
- 포스트는 이미지·JS 없이 42kB의 HTML/CSS/SVG만으로 작성, 실험적 보안 연구의 창의성을 보여줌
Hacker News 의견
-
개발자가 X-Frame-Options 헤더를 제대로 설정하면 이런 문제는 해결됨
하지만 현실적으로는 보안 문제를 쫓다가 브라우저에서 SVG 스펙의 절반을 삭제하는 식으로 대응할 것 같음- 완전히 해결된 건 아님. 일부 애플리케이션(예: Google Docs)은 프레이밍이 필요함
또 프레임이 아닌 HTML 인젝션이 가능한 사이트에서도 이런 공격이 가능함 - SVG에는 보안 지뢰가 너무 많음. 특히 사용자 제공 SVG처럼 신뢰할 수 없는 경우엔 그냥 비활성화하는 게 가장 단순함
- 완전히 해결된 건 아님. 일부 애플리케이션(예: Google Docs)은 프레이밍이 필요함
-
나는 이미 보안상의 이유로 SVG를 꺼두고 있음
그런데 요즘은 CSS까지 비활성화해야 할지도 모른다는 생각이 듦
CSS가 단순히 텍스트를 꾸미는 용도로 남아 있었으면 좋았을 텐데, 이제는 프로그래밍 언어처럼 변해서 해커나 광고주가 악용하기 쉬워졌음- “CSS를 단순하게 놔뒀으면 좋았을 텐데”라는 말에 공감하지만, 사실 이런 공격은 2000년대 후반에 훨씬 쉽게 가능했음
지금은 거의 불가능에 가까움 - 나는 보안 강화를 위해 브라우저를 망가뜨리기보다는, 민감한 데이터 자체를 브라우저 밖에 두는 게 낫다고 생각함
- 문제의 핵심은 CSS가 아니라 iFrame임. 브라우저 초창기부터 계속된 보안 취약점의 근원임
- 이 데모 외에 다른 보안 이유가 있는지 궁금함. 대부분의 플랫폼에서는 이 공격이 작동하지 않음
- 그건 과도한 대응임. 이런 공격에 걸릴 확률은 매우 낮고, 샌드박스나 세션 쿠키를 뚫을 수도 없음
- “CSS를 단순하게 놔뒀으면 좋았을 텐데”라는 말에 공감하지만, 사실 이런 공격은 2000년대 후반에 훨씬 쉽게 가능했음
-
“픽셀이 순수한 검정인지 감지해서 필터를 켜거나 끄는 예시”를 보며 완전히 혼란스러웠음
왜 HTML/CSS가 이렇게 복잡해졌는지 모르겠음
숨겨진<checkbox>와<label>이 있고, 클릭하면 체크박스가 토글되며, CSS만으로 상태에 따라 스타일이 바뀜
SVG는 실제로 아무것도 그리지 않고 필터만 정의함
<feTile>이 두 개나 쓰여서 타일 영역과 출력 영역을 따로 정의하는 구조도 이상함
<fake-frame>이나<art-frame>같은 요소는 또 뭐임?- 나는 이런 구조가 꽤 멋지다고 생각함. JavaScript 없이도 인터랙티브한 콘텐츠를 만들 수 있음
<label>클릭 시 체크박스가 토글되는 건 HTML의 기본 동작임
CSS의:has()선택자를 이용해 상태를 감지함
<feTile>은 단일 필터 요소로, 입력 이미지를 타일링하거나 크롭하는 용도로 씀
<fake-frame>과<art-frame>은 직접 정의한 커스텀 엘리먼트임
관련 내용을 블로그 글에 정리했음 - 사실 이런 기능 대부분은 “모던”이라기보다 90년대부터 존재하던 것들임
<label>클릭으로 포커스가 이동하는 건 데스크톱 UI의 전통을 따른 것임
체크박스 상태에 따라 스타일을 바꾸는 기능도 Firefox 1 시절부터 있었음
SVG 필터를 HTML에 직접 임베드하는 것도 오래된 기능임
즉, 이건 새로운 HTML의 문제라기보다 오래된 기능의 조합임
- 나는 이런 구조가 꽤 멋지다고 생각함. JavaScript 없이도 인터랙티브한 콘텐츠를 만들 수 있음
-
이 데모를 보니 예전 Flash Player 해킹이 떠올랐음
사용자가 시스템 스토리지를 허용하도록 속이던 그 방식과 비슷함
벡터 그래픽은 정말 스스로를 제어하지 못하는 존재 같음 -
SVG adder는 예술 작품 같음. 정말 멋짐
- 매우 강력한 데모였음. 오늘 처음 알았는데, Turing 완전성을 위해서는 단순히 기능적 완전성만으로는 부족하고, 저장공간과 임의 접근이 필요함을 배움
관련 내용은 Stack Overflow 글에서 참고했음
- 매우 강력한 데모였음. 오늘 처음 알았는데, Turing 완전성을 위해서는 단순히 기능적 완전성만으로는 부족하고, 저장공간과 임의 접근이 필요함을 배움
-
내 안드로이드 Chrome(정확히는 Kiwi 브라우저)에서는 다크 모드 때문인지 화면이 깨져 보이거나 이상하게 표시됨
다른 사람도 이런 현상이 있는지 궁금함- Firefox에서 Dark Reader를 꺼야 예제가 제대로 보였음
- 줌 비율이 100%가 아닐 때 QR 관련 예제가 깨짐
-
이 글을 보니 예전에 봤던 CSS 계산 데모가 떠올랐음
-
정말 인상적인 작업임. 어떻게 해결해야 할지는 모르겠지만, 빠른 시일 내에 수정이 필요함
-
너무 멋진 포스트였음. 읽는 내내 즐거웠음