Normaltic 모의해킹 취업반 스터디 8기 - 13주차

containerxox·2025년 7월 2일
post-thumbnail

☑️ XSS와 CSRF의 차이

  • 공통점: CSRF와 XSS 둘다 클라이언트를 공격하는 기법
  • 차이점
    XSS클라이언트측 스크립트(HTML, Javascript)를 삽입하여 클라이언트 측 웹 브라우저에서 실행되게 만드는 공격기법
    CSRF사용자가 원치 않은 요청을 서버로 전송하게 만드는 공격 기법



☑️ CSRF 공격을 수행할 때 GET 방식으로 요청을 보내는 경우와 POST 방식으로 요청을 보내는 경우

  • GET Method
    예시로 http://vuln.com/mypage.php?pass=1234
    해당 링크를 사용자가 클릭하게만 만들면 비밀번호 요청을 보내는 공격을 할 수 있다.
  • POST Method
    POST 방식의 요청은 링크를 클릭해서는 공격을 시도할 수 없다.
    데이터를 요청의 body에 담아 보내야 하기 때문에 <form>태그나 자바스크립트를 사용해야 한다.
    그런데 <form> 태그를 사용하려면 < 꺾쇠를 삽입할 수 있어야 하므로 XSS 취약점이 존재해야 한다.
    즉, POST 방식의 CSRF 공격을 성공시키려면 XSS 공격이 가능해야 한다.



☑️ CSRF Token의 한계

▶ (참고) GET Admin 3 풀이:
https://velog.io/@containerxox/Normaltic-%EB%AA%A8%EC%9D%98%ED%95%B4%ED%82%B9-%EC%B7%A8%EC%97%85%EB%B0%98-%EC%8A%A4%ED%84%B0%EB%94%94-8%EA%B8%B0-12%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9CCTF-Write-up#%EF%B8%8F-get-admin-3

➡️ CSRf 토큰은 XSS취약점이 존재하면 탈취가능, 우회가 가능하다.
➡️ 하지만, XSS 취약점이 존재하지 않으면 우회하기 힘들다.



☑️ CSRF 대응 방안

  • Referer 체크
  • 요청 위조가 불가능하게 인증정보 넣기
  • CSRF 토큰 추가
  • SOP
  • CORS

① Referer 헤더 체크

  • Referer 헤더는 HTTP 요청 헤더
  • 지금 이 요청이 어디에서 왔는지를 알려주는 헤더

    ✔️ ( 예시 ) 게시글 작성 프로세스
    /csrf_1/notice_write.php 페이지에서 글 작성 → create 버튼 클릭
    /csrf_1/notice_write_process.php로 요청을 보냄.
    Referer 헤더를 보면 해당 요청을 보낸 곳이 http://ctf.segfaulthub.com:7575/csrf_1/notice_write.php임을 확인할 수 있다.

⭐ 즉, referer 헤더를 확인하는 것도 CSRF 대응방법 중 하나이다.

Referer 헤더를 통해 요청이 어떤 페이지에서 발생했는지 확인함으로써, 의심스러운 경로에서 들어온 요청인지 여부를 판단할 수 있다.

🔸 부적절한 예외 처리로 인한 Referer 우회

💁‍♀️< 비밀번호를 변경하려면 반드시 mypage.php를 통해서만 요청할 수 있도록 개발했다고 가정 >
이렇게 개발을 하면 확장성이 떨어진다는 단점이 있다.
요즘은 한 사이트가 여러 다른 사이트와 연동되는 경우가 많은데, 이 방식이라면 비밀번호 변경 페이지는 무조건 mypage.php를 거쳐야만 한다.

예시로, 사용자가 로그인한 뒤 30일 이상 비밀번호를 변경하지 않아 메인 화면에서 비밀번호 변경 페이지가 바로 뜬 상황을 생각해보자.
사용자가 새 비밀번호를 입력하고 submit을 눌러도, 요청이 mypage.php에서 온 것이 아니기때문에
아래 사진처럼 응답 결과가 Invalid referer haeder라는 실패로 처리된다.

➡️ 이처럼 Referer 기반 검증에는 이런 한계가 있다.

그래서 개발자들은 예외 상황이 발생하면 이를 처리하기 위해 예외처리(try-catch)를 추가한다.
그런데 종종 예외가 발생하면 '일단 통과시키자'는 식으로 처리하기도 한다.
이 경우 Referer헤더가 없는 요청으로 우회가 가능해진다. ( referer헤더가 없다는 예외가 발생 → 일단 통과시켜 )
또한<meta name="referrer" content="no-referrer">를 사용하면 브라우저가 Referer 헤더를 아예 보내지 않도록 할 수도 있다

(예시) Referer 헤더가 없는 경우

물론 Referer체크는 무조건 우회가 가능한 것은 아니다.
보안 로직을 제대로 설계하고 예외 상황도 안전하게 처리한다면 우회방법은 존재하지 않는다.

