C
네트워크/보안/Lesson 07

CORS + 보안 — 동일 출처·CORS·Preflight

30분·theory

CORS + 보안 — 동일 출처·CORS·Preflight

🎯 이 lesson 을 읽고 나면

이 lesson 을 다 읽고 나면 아래 3가지를 자신 있게 할 수 있습니다.

  • ✅ CORS preflight + Access-Control-Allow-Origin
  • ✅ XSS · CSRF · SQL Injection 방어
  • ✅ helmet · CSP · HSTS 보안 헤더

학습 목표를 체크리스트로 두고 다 답할 수 있게 되면 lesson 을 닫으세요.

Same-Origin Policy + CORS

Same-Origin Policy (SOP) — 브라우저 보안의 기본:

  • 같은 출처 의 자원만 JS 에서 접근 가능
  • 출처 (Origin) = 프로토콜 + 호스트 + 포트
  • https://example.com:443 vs https://api.example.com:443 = 다른 출처

SOP 가 없으면:

  • 악성 사이트가 내 은행 쿠키 로 송금 요청 가능
  • 너무 위험 → 브라우저가 강제

CORS (Cross-Origin Resource Sharing) — SOP 의 예외 메커니즘:

  • 서버가 Access-Control-Allow-Origin 헤더로 허용된 출처 명시
  • 브라우저가 검증

Simple Request (CORS preflight 없이):

  • 메서드: GET·HEAD·POST 만
  • 헤더: 표준만 (Content-Type 도 제한적)
  • Content-Type: text/plain·application/x-www-form-urlencoded·multipart/form-data

위반 시: 브라우저가 응답을 JS 에서 차단. (요청 자체는 서버에 도착)

CORS Preflight + 해결

Preflight Request위험한 요청 전 사전 확인:

조건 (하나라도 해당 시 preflight):

  • 메서드: PUT·DELETE·PATCH 등
  • 커스텀 헤더: Authorization·X-API-Key
  • Content-Type: application/json

Preflight 흐름:

code
1. 브라우저: OPTIONS /api/users
   Origin: https://frontend.com
   Access-Control-Request-Method: POST
   Access-Control-Request-Headers: Authorization, Content-Type

2. 서버: 200 OK
   Access-Control-Allow-Origin: https://frontend.com
   Access-Control-Allow-Methods: POST, PUT, DELETE
   Access-Control-Allow-Headers: Authorization, Content-Type
   Access-Control-Max-Age: 600    (10분 캐시)

3. 실제 요청: POST /api/users
4. 정상 처리

서버 측 해결:

Express:

javascript
const cors = require('cors');
app.use(cors({
  origin: ['https://frontend.com', 'https://admin.example.com'],
  credentials: true,        // 쿠키 허용
  methods: ['GET','POST','PUT','DELETE','PATCH'],
  allowedHeaders: ['Content-Type','Authorization'],
  maxAge: 600,
}));

Spring:

java
@CrossOrigin(origins = "https://frontend.com",
             allowCredentials = "true")
@RestController
public class UserController { ... }

// 또는 전역:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
  @Override public void addCorsMappings(CorsRegistry r) {
    r.addMapping("/api/**")
     .allowedOrigins("https://frontend.com")
     .allowedMethods("GET","POST","PUT","DELETE")
     .allowCredentials(true);
  }
}

CORS 흔한 함정:

  • Access-Control-Allow-Origin: * + Allow-Credentials: true → 무효 (보안 충돌)
  • ❌ 와일드카드 쿠키* 와 함께 못 씀
  • ❌ 프록시로 CORS 우회 (개발 환경만, production 은 정식 설정)
  • ✅ 명시적 origin 리스트 + 자격증명 명시 + preflight 캐시

프록시 + 보안 헤더

프록시 서버 — 클라이언트와 서버 사이의 중개자:

Forward Proxy (앞 프록시):

  • 클라이언트
  • 사용자 IP 숨김, 콘텐츠 필터링
  • 예: 회사 방화벽·VPN·Squid

Reverse Proxy (역 프록시):

  • 서버
  • 클라이언트는 프록시만 보고, 실제 서버 숨김
  • 로드 밸런싱·SSL termination·캐싱·압축
  • 예: Nginx·HAProxy·Cloudflare·AWS ALB

Nginx 역프록시 예:

nginx
server {
    listen 443 ssl;
    server_name codemaster40.com;

    ssl_certificate /etc/letsencrypt/live/codemaster40.com/fullchain.pem;

    location / {
        proxy_pass http://localhost:3000;       # Next.js
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /api {
        proxy_pass http://localhost:8080;       # Spring Boot
    }

    # Rate limit
    limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
}

필수 보안 헤더:

헤더용도
Strict-Transport-SecurityHTTPS 강제 (HSTS)
X-Frame-Options: DENYClickjacking 방어 (iframe 차단)
X-Content-Type-Options: nosniffMIME 추측 차단
Content-Security-PolicyXSS·인젝션 방어
Referrer-PolicyReferer 노출 제어
Permissions-Policy카메라·마이크 등 권한

Helmet (Node.js·Express):

javascript
const helmet = require('helmet');
app.use(helmet());   // 위 헤더 자동 설정

🤖 AI 에게 이렇게 요청해보세요

이 lesson 의 개념을 알면 AI 에게 구체적으로 지시할 수 있습니다. 막연한 "고쳐줘" 가 아니라 어휘를 가진 요청 — 그게 토큰 절약의 출발점입니다.

  • "이 Express 앱에 helmet + CORS 화이트리스트 + CSP 헤더 추가해줘"
  • "이 코드의 OWASP Top 10 점검 후 보강해줘"

왜 이게 토큰을 줄이나

개념을 모를 땐 AI 답변을 받고도 "그게 뭐예요?" 를 다시 물어야 합니다. 그 "다시 물음" 이 토큰을 잡아먹습니다. 개념 한 번 익혀두면 대화가 한 번에 끝납니다.

CORS + 보안 — 동일출처·CORS·Preflight - 네트워크