핵심 요약
- 스크립트 태그가 HTML에 있어도 브라우저의 CSP 오류가 있으면 실제 실행은 별도로 확인해야 한다.
- Next.js의 headers()와 middleware.ts가 모두 CSP를 설정하는지 검색하고 최종 응답 헤더를 확인한다.
- 수정은 공개 도메인에서 응답 헤더와 브라우저 오류를 다시 확인한 뒤 완료로 판단한다.
A2Z Studio를 개편한 뒤 공개 사이트에서 AdSense 연동 상태를 점검했습니다. HTML에는 광고 스크립트가 있었지만 브라우저에서는 Google 관련 요청 하나가 CSP(Content Security Policy)에 막혔습니다. 처음에는 next.config.ts의 보안 헤더를 고치면 끝날 것으로 봤습니다. 그런데 새 배포를 열어도 오류가 남았습니다. 소스에 선언된 값과 방문자가 받은 값이 다를 수 있다는 신호였습니다. 이 글은 광고가 실제로 표시됐다는 기록이나 사이트 승인 후기가 아니라, 스크립트 차단을 찾아 해결한 배포 점검 기록입니다.
설정 파일보다 먼저 최종 응답을 본 이유
CSP는 브라우저가 어떤 스크립트와 요청을 허용할지 결정하는 응답 헤더입니다. 개발자 도구 콘솔에서 Content Security Policy 오류가 보이면 태그의 존재만 확인해서는 부족합니다. 우선 시크릿 창이나 로그아웃한 브라우저에서 공개 주소를 열고 콘솔의 차단된 URL과 적용된 지시문을 기록합니다. 그런 다음 실제 응답에 어떤 정책이 들어왔는지 확인합니다.
curl -sSI https://a2z-studio.com/ | grep -i content-security-policy
rg -n 'Content-Security-Policy|script-src|default-src' next.config.ts middleware.ts app
첫 명령은 방문자가 받는 헤더를, 둘째 명령은 저장소에서 그 헤더를 만드는 위치를 찾습니다. 경로마다 헤더가 다르게 적용될 수 있으므로 문제가 난 페이지 주소도 별도로 확인해야 합니다. 응답 헤더가 여럿이면 브라우저는 각 정책을 함께 적용합니다. 한쪽이 허용하더라도 다른 쪽이 차단하면 요청은 막힐 수 있습니다. 따라서 파일 하나를 바꾼 뒤에는 반드시 배포된 URL에서 같은 점검을 반복해야 합니다.
실제 원인: 두 곳에서 만들던 CSP
이 프로젝트에는 next.config.ts의 headers()와 middleware.ts가 모두 CSP를 설정한 시점이 있었습니다. 첫 수정에서는 설정 파일의 제한을 완화했지만, 미들웨어가 여전히 응답에 정책을 추가하고 있었습니다. 소스 검색으로 두 위치를 찾고, 미들웨어의 CSP 설정을 제거했습니다. 현재 미들웨어에는 이전 도메인과 HTTP 요청을 정규 HTTPS 주소로 보내는 리다이렉트만 남아 있습니다. 보안 헤더는 next.config.ts에서 한곳에 관리합니다. 같은 이름의 헤더가 중복되는지를 보기 위해 코드 검색뿐 아니라 공개 응답도 함께 확인한 이유입니다.
현재 사이트의 CSP는 object-src 'none', base-uri 'self', form-action 'self', frame-ancestors 'none', upgrade-insecure-requests처럼 필요한 제한을 남겼습니다. 광고에 필요한 여러 도메인을 임의로 script-src 허용 목록에 계속 더하는 방식은 택하지 않았습니다. Google은 AdSense 코드가 쓰는 도메인이 바뀔 수 있으므로, CSP를 엄격하게 운영하려면 nonce 기반 정책을 안내합니다. 이 사이트에는 아직 nonce를 모든 스크립트에 일관되게 붙이는 구현이 없으므로, 존재하지 않는 보호 수준을 설정했다고 주장할 수 없습니다. CSP 변경은 보안 설정 변경이기도 해서, 단순히 오류를 없애려고 모든 지시문을 삭제하는 것도 적절하지 않습니다.
배포 후 확인한 범위
수정본을 운영에 올리고 Vercel 배포가 Ready인지 확인한 다음, a2z-studio.com 응답 헤더와 브라우저 콘솔을 다시 봤습니다. 이전에 보였던 CSP 차단 오류는 재현되지 않았고 해당 Google 요청도 응답했습니다. 이것이 확인해 주는 것은 그 점검 세션에서 차단이 해소되었다는 사실까지입니다. 광고 노출, 계정 정책 판정, AdSense 사이트 승인 여부를 증명하지는 않습니다. 브라우저 확장 프로그램, 동의 상태, 지역, 이후 광고 코드 변경에 따라 새 요청이 생길 수 있으므로 스크립트가 정상 동작하는지는 운영에서 계속 봐야 합니다.
같은 문제가 생겼다면 HTML의 스크립트 태그 → 실제 응답 CSP → 브라우저 콘솔 → 선언 위치 전체 → 새 배포의 공개 주소 순서로 좁혀 보는 편이 좋습니다. Google은 정책을 바꾸기 전 Content-Security-Policy-Report-Only로 위반을 관찰하는 방법도 권장합니다. 사이트 승인 심사 중이라면 헤더 오류를 고쳤다는 이유만으로 심사를 다시 요청하거나 사이트를 재등록할 근거가 되지는 않습니다. 방문자가 사용할 수 있는 콘텐츠와 서비스의 품질은 별도로 살펴봐야 합니다.
글쓴이 · 1인 개발 스튜디오
A2Z Studio
앱인토스 미니앱, iOS 앱, Next.js 웹 서비스를 직접 만들고 운영합니다. 글은 실제 운영 코드에서 겪은 문제만 다룹니다. 소개 보기