즉, 위에서 소개한 우회 시나리오는 개발자가 문제(예외)가 발생했을 때,
이를 안전하게 처리하기 않고 무조건 통과시키는 방식으로 코드를 작성했기 때문에

Referer헤더가 없는 요청으로 우회가 가능해진 것이다.




② Request에 인증정보를 포함하도록 만들기

  • 요청을 위조할 수 없게 하려면, 요청 파라미터에 반드시 인증정보를 포함시켜야 한다.

    대표적인 인증정보 예시로는 비밀번호가 있다.
    그래서 실제로 마이페이지나 개인정보 변경 시에 사용자가 현재 비밀번호를 입력하도록 요구하는 경우가 많다.
    공격자가 페이로드를 작성하더라도, 요청에 반드시 현재 비밀번호를 포함해야 한다면,
    사용자의 비밀번호를 모르는 공격자는 요청을 위조할 수 없게 된다.
    즉, 요청 파라미터에 인증정보를 요구함으로써 CSRF 공격을 차단할 수 있다. 다만, CSRF 공격은 서버로 요청이 발생하는 모든 지점에서 발생가능하기 때문에 상황에 따라 대응 방법을 적절히 선택해야 한다.
    예를 들어, 비밀번호 변경 요청에는 반드시 인증정보(비밀번호)를 포함하도록 하고,
    게시판 글 작성과 같은 기능에는 CSRF 토큰이나 Referer 체크를 적용하도록 한다.
    왜냐하면, 게시판 글 작성에까지 비밀번호 입력을 요구하면 서비스 사용성이 크게 떨어지기 때문이다.
    즉, 상황에 맞게 적절한 대응 방법을 적용해야 한다.


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

하지만, 이러한 공격을 방지하기 위해 브라우저는 SOP(Same-Origin Policy)를 적용한다.
SOP같은 출처에 있는 자원만 자바스크립트로 접근할 수 있도록 제한한다.

즉, <iframe>을 통해 다른 출처의 페이지에 접근은 가능하지만,
자바스크립트로 다른 출처의 페이지의 데이터를 추출하는 것은 불가능
하다.
다른 출처의 자원에 접근하지 못하도록하는 SOP 덕분에 이런 공격을 막을 수 있다.

  • 같은 출처(Same-Origin)의 3가지 기준
  1. 스키마(프로토콜)
  2. 도메인(호스트)
  3. 포트
    가 같아야 같은 출처로 인정!





💁‍♀️ 요즘 개발자들을 보면 다른 도메인에 있는 데이터를 가져오거나, 다른 도메인에 요청을 보내는 경우가 많다.
SOP만 적용하면 이런 상황에서 너무 제한적이라 사용하는데 불편함이 생길 수 있다.
이런 한계를 보완하고 더 유연하게 다른 도메인의 요청을 허용할 수 있도록 나온 것이 CORS

④ CORS (Cross-Origin Resource Sharing, 교차 출처 리소스 공유)

: 몇 가지 규칙만 지키면 다른 출처에서도 데이터를 사용할 수 있게 해주는 정책

📜 ( 규칙 )

1️⃣ ACAO (Access-Control-Allow-Origin) 헤더
ACAO헤더는 서버가 Response에 포함시켜 보내는 헤더.
어떤 출처(origin)이 이 자원을 사용할 수 있는지 설정해준다.
↳ 이 헤더는 이 자원을 허용할 도메인을 설정해주는거야.
↳ 예시)



2️⃣ ACAC (Access-Control-Allow-Credentials) 헤더
↳ 쿠키, 인증 헤더(Authorization), TLS 클라이언트 인증서”와 같은
자격 증명(credentials)을 포함한 요청을 허용할지” 여부를 서버가 브라우저에 알려주는 헤더

기본적으로 브라우저는 보안을 위해 크로스 도메인 요청에 자격 증명(Cookie 등)을 포함하지 않는다.
⚠️ 하지만 !!
↳ 민감한 데이터(마이페이지, 결제 정보 등)는 쿠키인증이 필요하다 !
이런 요청이 다른 출처라면 ? ▶ 브라우저가 쿠키 포함 요청을 허용해야 한다 !
그래서 서버가 Access-Control-Allow-Credentials: true 를 응답에 포함시키면,
“브라우저야! 이 응답은 쿠키 같은 자격 증명을 포함한 요청도 허용해도 돼!”라고 허락
한다.

ACAC: true가 설정되면, Access-Control-Allow-Origin은 *를 쓸 수 없다 !
↳ 즉, 반드시 Access-Control-Allow-Origin에 구체적인 Origin 값을 설정해야 한다.
↳ 이유: 누구나 쿠키 포함 요청을 보낼 수 있게 되면, 개인정보가 노출될 수 있기 때문

