챗GPT 공유 링크 열고 버튼 한 번 누르면 공격자 코드 실행…비공개 대화 빼낼 수 있었다
노트북과 연결고리 표지, 자물쇠 그림이 놓인 책상 위 보안 안내판 — AI로 생성한 자료 이미지

챗GPT 공유 대화 링크 하나가 이용자의 로그인 세션 안에서 공격자 코드를 실행하는 통로가 될 수 있었던 것으로 드러났다. 보안업체 Parameter 연구진은 이 결함을 이용해 링크를 연 사람의 비공개 대화를 빼낼 수 있다는 점을 시연했다. 연구진은 10월 18일(현지시각) 오픈AI의 버그 바운티 프로그램(취약점 신고 보상제)으로 제보했고, 오픈AI는 8일 뒤 수정을 마치며 가장 심각한 등급인 P1로 분류했다. 이하 날짜는 모두 현지시각 기준이다.

평범한 공유 대화가 함정이 됐다

The Hacker News에 따르면 공격에 쓰인 것은 공개 링크로 공유한 평범한 챗GPT 대화였다. 진짜 공유 대화와 똑같이 이메일이나 채팅 메시지, 고객지원 티켓, 소셜미디어 게시물로 전달할 수 있었다. Parameter 기술 문서는 공격자가 진짜 인터랙티브 그래프와 어시스턴트가 작성한 HTML 미리보기(Preview)가 담긴 대화를 만들어 공유하는 것만으로 충분했다고 설명한다. 첨부물만으로는 아무 일도 일어나지 않았다.

피해자는 아무것도 설치하지 않아도 됐다. 워크스페이스에 가입할 필요도, 공격자를 거쳐 로그인할 필요도 없었다. 가장 안정적으로 작동한 방식에서 피해자가 한 일은 링크를 열고 챗GPT의 미리보기 버튼을 한 번 누르는 것뿐이었다.

이후 Parameter는 HTML 블록이 스스로 미리보기로 열리도록 설정한 버전도 만들었다. 이 버전에서는 링크를 여는 것 자체가 유일한 조작이었다. 디지빈(DigitBin)은 이 부분이 단순한 속임수를 실제 위험으로 바꾸는 대목이라고 짚었다.

조명이 켜진 어두운 실내 책상에서 노트북 자판을 누르는 손 — AI 자료 이미지

로그인 세션 안에서 무엇을 할 수 있었나

링크가 열리면 공격자 코드는 피해자의 로그인 세션 안에서 진짜 챗GPT 사이트와 같은 권한으로 실행됐다. 코드는 피해자의 최근 대화 목록을 불러왔다. 공격자에게 공유된 적 없는 비공개 대화도 열었다. 그 내용 일부는 연구진이 통제하는 서버로 전송됐다.

화면에 보이는 내용을 복사하는 방식이 아니었다. 코드는 챗GPT의 로그인 상태 API를 직접 호출했다. 디지빈에 따르면 시연에서 페이로드(공격 코드)는 부모 페이지의 세션 정보를 읽은 뒤 피해자 명의로 대화 API를 불렀고, 선택한 값을 이미지 요청 형태로 외부 서버에 보냈다.

피해자의 웹 접근 권한을 그대로 쓰기 때문에 영향 범위는 대화 열람에 그치지 않았다. 연구진은 “사실상 피해자의 챗GPT 계정을 대신해 어떤 행동이든 할 수 있었다”고 적었다. 다만 실험은 통제된 환경에서 이뤄졌다. Parameter는 실제 악용 사례를 보고하지 않았고, 비공개 대화 탈취 시연도 실제 이용자가 아닌 별개의 계정끼리 진행했다.

샌드박스는 지켜졌지만 옆문이 열려 있었다

Parameter의 설명에 따르면 챗GPT는 대화 속 HTML 블록을 미리보기 기능으로 작은 웹페이지로 바꿔 보여준다. 이 페이지에는 어떤 코드든 들어갈 수 있다. 그래서 챗GPT는 이를 별도 웹 주소의 잠금된 프레임에서 실행하고, 바깥의 메인 챗GPT 페이지는 읽지 못하게 막는다. 이 샌드박스(격리 실행 환경) 자체는 뚫리지 않았다.

