오늘은 브라우저의 CORS 정책부터 시작해서, 실제 발생했던 대형 보안 사고 사례, 그리고 SQL Injection / XSS / CSRF 같은 대표적인 웹 취약점까지 실습을 통해 공부했다.
브라우저가 한 출처(Origin)에서 실행 중인 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 허용하는 메커니즘.
브라우저는 보안을 위해 SOP를 적용하며, 두 URL이 아래 세 가지가 모두 같아야 같은 출처로 간주한다.
Access-Control-Allow-Origin 헤더를 설정해두면 다른 출처에서도 요청 가능브라우저와 서버가 비동기로 데이터를 주고받는 전통적인 방식 (Ajax의 핵심 기술). onload, onerror 같은 이벤트 콜백 기반으로 동작.
XHR의 현대적 대안. Promise 기반이라 .then() 체이닝이나 async/await와 훨씬 잘 어울리고 문법도 간결하다.
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
.then()으로 비동기 흐름을 연결하고, .catch()로 에러를 한 곳에서 처리할 수 있다는 게 핵심.
| 항목 | XHR | Fetch |
|---|---|---|
| 문법 | 다소 복잡 | 간결 |
| 비동기 처리 | 콜백 기반 | Promise 기반 |
| 브라우저 지원 | 레거시 포함 | 모던 브라우저 위주 |
| 부가 기능 | 진행률 추적 등 | 상대적으로 단순 |
→ 실무에서는 대부분 Fetch API를 권장.
Fetch API나 axios로 API를 호출하고, useEffect로 컴포넌트 마운트 시점에 데이터를 불러온다vite.config.js 등에서 개발 서버 프록시를 설정해 우회할 수 있음Access-Control-Allow-Origin 헤더를 제대로 설정해야 한다사용자 입력을 그대로 쿼리에 끼워 넣으면, ' OR '1'='1' 같은 입력값이 조건문을 항상 참으로 만들어버려 인증을 무력화시킬 수 있다.
?)와 값을 분리해서 바인딩하면, 입력값은 항상 '문자열'로만 취급되어 명령어로 실행되지 않는다악성 스크립트를 페이지에 삽입해 사용자 브라우저에서 실행시키는 공격.
<, >, ", ', & 같은 특수문자를 HTML 엔티티로 이스케이프 처리 → 코드가 아닌 순수 텍스트로 인식되게 만듦innerHTML을 직접 다룰 때는 주의 필요사용자가 의도하지 않은 요청이 자신도 모르게 실행되는 공격.
SameSite 쿠키 속성, Referer 헤더 검증, 중요 작업 시 재인증 요구도 함께 사용CORS는 브라우저의 보안장치일 뿐이고, 진짜 보안은 서버의 입력값 검증 + 인증/인가 + 암호화 + 지속적인 모니터링에서 나온다.