Mixed Content The page at '...' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '...'. This request has been blocked; the content must be served over HTTPS 에러를 Nginx에서 해결하기
배경
지난 프로젝트에서도 CORS 문제가 발생해서 하루만에 도메인도 구매하고 Nginx로 연결한 다음 Spring Boot 프로젝트에서 CORS 설정도 해줬었는데, 이번 프로젝트에서도 동일한 방법을 실행했지만 CORS가 해결되지 않는 문제가 발생했다. (이 문제로 서버도 몇 번이나 다시 만들고 nginx 파일을 몇 십번이나 했었다..)
원인 및 결과
Nginx에서 proxy_pass를 127.0.0.1(localhost)로 연결해줬다. 이 부분이 https로 연결된 도메인과 함께 사용돼서 Mixed Content 에러가 발생한 것이다.
server {
listen 443 ssl; # managed by Certbot
...
location / {
proxy_pass http://127.0.0.1:8008;
}
}
구글이나 GPT에 아무리 검색을 해봐도 이렇게 사용하는 게 맞는데 대체 뭐가 문제인지 찾아보다가 정말 많은 시간을 보냈다.
그러다가 CORS 해결 방법 중에 meta 태그를 추가하는 방법에서 생각해봤다. 이 태그를 Nginx에 적용할 수 없을까?
검색해보니 add_header Content-Security-Policy "upgrade-insecure-requests";
를 추가하면 된대서 적용해보니 바로 해결되었다.
결국 서버 내에서 HTTP 보안 정책 중 하나인 CPS를 위반해서 발생한 문제였다..
완성한 코드
server {
listen 443 ssl; # managed by Certbot
...
location / {
proxy_pass http://127.0.0.1:8008;
add_header Content-Security-Policy "upgrade-insecure-requests";
}
}
Content-Security-Policy(CSP)?
- 위에서 추가해준 Content-Security-Policy(CSP)는 콘텐츠 보안 정책으로, 웹 애플리케이션이 웹 페이지에서 로드할 수 있는 리소스의 종류를 제어하는 보안 기능이다. CSP는 보통 XSS나 Injection 공격을 방지하는 데 사용한다.
- Content-Security-Policy에 추가해준 upgrade-insecure-request는 HTTP로 요청된 리소스를 자동으로 HTTPS로 업그레이드하도록 브라우저에 지시한다. 즉, HTTPS를 지원하는 모든 리소스를 보안 연결을 통해 업로드할 수 있게 되어 데이터를 보호할 수 있는 것이다.