침투 경로는 같은 대화에 들어 있던 다른 기능이었다. 공유 대화에는 인터랙티브 그래프가 포함돼 있었고, 이 그래프를 그리면 수학 라이브러리 MathLive가 메인 챗GPT 페이지로 로드됐다. MathLive는 화면 키보드 관련 메시지를 받는 리스너(수신 대기 코드)를 남겼다.

브라우저 프레임 사이에 오가는 메시지는 받는 쪽이 보낸 쪽을 확인할 때만 안전하다. Parameter는 이 리스너가 누가 보냈는지와 상관없이 키보드 메시지를 받아들이고, 메시지에 가공되지 않은 HTML까지 실을 수 있다는 점을 발견했다. 디지빈이 전한 문서 내용으로는 출처 정책이 “none”으로 설정돼 있었다. 샌드박스 안의 미리보기가 메시지 두 개를 보내 가상 키보드 배열을 공격자 HTML로 바꾸고 이를 표시하게 한 것이다.

해당 배열 마크업은 innerHTML로 들어갔고, 이를 막아야 할 보조 함수는 내용을 걸러내는 살균기가 아니라 입력을 그대로 돌려주는 래퍼였다고 Parameter는 밝혔다. 주입된 HTML은 샌드박스 속성이 없는 새 프레임을 만들었다. 이 프레임은 브라우저가 chatgpt.com의 일부로 취급했다.

마지막 단계에서는 유튜브가 등장한다. 챗GPT의 콘텐츠 보안 정책(CSP·페이지 스크립트가 어디서 올 수 있는지 제한하는 규칙)은 인라인 코드를 막았지만 유튜브 스크립트는 허용했다. Parameter는 콜백 파라미터를 그대로 되돌려주는 유튜브 엔드포인트를 이용해 스크립트를 실행시켰다.

제보부터 패치까지 8일

디지빈이 정리한 Parameter 기술 문서의 타임라인은 다음과 같다. 10월 13일 Parameter가 실제 운영 코드에서 문제를 확인했다. 10월 18일 오픈AI에 제보했고, 10월 21일 심각도가 P2에서 P1로 올라갔다. 10월 26일에는 두 버전의 챗GPT 웹 프런트엔드가 모두 공격에 쓰인 메시지를 거부하는 것이 확인됐다. Parameter는 수정 이후인 10월 28일 기술 문서를 공개했다.

Parameter에 따르면 오픈AI는 코드 실행과 비공개 대화 탈취 시연을 모두 재현했다. 이후 심각도를 P2에서 P1로 올리고 프런트엔드 두 버전에 수정을 배포했다. 오픈AI가 이 제보에 지급한 보상금은 총 5,000달러다. 디지빈은 이렇게 여러 단계가 얽힌 공격 사슬을 제보 후 8일 만에 고친 것이 빠른 편이라고 평가했다. 영향받은 두 프런트엔드 버전의 구체적인 이름은 Parameter가 밝히지 않았다.

원인은 설계 세 가지…이용자가 할 일은 없다

Parameter는 문제의 뿌리를 서로 맞물린 설계 선택 세 가지로 정리했다. 첫째, MathLive가 설정을 바꾸는 메시지를 어느 프레임이 보냈는지 확인하지 않고 처리했다. 둘째, 그 메시지가 키보드 배열 데이터라는 이름으로 가공되지 않은 HTML을 실을 수 있었다. 셋째, 그 HTML이 샌드박스 없이 chatgpt.com 신원을 물려받는 프레임을 만들 수 있었다.

유튜브 단계는 최종 우회 수단일 뿐 원인이 아니었다. 이 경로만 막아도 신뢰할 수 없는 미리보기가 메인 사이트에 HTML을 밀어 넣을 수 있다는 구조적 문제는 그대로 남는다. Parameter는 기술 문서에서 “CSP는 가치 있는 심층 방어책이지만 안전하지 않은 렌더링 경로를 안전하게 만들 수는 없다”고 적었다.

챗GPT 이용자가 따로 조치할 필요는 없다. 수정은 오픈AI 서버 쪽에서 이뤄졌고 설치하거나 재설정할 것이 없다. 디지빈은 그럼에도 공유된 AI 대화를 낯선 첨부파일처럼 다루고, 아는 사람이 보낸 링크만 열라고 조언했다.

핫 뉴스

뉴스 view