| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 계정추상화
- erc4337 contract
- git rebase
- 스마트 컨트렉트 함수이름 중복
- Vue.js
- 체인의정석
- ethers type
- cloud hsm
- ethers v6
- ethers websocket
- ethers typescript
- 스마트컨트렉트 예약어 함수이름 중복
- 러스트기초
- redux toolkit 설명
- Vue
- ambiguous function description
- 머신러닝기초
- 티스토리챌린지
- SBT표준
- rust 기초
- 컨트렉트 동일한 함수이름 호출
- erc4337
- 러스트 기초 학습
- redux 기초
- vue기초
- 오블완
- cloud hsm 사용하기
- 러스트 기초
- cloud hsm 서명
- 스마트컨트렉트 함수이름 중복 호출
- Today
- Total
체인의정석
웹 서비스에서 Content-Security-Policy (CSP), Referer Policy 처리를 통한 보안 강화 본문
웹 서비스에서 Content-Security-Policy (CSP), Referer Policy 처리를 통한 보안 강화
체인의정석 2026. 1. 5. 16:48상황
모회사에서 별도의 WAF와 백신을 설치한 이후에 관련된 ASM(Attack Surface Management) 대시보드를 볼 수 있게 되었다.
ASM은 외부 공격자가 접근할 수 있는 모든 잠재적 지점을 지속적으로 식별하고 분석하며, 보안 취약점을 최소화하는 프로세스라고 한다.
보니 referer policy와 Content-Security-Policy가 적용되지 않아서 보안성 경고가 뜬 부분을 볼 수 있었다.
https://velog.io/@sejinkim/Referrer-Policy%EC%9D%98-%EC%9D%B4%ED%95%B4
Referrer-Policy의 이해
사용자 행동 로그 데이터 수집 중 Referer가 유실되었던 사례를 계기로, Referrer-Policy에 관해 자세히 알아보았습니다.
velog.io
Referer Policy - 서버 처리
- 목적: 브라우저가 HTTP 요청 시 Referer (오타가 있는 원조 헤더 이름) 헤더에 포함할 이전 페이지의 URL 정보(리퍼러 정보)의 양을 제어합니다.
- 작동 방식: 사용자가 한 웹사이트에서 다른 웹사이트로 이동하거나 리소스를 요청할 때, 목적지 서버에 어떤 출처 정보를 보낼지 결정합니다.
- 주요 목표: URL에 포함될 수 있는 민감한 정보(예: 세션 토큰, 개인 식별자)의 불필요한 노출을 방지하여 사용자 프라이버시를 보호하는 데 중점을 둡니다.
- 예시: Referrer-Policy: no-referrer는 어떠한 리퍼러 정보도 보내지 않도록 지시하며, Referrer-Policy: strict-origin-when-cross-origin은 동일 출처 요청 시에는 전체 URL을 보내지만 교차 출처 요청 시에는 출처(origin) 정보만 보내도록 합니다.
웹 사이트 보안의 기본적인 대전제는 Same Origin Policy(SOP) 동일 출처 정책이다.
가능한 공격 벡터를 줄이기 위해, 다른 출저와의 상호작용을 제한하는 보안 정책이다.
동일한 출저가 아닌 경우 Cross-site 또는 Cross-Origin 이라고 하며, 개인정보 보호 및 웹 공격 방어 차원에서 특정 기능이나 정보가 제한됩니다.
먼저 referer policy에 대해서 찾아본 결과 Referer의 정의는 현재 요청을 보낸 페이지의 절대 혹은 부분 주소라고 한다. 리소스 요청이나 사용자의 링크 클릭에 존재할 수 있으며, 여기서 정보를 제한하지 않으면 사용자의 개인정보가 노출될 수 있기 때문에 제한을 하는 정책이라고 한다. 일단 SOP의 경우에는 문제를 삼지 않지만 cross-origin 요청일 때는 엄격하게 제한하는 것이 기본적인 기조라고 한다.
따아서 cross-origin요청일 때는 "strict-origin-when-cross-origin" 요청을 주면 된다.
반영하는 방법은 다음과 같다.
https://kku-jun.tistory.com/48
Referer Policy 적용하기
혹시 프로젝트를 진행하면서 이미지 url을 통해 접근은 가능하나 개발중인 서비스앱 내부에서는 호출하지 못한 경험이 있는가? 필자는 다음 경험을 Referer policy를 정의하면서 접근할 수 있게 되
kku-jun.tistory.com
해당 방법은 간단한데 웹서버에서
// 보안 헤더 설정
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
위 언어는 go언어지만 해당 방식으로 보안 헤더를 서버에서 설정해 주면

