원격 로드된 JavaScript 콘텐츠에 대해 궁금합니다

음… 아직 내 광고 서버를 Discourse에 표시되도록 하는 작업 중입니다. 어떻게든 해결할 수 없는 수수께끼 같은 문제에 부딪혔습니다. 테마 편집 기능을 사용하여 스크립트 요청을 </body>와 ‘footer’ 양쪽에 추가했습니다.

footer(또는 ‘after header’)에 추가하면 코드가 실패합니다. 검사 모드에서 인코딩된 텍스트가 올바르게 보이는 것 같긴 합니다. 아래를 확인해 주세요:

"Where is this?"라는 텍스트는 표시되지만, 그 외에는 아무것도 표시되지 않습니다.

하지만 동일한 스크립트 요청(아래 참조)을 </body>에 추가하면 작동합니다. 왜 그런 걸까요?

<script language="Javascript" src="https://adserver.kitmaker.net/index.php?section=serve&action=1">

House Ads 데이터 필드에 이것을 추가해 보았지만, 다시 한 번 텍스트가 페이지의 인코딩 데이터 일부로만 나타나고 아무것도 표시되지 않았습니다.

creatives\&quot;:{\&quot;Leaderboard Ad\&quot;:\&quot;\\u003cscript language=\\\&quot;Javascript\\\&quot; src=\\\&quot;https://adserver.kitmaker.net/index.php?section=serve\\u0026action=1\\\&quot;\\u003e\&quot;}},\&quot;

또한 AdSense 광고를 단독으로 작동하게 하는 것도 아직 불가능해 보입니다. 하지만 그것은 아마도 AdSense 측 문제일 수 있으며, 아직 사이트를 스캔하여 무엇을 표시할지 확인하지 못한 것일 수도 있습니다. 그런데 이렇게 오래 걸리는 것이 좀 이상하긴 합니다.

도움 주시면 감사하겠습니다.

Jim

개발자가 이 글을 보셨으면 좋겠습니다. :slight_smile:

관리자분께 이 글을 지원(Support)이나 적절한 카테고리로 이동해 주실 수 있을까요? 카테고리를 지정하지 않고 그대로 두었습니다.

감사합니다. 이 문제를 계속 언급하는 것이 부담스러울 수 있다는 점은 알지만, 배포 마감일이 다가오고 있어 이 문제를 꼭 해결해야 합니다.

음, CSP 로그에서 Google 광고 스크립트가 차단되고 있다는 것을 확인했으니

https://pagead2.googlesyndication.com

을 CSP 스크립트 src 목록에 추가했고, 그제서야 Google AdSense 광고가 표시되기 시작했습니다 (AdSense 플러그인이 설치되어 있는데도 여전히 이렇게 해야 하는 것에 약간 놀랐습니다). 그런데 주목할 점은 House Ads를 100%로 설정했을 때(즉, 제 스크립트만 호출되도록 했을 때) CSP에서 문제가 있다는 알림이 전혀 없다는 것입니다. 그래서 다시 혼란스러운 상태로 돌아갔습니다. House Ad 코드는 HTML에 (인코딩되어) 있으며, 브라우저 검사 뷰에서는 위에서와 같이 표시됩니다.

CSP 경고를 트리거하지 않으면서 출력을 차단하는 것이 있을까요?

출력은 광고 공간을 생성하기 위해 document.write를 사용합니다. 이것이 원인이 아닐까 추측하고 있습니다. 출력은 다음과 같습니다:

하하… 만약 스크립트 출력을 여기에 텍스트로 넣었다면 제대로 생성되었을 것입니다. 아…

비슷한 문제를 다루는 이 포스트를 찾았지만, 이 사람은 스스로 해결했고, 저보다 자바스크립트에 훨씬 능숙해 보입니다.

그와 마찬가지로, 저는 이 문제에 대한 도움을 위해 비용을 지불할 의향이 있습니다.

감사합니다,
Jim

자… 이건 전부 CSP와 관련이 있는 것 같습니다(그렇게 추정합니다). 사이트가 ‘unsafe-inline’ 데이터로 설정되어 있고, 변수가 포함된 URL로 애드서버 스크립트를 가져오려고 하고 있기 때문이죠. 아… 제 방식이 좀 야만적이긴 합니다.

자… 혹시 아시는 분 계신가요? 이 문제를 간단히 해결할 방법이 있나요, 아니면 그냥 포기해야 하나요?

올바른 해결 방법은 인라인을 사용하지 않고, 기존 EmberJS 템플릿의 아웃렛에 연결되도록 재작성하는 것입니다. 임시적인 해결책을 찾고 있다면, 커스텀 광고 솔루션에 변경 사항을 적용하는 동안 사이트 설정에서 CSP를 비활성화할 수 있습니다. 다만, 이로 인해 XSS 공격에 노출될 수 있다는 점을 유의하시기 바랍니다.

또한, 이 PR(AdButler support - Pull Request #80 - discourse/discourse-adplugin - GitHub)이나 Carbon Ads Integration - Pull Request #73 - discourse/discourse-adplugin - GitHub, 또는 Add CodeFund Advertising option - Pull Request #65%EC%97%90%EC%84%9C%EC%B2%98%EB%9F%BC - discourse/discourse-adplugin - GitHub adplugin의 포크에 서버를 추가하는 방법도 검토해 볼 수 있습니다.

그렇다면 Content Security Policy는 어디서 선언되는 건가요? 관련 메타 태그를 찾지 못했습니다. 브라우저마다 기본으로 적용되는 HTML5 설정인가요?

Content Security Policy를 이용한 XSS 공격 완화를 확인해 보세요.

Falco님, 감사합니다. 모든 보호 기능을 끄는 대신, 애드서버 URL에 대해서만 데이터 문자열을 화이트리스트에 등록하여 해당 변수를 통과시킬 수 있는 방법이 있을까요? 아니면… ‘‘unsafe-inline’ data’ 요구사항을 단순히 비활성화할 수 있을까요?

아쉽게도 링크해 주신 글에서 해당 옵션을 찾을 수 없네요.

다시 한번 감사합니다.

음, 아마도 절박해진 것 같네요. CSP를 완전히 끄려고 시도해 보았거든요…

그런데도 여전히 사이트의 메인 섹션에 광고가 표시되지 않고, 테마의 </body>에 설치된 푸터 부분에서만 표시됩니다. 그런데 중앙 섹션 주위에 <noscript> 래퍼가 있고, 푸터 쪽은 </noscript> 닫는 태그 밖에 있더라고요. 그래서 그런 건가요?

Firefox에서 확인해 보니 이제 콘솔에 CSP 경고가 표시되지 않습니다. 처음부터 Chrome에서는 왜 경고가 보이지 않았는지 모르겠네요.

Discourse는 단일 페이지 애플리케이션(SPA)이며, 모든 페이지 마크업은 EmberJS 애플리케이션을 통해 클라이언트 사이드에서 생성됩니다.

document.write와 같은 직접적인 DOM 조작은 전체 구조와 정면으로 충돌하며, 단순히 작동할 가능성은 매우 낮습니다.

광고 시스템을 공식 Ad 플러그인의 House Ads 시스템에 맞게 조정해 보시는 것을 권장합니다. House Ads 인벤토리에 단일 광고를 배치하고, page change 훅을 사용하여 광고 서버에 연락한 후 응답으로 광고를 교체하는 방식도 고려해 볼 수 있습니다. 아니면 광고 시스템이 API를 통해 House Ads 인벤토리에 직접 데이터를 기록할 수 있도록 할 수도 있습니다.

도와주셔서 감사합니다, Falco. 조금 무섭긴 하지만, 이 광고 서버의 코드베이스는 API라는 용어가 만들어지기 전에 작성된 것이어서… 결국 처음부터 완전히 새로운 광고 서버 시스템을 작성하는 것이 더 나을 것 같습니다. 하지만 지금은 이 새로운 포럼과 6개 이상의 새로운 콘텐츠 사이트를 배포해야 해서 그럴 시간이 없습니다.

document.write를 대체할 다른 옵션들을 시도해보고, 그것이 작동할 수 있는지 확인해 보겠습니다.

감사합니다,
Jim