[TIL] 웹 보안 - CORS, XSS, CSRF, SQL Injection

지현·2026년 7월 12일

오늘은 브라우저의 CORS 정책부터 시작해서, 실제 발생했던 대형 보안 사고 사례, 그리고 SQL Injection / XSS / CSRF 같은 대표적인 웹 취약점까지 실습을 통해 공부했다.

1. CORS (Cross-Origin Resource Sharing)

CORS란?

브라우저가 한 출처(Origin)에서 실행 중인 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 허용하는 메커니즘.

동일 출처 정책 (Same-Origin Policy, SOP)

브라우저는 보안을 위해 SOP를 적용하며, 두 URL이 아래 세 가지가 모두 같아야 같은 출처로 간주한다.

  • 프로토콜 (http vs https)
  • 도메인 (example.com vs api.example.com)
  • 포트 (3000 vs 8080)

실습으로 확인한 것

  • 다른 출처 요청: GitHub API처럼 CORS를 허용해둔 서버는 다른 도메인에서도 정상적으로 응답을 받을 수 있음
  • 같은 출처 요청: 애초에 CORS 제한 자체가 없음
  • CORS 미설정 서버: 다른 포트로 요청 시 브라우저가 요청 자체를 차단 (Failed to fetch 형태의 에러)
  • CORS 허용 서버: 서버가 Access-Control-Allow-Origin 헤더를 설정해두면 다른 출처에서도 요청 가능

기억할 점

  • CORS는 브라우저의 보안 정책이라 서버 간 통신(server-to-server)에는 적용되지 않는다
  • 결국 CORS 문제 해결의 열쇠는 서버 쪽 헤더 설정에 있다
  • 개발 환경에서는 프록시로 우회 가능하지만, 프로덕션에서는 서버에서 반드시 CORS 헤더를 제대로 설정해야 함

2. XMLHttpRequest vs Fetch API

XMLHttpRequest (XHR)

브라우저와 서버가 비동기로 데이터를 주고받는 전통적인 방식 (Ajax의 핵심 기술). onload, onerror 같은 이벤트 콜백 기반으로 동작.

Fetch API

XHR의 현대적 대안. Promise 기반이라 .then() 체이닝이나 async/await와 훨씬 잘 어울리고 문법도 간결하다.

Promise 체이닝

fetch(url)
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

.then()으로 비동기 흐름을 연결하고, .catch()로 에러를 한 곳에서 처리할 수 있다는 게 핵심.

비교 정리

항목XHRFetch
문법다소 복잡간결
비동기 처리콜백 기반Promise 기반
브라우저 지원레거시 포함모던 브라우저 위주
부가 기능진행률 추적 등상대적으로 단순

→ 실무에서는 대부분 Fetch API를 권장.


3. React에서의 CORS 처리

  • React에서는 보통 Fetch APIaxios로 API를 호출하고, useEffect로 컴포넌트 마운트 시점에 데이터를 불러온다
  • CORS 에러가 발생하면 vite.config.js 등에서 개발 서버 프록시를 설정해 우회할 수 있음
  • 단, 프록시는 개발 환경 전용이며, 실서비스에서는 결국 서버에서 Access-Control-Allow-Origin 헤더를 제대로 설정해야 한다
  • 민감한 데이터를 다루는 API일수록 CORS 허용 도메인을 신뢰할 수 있는 출처로 제한하는 것이 중요

4. SQL Injection / XSS / CSRF 실습

SQL Injection

사용자 입력을 그대로 쿼리에 끼워 넣으면, ' OR '1'='1' 같은 입력값이 조건문을 항상 참으로 만들어버려 인증을 무력화시킬 수 있다.

  • 취약한 방식: 문자열 그대로 쿼리에 삽입
  • 방어 방식: Prepared Statement(준비된 구문) 사용 — 쿼리 구조(?)와 값을 분리해서 바인딩하면, 입력값은 항상 '문자열'로만 취급되어 명령어로 실행되지 않는다

XSS (Cross-Site Scripting)

악성 스크립트를 페이지에 삽입해 사용자 브라우저에서 실행시키는 공격.

  • 취약한 방식: 사용자 입력을 검증 없이 그대로 화면에 렌더링
  • 방어 방식: <, >, ", ', & 같은 특수문자를 HTML 엔티티로 이스케이프 처리 → 코드가 아닌 순수 텍스트로 인식되게 만듦
  • React/Vue 등은 기본적으로 XSS를 방어해주지만, innerHTML을 직접 다룰 때는 주의 필요

CSRF (Cross-Site Request Forgery)

사용자가 의도하지 않은 요청이 자신도 모르게 실행되는 공격.

  • 방어 방식: 서버가 발급한 CSRF 토큰을 요청에 포함시키고, 서버는 세션에 저장된 토큰과 일치하는지 검증
  • 그 외 SameSite 쿠키 속성, Referer 헤더 검증, 중요 작업 시 재인증 요구도 함께 사용

인증/세션 관리 모범 사례

  • 비밀번호는 bcrypt, Argon2 등으로 해시 + 솔트 처리
  • 세션 ID는 안전하게 생성하고 적절한 만료 시간 설정, HTTPS 필수
  • JWT 사용 시 서명 검증 + 짧은 만료시간 + Refresh Token 분리
  • 2FA/MFA로 인증 강화, 무차별 대입 공격 방지를 위한 계정 잠금 기능

오늘의 한 줄 요약

CORS는 브라우저의 보안장치일 뿐이고, 진짜 보안은 서버의 입력값 검증 + 인증/인가 + 암호화 + 지속적인 모니터링에서 나온다.

0개의 댓글