위와 같이 referrer policy가 반영되게 된다.
CSP - 서버 처리
다음으로 작업한 부분은 CSP 반영이다.
- 목적: 웹사이트 관리자가 페이지에서 로드할 수 있는 리소스(스크립트, 이미지, 스타일 등)의 출처를 제어할 수 있도록 합니다.
- 작동 방식: 신뢰할 수 있는 콘텐츠 소스(도메인)를 지정하여, 브라우저가 승인되지 않은 출처의 악성 콘텐츠를 로드하거나 실행하는 것을 방지합니다.
- 주요 목표: 교차 사이트 스크립팅(XSS) 및 데이터 삽입 공격과 같은 특정 유형의 공격을 탐지하고 완화하는 데 효과적인 추가 보안 계층입니다.
- 예시: Content-Security-Policy: script-src 'self' https://trusted-scripts.com;은 브라우저에게 자체 출처와 trusted-scripts.com에서만 스크립트를 로드하도록 지시합니다.
여기서 말하는 CSP는 콘텐츠 보안 정책으로 교차 사이트 스크립팅과 데이터 주입 공격 등을 방어하기 위한 추가 보안 계층이라고 한다.
There is missing header: Content-Security-Policy. The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page.
만약 http 요청에서 아래와 같이 이미 정책이 있다면 괜찮지만 해당 정책이 없다면 외부로부터의 호출에 있어서 보안 계층이 없어지는 것이기 때문에 활성화를 시켜주어야한다.
CSP를 활성화하려면 Content-Security-Policy HTTP 헤더를 반환하도록 웹 서버를 구성해야 한다.
w.Header().Set("Content-Security-Policy",
"default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self' data:;
connect-src 'self'")
https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/CSP
컨텐츠 보안 정책 (CSP) - HTTP | MDN
CSP의 주요 목표는 XSS 공격을 완화하고 보고하는 것입니다. XSS 공격은 서버에서 받은 콘텐츠를 브라우저가 신뢰한다는 점을 악용합니다. 브라우저는 콘텐츠의 출처를 신뢰하기 때문에 콘텐츠가
developer.mozilla.org
Referer Policy & CSP 프론트엔드 처리
또한 두 부분 모두 프론트엔드에서 정적 파일 실행하는 부분도 ASM 모니터링 툴에 걸려서 업데이트를 진행해야 했었다.
만약 메타 마스크도 들어간다면 프론트엔드에서는 아래와 같이 정책을 짜면 된다.
파일명 : next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Content-Security-Policy',
value: [
"default-src 'self'",
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.yourdomain.com",
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net",
"img-src 'self' data: https:",
"font-src 'self' data: https://fonts.gstatic.com https://cdn.jsdelivr.net",
"connect-src 'self' https://*.yourdomain.com https://*.metamask.io https://*.metamask-api.io https://*.arbitrum.io https://*.infura.io https://cdn.jsdelivr.net wss://*.metamask.io wss://*.metamask-api.io",
].join('; '),
},
],
},
];
},
};
export default nextConfig;
이렇게 사용되는 외부 도메인 호출을 모두 CSP 정책에 넣어주어야 외부 공격으로부터 더 안전한 서비스를 만들 수 있게 된다.
또한 프론트에서 상세하게 CSP정책이 있기 때문에 이렇게 도메인을 하나하나 넣어주는 작업은 백엔드에서는 할 필요가 없다.
'개발 > frontend' 카테고리의 다른 글
| React, Next.js 취약점 (CVE-2025-55182, CVE-2025-66478) (0) | 2025.12.30 |
|---|---|
| React) 재랜더링과 메모이제이션 Memo, useMemo & useEffect (0) | 2025.09.25 |
| Ts에서 export가 하나도 정의되어 있지 않은 경우 (모듈 vs 파일) (0) | 2025.08.20 |
| Indexed DB & 프론트엔드 (ts) (4) | 2025.07.17 |
| Redux와 Thunk, CreateAsyncThunk (0) | 2025.07.10 |