web2

CSRF(Cross-Site Request Forgery)

maru_ 2026. 6. 4. 20:39
<form aciton="https://maru.com/change-email" method="POST"
  <input type="hidden" name="email" value="attacker@maur.com">
 </form>
 
 <script>
   document.forms[0].submit();
 </script>

CSRF(Cross-Site Request Forgery)

사이트 간 요청 위조

- 사용자가 어떤 사이트에 로그인된 상태를 이용해서, 공격자가 사용자의 브라우저로 하여금 원치 않는 요청을 보내게 만드는 공격

 

csrf의 흐름을 간단하게 살펴보면

1. maru 사이트에 로그인함

2. 브라우저에 maru사이트 쿠키 저장됨 (ex: session=maru123)

3. 이 상태에서 사용자가 공격자 사이트에 접속함

4. 공격자 사이트 HTML/JS가 maru사이트로 요청을 발생시킴

예를들면,,

- <img src="https://maru.com/delete">

- location.href = "https://maru.com/chage?email=ina~

- 자동 submit form

5. 브라우저는 요청 목적지가 maru.com인 걸 보고 maru.com의 쿠키를 자동 첨부

6. maru사이트 서버가 쿠키만 보고 로그인된 사용자의 요청으로 보고 요청을 처리하면 피해 발생

 

 

GET / POST

GET
- 보통 서버에서 데이터를 가져올 때 사용

예를들어서

<form action="/search" method="GET>
  <input name="q">
  <button type="submit">검색</button>
 </form>

이런 검색 기능이 있고

사용자가 검색창에 xss를 입력하고 검색하면 브라우저는

/search?q=xss 요런 주소로 이동한다

서버에서는 q=xss 라는 값을 받은 것,,

 

GET의 특징
- URL에 데이터가 보인다

--> 그래서 주소를 복사해서 다른 사람에게 보내도 같은 검색 결과를 볼 수 있음

예를 들면, 우리가 네이버 검색 결과 url을 공유하거나 이런것들

그래서, GET은 

- 검색하기

- 게시글 조회

- 상품 목록 보기

- 페이지 이동

- 필터 / 정렬 적용

과 같은 데이터 조회 기능에 잘 어울린다

 

POST

- 보통 서버에 데이터를 제출하거나 상태를 바꿀 때 사용

예를들어서 

<form action="/change-email" method="POST">
  <input name="email">
  <button type="submit">변경</button>
</form>

이메일 변경 기능이 있는 경우에 이렇게 폼을 작성하고

사용자가 새로운 이메일 주소를 입력하고 제출하면 브라우저는

POST /change-email HTTP/1.1
Host: maru.com
Cookie: session=abc123

email=ina@maru.com

이런 요청을 서버에 보내는데

여기에서 GET과 다르게 데이터가 url이 아닌 요청 body 안에 들어간다는 것이다

그래서 POST요청은

주소창에 /change-email 이렇게만 보이고

데이터 email=ina@maur.com은 요청 본문에 들어간다

 

POST의 특징

- 서버의 상태를 바꾸는 기능에 어울림 (주로 제출, 생성, 변경 같은 것들)

- 데이터는 요청 본문에 들어감

그래서 보통

- 로그인

- 회원가입

- 댓글 작성

- 게시글 작성

- 비밀번호 변경

- 이메일 변경

- 결제 요청

- 파일 업로드

같은 기능에서 쓰임

로그인 예시 코드를 보면

<form action-"/login" method="POST">
  <input name="id">
  <input name="pw" type="password">
  <button>로그인</button>
</form>

이런 코드로 쓰이고

여기에

id = maru

pw = 1234 

입력을 하면

POST /login HTTP/1.1
Host: example.com

id=maru&pw=1234

이런식으로 요청이 발생하고

 URL은 보통 /login 이렇게만 보임

 

 

이 2개 method 모두 보안적으로 보면

GET =  URL에 데이터가 노출되므로 민감정보 전달에 부적절

POST = URL에 안 보이지만 암호화는 아님

--> HTTPS가 있어야 네트워크에서 보호된다

 

CSRF와 연결해보면,, 

GET은

<img src="https://a.com/delete-account">

이미지 태그로 브라우저가 GET요청을 보내게 함

<img src> 태그 만으로도 요청이 나갈 수 있어 위험함

=> 그래서 중요한 상태 변경 기능이 GET이면 위험!

 

마찬가지로 POST도 위험한데

<img src>는 쓸 수 없지만

<form action="https://a.com/change-email" method="POST">
  <input type="hidden" name="email" value="attacker@example.com">
</form>

<script>
  document.forms[0].submit();
</script>

이렇게 form으로 자동 요청을 제출할 수 있다.

 

**forms[0]의 의미는..?**

- 현재 HTML 문서 안에 있는 form들 중 첫 번째 form을 의미

예를들어서,

<form action="/login" method="POST"
  <input name="id">
</form>

<form action="/search" method="GET">
  <input name="q">
</form>

HTML이 이렇게 있을 때

document.form[0]  // 첫 번째 form: /login
document.form[1] //  두 번째 form: /search

이런식으로,, 인덱스로 순서 표현

인덱스말고 form에 이름 붙여서 쓰면 더 명확하게 쓸 수 있음

<form id="maru" action="https://maru.com/change-email" method="POST">
  <input type="hidden" name="email" value="attacker@maru.com">
</form>

<script>
  document.getElementBtyId("maru").submit();
</script>

요런식으로,, id=이름 붙여서 하면 더 명확

 

CSRF를 정리해보면,

사용자가 로그인한 사이트의 쿠키가 브라우저에 저장되어 있다는 점을 악용해서,

사용자가 공격자 사이트에 접속했을 때 공격자 사이트가 해당 사이트로 요청을 보내게 만들고, 이때 브라우저가 로그인 쿠키를 자동으로 첨부하면서 서버가 이를 정상 요청으로 처리하게 만드는 공격이다

 

1. 브라우저에 로그인 쿠키가 저장돼 있음

2. 공격자 사이트가 해당 사이트로 요청을 보내게 만듦

3. 브라우저가 해당 사이트 쿠키를 자동으로 붙임

4. 해당 사이트가 그 요청을 정상 요청처럼 처리해버림

 

XSS랑 비교해서 정리해보면,

XSS

- 피해자 브라우저에서 공격자 스크립트가 실행

- 주로 브라우저 내부 동작을 장악하는 느낌

- 쿠키 탈취, 화면 변조, 악성 요청 전송 ,,이런것들

CSRF

- 피해자 브라우저가 로그인된 상태의 쿠키를 가지고 요청을 보내게 됨

- 주로 로그인된 사용자의 권한을 악용하는 느낌

- 이메일 변경, 글 작성, 회원 탈퇴 같은 요청 유도 가능

 

 

 

'web2' 카테고리의 다른 글

Server-Side Request Forgery (SSRF)  (0) 2026.06.28
docker 사용하기 (run, compose)  (0) 2026.06.17
DOM-based XSS  (0) 2026.06.02
웹은 어떻게 동작하나요(HTML,JS,CSS,브라우저의 관계)  (0) 2026.05.31
XSS (cross-site scripting)  (0) 2026.05.30