1393 words
7 minutes
[Web]웹서버 수준에서의 요청 핸들링
01. 오리진 모델
SOP 개념
- Same Origin Policy는 브라우저 레이어의 핵심 보안 메커니즘
- 기본적으로 한 오리진에서 로드된 리소스가 다른 오리진과 상호작용하는 것을 막는다
- SOP로 제한하는 것들
- DOM 접근
- js를 통한 크로스오리진 요청
- Web Storage , Indexed DB접근
오리진
- 오리진은 다음 세 가지 요소의 조합이다.
- scheme(프로토콜)
- host
- port
scheme://host:port
오리진 비교:https://example.com:443/path ← 기준 URL
같은 오리진:
- https://example.com/other (443 포트 생략)- https://example.com:443/api
다른 오리진:
- http://example.com (scheme 다름)- https://api.example.com (host 다름)- https://example.com:8443 (port 다름)Concept
- Same Origin Policy : 브라우저가 한 오리진의 스크립트가 다른 오리진의 리소스에 접근하는 것을 제한하는 일종의 보안 정책
- scheme : url의 프로토콜 부분(https, http)
- host : 도메인명 또는 ip주소
- CSRF : Cross-Site Request Forgery. 사용자의 의도와 무관하게 공격자가 요청을 위조하는 공격
- Content Security Policy (CSP): SOP를 보완하는 추가 보안 레이어
02. CORS & Preflight
CORS
- CORS(Cross Origin Resource Sharing)은 서버가 명시적으로 허용한 경우에만 크로스 오리진을 가능하게 하는것
CORS 응답헤더 예제
오리진 수준
# 특정 오리진만 허용( 정적 cors)add_header Access-Control-Allow-Origin "https://app.allowed.com";
# 모든 오리진 허용add_header Access-Control-Allow-Origin "*";
# 동적 cors (요청 오리진. 클라이언트가 보낸 오리진을 허용)add_header Access-Control-Allow-Origin $http_origin;# Vary: Origin은 CDN/Proxy에게 origin별 별도 캐싱을 지시# 동적 cors 사용 시 필수add_header Vary "Origin"
# 조건부 corsmap $http_origin $cors_origin { default ""; "https://app.example.com" $http_origin; "https://admin.example.com" $http_origin;}
location /api { add_header Access-Control-Allow-Origin $cors_origin; add_header Vary "Origin"; # 여전히 필요함
# 허용되지 않은 오리진은 빈 응답 → 이것도 캐시됨}메서드 수준
# 허용할 HTTP 메서드 명시add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";헤더 수준
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Request-ID";그 외 옵션
# 쿠키/인증 정보 포함 허용 (Origin이 * 이면 안됨)add_header Access-Control-Allow-Credentials "true";
# 프리플라이트 응답 캐시 시간 (초)add_header Access-Control-Max-Age "86400"; # 24시간프리플라이트(Preflight)
Concept
- CORS
Resource Sharing, SOP를 안전하게 완화하는 W3C 표준 - 프리플라이트 요청 : 실제 요청 전 OPTIONS 메서드로 권한을 확인하는 사전 요청
- 단순 요청 : GET/HEAD/POST + 기본 헤더만 사용하는 프리플라이트가 불필요한 요청
- 비단순 요청 : JSON, 커스텀 헤더, PUT/DELETE 등 프리플라이트가 필요한 요청
- Vary Origin: 오리진별로 다른 응답을 캐시하도록 지시하는 옵션
- $http_origin: NGINX 변수, 요청의 Origin 헤더 값
몇가지 CORS/Preflight 패턴들
1. 오리진 허용 패턴
# $http_origin을 그대로 반사 - 모든 오리진 허용
location /api { if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS' always; add_header Access-Control-Allow-Headers 'Content-Type, Authorization' always; add_header Access-Control-Max-Age 86400; return 204; # 요청이 성공했지만 서버에서 반환할 정보가 없음 }
add_header Access-Control-Allow-Origin $http_origin always; proxy_pass http://backend;}2. White List 패턴
# map을 이용한 허용 오리진 관리map $http_origin $cors_origin { default ""; "https://app.example.com" $http_origin; "https://admin.example.com" $http_origin; "http://localhost:3000" $http_origin;}
location /api { if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin $cors_origin always; # etc.. return 204; }
add_header Access-Control-Allow-Origin $cors_origin always; proxy_pass http://backend;}3. asdfjaha 4. asdfjaha
실제 업무용 세팅은 이거보다는 복잡하지만 몇가지 패턴이 정해져있어서 그거 중심으로 보면 된다.
03. 리버스 프록시
Unsorted
Concept
- Preflight(프리플라이트) : 크로스 오리진의 비단순 요청 전에 브라우저가
OPTIONS로 서버 허용을 미리 확인하는 절차. - proxy_pass : 현재
location으로 들어온 요청을 보낼 업스트림(목적지) 지정. - proxy_set_header Host … : 업스트림에 보낼
Host헤더를 지정(가상호스트/SNI 선택에 영향). - proxy_ssl_server_name on : 업스트림 HTTPS 연결 시 SNI 확장에 서버 이름을 포함하여 올바른 인증서 선택 유도.
- proxy_http_version 1.1 : 업스트림과의 프록시 연결을 HTTP/1.1로 사용(keep-alive, chunked 등 지원).
- X-Real-IP : 업스트림에 전달하는 직전 클라이언트 IP(로그/감사용).
- X-Forwarded-For : 프록시 체인을 따라 누적된 클라이언트 IP 목록(표준 관례).
- X-Forwarded-Proto : 원 요청의 스킴(HTTP/HTTPS) 정보 전달.
- X-Forwarded-Host : 원 요청의 호스트(도메인/IP) 전달.
- X-Forwarded-Port : 원 요청의 포트 전달.
- X-Forwarded-Prefix : 프록시 뒤에서 서비스가 놓인 서브경로를 백엔드에 알림(경로 보정용).
- proxy_redirect : 업스트림이 응답한
Location절대 URL을 현재 스킴/호스트 등으로 재작성. - port_in_redirect off : 리다이렉트 URL에 불필요한 포트 번호 추가를 방지.
- proxy_cookie_domain :
Set-Cookie의 도메인을 클라이언트 호스트로 보정. - proxy_cookie_path :
Set-Cookie의 경로를 프록시 서브경로로 보정. - OPTIONS 204 처리 : 프리플라이트 요청을 프록시에서 즉시
204로 응답하여 백엔드 도달 전 허용. - Access-Control-Allow-* 헤더 : 프리플라이트/실요청에 오리진/메서드/헤더/자격증명 허용 범위를 명시.
- proxy_intercept_errors on : 업스트림 에러를 프록시에서 가로채 자체 처리 가능.
- error_page 404 = /index.html : SPA에서 라우트 미스 시
index.html로 내부 리라이트. - SNI : TLS에서 클라이언트가 접속하려는 호스트명을 전송해 서버가 올바른 인증서를 선택하도록 하는 확장.
- cert-manager(개념) : Kubernetes에서 인증서 발급/갱신을 자동화하는 컨트롤러(예: Let’s Encrypt 연동).
[Web]웹서버 수준에서의 요청 핸들링
https://yjinheon.netlify.app/posts/03be/01web-server/nginx/