✔️ ( 예시 )
↳ 이 응답은 https://normaltic.com에서 보낸 쿠키 포함 요청도 허용하겠다는 의미

Access-Control-Allow-Origin: https://normaltic.com
Access-Control-Allow-Credentials: true

   

💁‍♀️ 다른 출처에서의 접근을 제한하려면, SOP(동일 출처 정책)나 CORS처럼 허용할 출처를 White List로 관리해야 한다.
즉, 개발자가 직접 허용할 도메인을 ACAO헤더에 하나하나 등록해야 한다.

그런데 개발자 입장에서는 이 작업이 꽤 번거롭다. 허용가능한 도메인을 일일이 추가해줘야 하기 때문이다.
그래서 일부 개발자들은 귀찮음을 피하려고 ACAO: *로 설정해 모든 출처의 접근을 허용해버리기도 한다.
하지만, 이렇게 하면 ACAO헤더의 의미가 사실상 무색해진다.

특히 주목해야 할 점은, 쿠키가 포함된 요청에 대한 응답은 ACAO: *를 사용할 수 없다는 점이다.
예들 들어, 마이페이지처럼 개인정보가 포함된 페이지는 쿠키 인증이 필요하다.
사용자의 쿠키가 요청에 포함되어야 개인정보가 담긴 응답이 돌아오기 때문이다.

이때 브라우저는 응답이 쿠키를 포함한 요청에 대한 것인지 판단하기 위해 ACAC 헤더를 확인한다.
이 헤더가 Access-Control-Allow-Credentials: true로 설정되어 있으면
'이 응답은 쿠키를 포함한 요청에 대한 응답이다' 라는 의미
가 된다.

👉 다시 말해, 쿠키가 포함된 요청에 대해서는 ACAO*를 쓸 수 없고,
반드시 허용할 출처를 구체적으로 지정해야 한다.





💁‍♀️ *Access-Control-Allow-Origin(ACAO)헤더에 쓸 수 없는 상황에서는,
일부 게으른 개발자들이 *처럼 동작하도록 잘못된 설정을 해버리기도 한다.

아래 사진처럼, 서버가 Origin요청 헤더에 들어온 값 그대로를 ACAO에 넣어주는 방식으로 잘못 개발되면,
공격자 페이지에서 다른 도메인에 대한 요청도 허용되어 버린다.

이렇게 되면, 공격자는 자신의 악성 페이지에서 다른 도메인으로 비밀번호 변경요청을 보낼 수 있게 되어
XSS를 찾을 필요조차 없어지고, 사실상 SOP가 없는 거나 마찬가지
가 된다.
이는 CSRF 취약점으로 이어진다.




☑️ CORS 버그바운티 사례

1️⃣ Request

  • Origin 헤더를 보면 공격자가 만든 임의의 도메인 developersxzomato.com으로 요청이 보내지고 있다.
  • Referer는 여전히 실제 사이트((https://www.zomato.com/)로 되어 있어서 정상 사용자가 요청한 것처럼 보인다.
  • Cookie도 포함되어 있어서 사용자 인증 정보가 같이 전송되고 있다.

    👉 (조금 더 상세히 정리)

2️⃣ Response

  • 서버가 응답하면서 Access-Control-Allow-Origin: developersxzomato.com으로 응답.
    즉, 서버가 요청에 들어온 Origin을 그대로 신뢰해 버린 상태.
  • Access-Control-Allow-Credentials: true까지 설정되어 있어 쿠키가 포함된 요청도 허용된 상태.
  • 이로 인해, 공격자가 만든 도메인에서도 사용자의 민감한 계정정보에 접근할 수 있음.

🚨 문제점

  • developersxzomato.com은 원래 Zomato공식 도메인이 아님.
  • 서버가 Origin 값 검증 없이 그대로 ACAO에 넣어주면서 교차 출처 데이터 공유가 허술해짐
  • 결국 CORS 정책이 SOP를 우회하도록 허용되며 CSRF + 개인정보 유출까지 가능해짐.

정리
CORS설정이 잘못되면, 공격자가 만든 도메인도 허용되어 민감 정보가 탈취될 수 있다.
특히 Access-Control-Allow-Origin에 Origin을 무조건 반영하거나,
Access-Control-Allow-Credentials: true로 쿠키까지 허용하면 위험성이 매우 커진다!

📕 내가 궁금했던 것들
ACAOOrigin헤더와 비교하는거야? 아님 Referer헤더와 비교하는거야?
ACAOOrigin헤더와 비교한다.
Referer는 단순히 사용자가 이전에 어느 URL에서 왔는지를 알려주는 정보일 뿐이고, CORS검증의 대상이 아니다.



< 과 제 >

  • CSRF 문제들 고민해서 풀어보기
  • CSRF 정리(SOP, CORS)
  • 웹 개발 (db파일, 웹 소스파일)한거 제출하기

0개의 댓글