iframe에 sandbox를 걸었는데 스크립트가 부모 쿠키를 읽은 이유
문제 발생
사용자가 올린 HTML 미리보기를 iframe으로 보여주기로 하고 sandbox를 걸었습니다. 안전하다고 생각했는데, 넣어둔 테스트 스크립트가 부모 페이지의 쿠키를 읽어냈습니다.
<iframe sandbox="allow-scripts allow-same-origin" src="/preview/123"></iframe>원인 분석
sandbox 속성은 값이 비어 있으면(sandbox="") 모든 제한을 겁니다. 스크립트 실행, 폼 제출, 팝업, 쿠키·스토리지 접근, 내비게이션이 전부 막힙니다. 토큰을 하나씩 적는 것은 그 제한을 풀어주는 행위입니다.
문제는 두 토큰의 조합입니다. MDN이 경고로 못박습니다 — 임베드된 문서가 임베드하는 페이지와 같은 출처(same origin) 일 때 allow-scripts와 allow-same-origin을 함께 쓰는 것은 강력히 권장되지 않습니다. 임베드된 문서가 sandbox 속성 자체를 제거할 수 있게 되어, sandbox를 아예 쓰지 않은 것과 다를 바 없어지기 때문입니다.
스크립트를 돌릴 수 있고 같은 출처로 취급되면, 그 스크립트가 부모 문서에 접근해 자기를 감싼 iframe의 속성을 지울 수 있습니다. 울타리 안쪽에서 울타리를 여는 열쇠를 주는 셈입니다.
해결 방안
- 신뢰할 수 없는 콘텐츠는 다른 출처에서 서빙합니다. 이게 근본 대책입니다. 별도 도메인(또는 서브도메인)에 올리면
allow-scripts를 줘도allow-same-origin이 부모를 뜻하지 않습니다.
<iframe sandbox="allow-scripts" src="https://sandbox.example.com/preview/123"></iframe>- 스크립트가 필요 없으면 주지 않습니다. 미리보기 대부분은 마크업과 스타일이면 충분합니다.
<iframe sandbox="" srcdoc="<p>사용자 콘텐츠</p>" title="미리보기"></iframe>- 토큰은 필요한 것만 하나씩 엽니다.
| 토큰 | 푸는 제한 |
|---|---|
allow-scripts | 스크립트 실행 |
allow-same-origin | 같은 출처로 취급 (스토리지·쿠키 접근) |
allow-forms | 폼 제출 |
allow-popups | window.open, target="_blank" |
allow-modals | alert/confirm 등 모달 |
allow-top-navigation | 최상위 문서 이동 |
allow-downloads | 다운로드 |
allow-top-navigation은 특히 조심합니다 — iframe 안의 광고나 사용자 콘텐츠가 페이지 전체를 피싱 사이트로 옮길 수 있습니다.
- 기능 권한은
allow로 따로 막습니다.sandbox와 별개의 축입니다. MDN의 설명대로allow의 Permissions Policy는Permissions-Policy헤더의 정책 위에 얹는 추가 제한이지 대체가 아닙니다.
<iframe src="..." allow="camera 'none'; microphone 'none'"></iframe>- 리퍼러와 지연 로딩도 함께 정합니다. 외부 임베드에 현재 URL 전체를 흘리지 않습니다.
<iframe src="..." referrerpolicy="no-referrer" loading="lazy" title="지도"></iframe>-
title을 꼭 붙입니다. 스크린리더가 프레임 목록에서 구분할 유일한 단서입니다. -
sandbox는 방어의 한 겹입니다. 서버에서 저장 전에 sanitize하고, 응답에
Content-Security-Policy를 함께 겁니다. 클라이언트 속성 하나에 전부를 맡기지 않습니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.