임베드 플러그인 관련 문제의 원인을 찾았습니다. 임베드를 설정할 때 “허용된 호스트”(Allowed Hosts) 설정이 있으며, 이 설정은 iframe의 CSP(Content Security Policy)를 설정합니다. 따라서 iframe은 해당 호스트에서만 표시됩니다. 예를 들어, 허용된 호스트를 example.com으로 설정한 후 attacker.com에서 JS를 임베드하려고 하면, iframe이 로드되는 것이 거부되고 다음과 같은 오류가 발생합니다.
Refused to frame 'https://forum.example.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self' https://example.com".
그러나 이 시점에서는 JS가 이미 실행되어 임베드 코드에 주어진 URL로 포럼에 토픽을 생성해 버립니다.
제 경우의 상황은 Netlify를 사용하여 빌드를 미리 보기 때문에 블로그의 사본이 실제로 netlify.app URL에서 제공되고, 이 환경에서 해당 embed.js가 로드되어 이전에 잘못 가져온 게시물을 위한 포럼 스레드를 생성하고 있는 것입니다.
이것은 반드시 보안 문제는 아닙니다. 설정된 웹사이트 URL 중 경로 허용 목록(path allowlist)과 일치하는 URL에 대해서만 토픽을 생성할 수 있기 때문입니다. 하지만 이전 게시물을 Discourse로 이관하는 과정에서 포럼 스레드에 embed_url을 설정할 방법이 없었기 때문에, 이 마이그레이션 전략에서는 문제가 됩니다.
해결 방법은 “허용된 호스트” 설정에 포함되지 않은 도메인에서 embed.js가 실행되는 것을 방지하기 위해 CSP 규칙을 추가하는 것입니다.
개념 증명(Proof of Concept)으로, 임베드 코드를 완전히 무관한 도메인에 복사하고 discourseEmbedUrl을 이전에 가져온 오래된 게시물 중 하나로 설정했습니다. 페이지를 로드했을 때 iframe은 차단되었지만, JS는 이미 실행되어 포럼 스레드를 생성해 버렸습니다.
이것이 버그보다는 보안 문제로 판단된다면, 이 게시물을 삭제하고 대신 HackerOne을 통해 보고하는 것을 기꺼이 수행하겠습니다.