작업 환경
- VMware Workstation Pro (17.6.2 ver)
- Server
- Web 서버 : Rocky_Linux(8.10 ver, VMnet 2, PHP로 구성)
- DNS 서버 : Rocky_Linux(8.10 ver, VMnet 1)
- Client
- Kali Linux : Web 취약점 점검용 (VMnet 1)
- GNS 구성
- 해당 점검은 게시글 페이지에 한해서 진행됨
CF (상) | 15. 크로스사이트 리퀘스트 변조(CSRF) |
취약점 개요 | |
점검 내용 | 사용자의 신뢰(인증) 정보의 변조 여부 점검 |
점검 목적 | 사용자 입력 값에 대한 적절한 필터링 및 인증에 대한 유효성을 검증하여 신뢰(인증) 정보 내의 요청(Request)에 대한 변조 방지 |
보안 위협 | 사용자의 신뢰(인증) 정보 내에서 사용자의 요청(Request)을 변조함으로써 해당 사용자의 권한으로 악의적인 공격을 수행할 수 있음 |
판단 기준 |
양호 : 사용자 입력 값에 대한 검증 및 필터링이 이루어지는 경우 취약 : 사용자 입력 값에 대한 필터링이 이루어지지 않으며, HTML 코드(또는 스크립트)를 입력하여 실행되는 경우 |
참고 | OWASP TOP 10 항목 중 A01 : Broken Access Control A07 : Identification and Authentication Failures 에 해당한다고 판단 |
점검 방법
- Step 1) XSS 취약점이 존재하는지 확인
- XSS 취약점 → 이전 발행글 확인
2025.05.13 - [주요정보통신기반시설가이드/Web 취약점 점검] - [XS (상)] 11. 크로스사이트 스크립팅
[XS (상)] 11. 크로스사이트 스크립팅
작업 환경VMware Workstation Pro (17.6.2 ver)Server Web 서버 : Rocky_Linux(8.10 ver, VMnet 2, PHP로 구성)DNS 서버 : Rocky_Linux(8.10 ver, VMnet 1)ClientKali Linux : Web 취약점 점검용 (VMnet 1)GNS 구성해당 실습은 게시글페이지에
jijibae.tistory.com
- Step 2) 등록 및 변경 등의 데이터 수정 기능의 페이지가 있는지 조사함
- 비밀번호 수정 페이지는 데이터의 수정 가능
- Step 3) 데이터 수정 페이지에서 전송되는 요청(Request) 정보를 분석하여 임의의 명령을 수행하는 스크립트 삽입 후 해당 게시글을 타 사용자가 열람하였을 경우 스크립트가 실행되는지 확인
- 공격자가 게시글 페이지에 아래의 코드를 포함하여 게시물 작성
- 해당 버튼을 클릭시 해당 사용자의 비밀번호가 1 로 변경됨
<form method=POST action=proc/update_proc.php>
<input type=hidden name=pw value=1>
<input type=submit value='lotto!!!'>
</form>
해시 함수를 사용하여 비밀번호 암호화를 하여도 비밀번호가 변경되는 것을 확인할 수 있으며
이를 이용하여 공격자가 test123 계정으로 로그인하여 피해를 줄 수 있음
보안 설정 방법
- 웹 사이트에 사용자 입력 값이 저장되는 페이지는 요청이 일회성이 될 수 있도록 설계
- 사용 중인 프레임워크에 기본적으로 제공되는 CSRF 보호 기능 사용
- 사용자가 정상적인 프로세스를 통해 요청하였는지 HTTP 헤더의 Referer 검증 로직 구현
- 정상적인 요청(Request)과 비정상적인 요청(Request)를 구분할 수 있도록 Hidden Form을 사용하여 임의의 암호화된 토큰(세션 ID, Timestamp, nonce 등)을 추가하고 이 토큰을 검증하도록 설계
- HTML이나 자바스크립트에 해당되는 태그 사용을 사전에 제한하고, 서버 단에서 사용자 입력 값에 대한 필터링 구현
- HTML Editor 사용으로 인한 상기사항 조치 불가 시, 서버 사이드/서블릿/DAO(Data Access Object) 영역에서 조치하도록 설계
- XSS 조치 방안 참조
참고
📌 CSRF 란 ?
CSRF는 공격자가 사용자의 브라우저를 이용해 인증된 상태로
원하지 않는 요청을 서버에 보내도록 유도하는 공격
- 피해자가 로그인된 상태를 노려 의도하지 않은 요청을 서버가 수행하게 만드는 공격
- 요청 예시 : 비밀번호 변경, 글 삭제, 계좌 이체 등
XSS vs CSRF 차이점
항목 | XSS (Cross-Site Scripting) | CSRF (Cross-Site Request Forgery) |
공격 대상 | 사용자 브라우저 | 서버의 인증된 요청 처리 |
공격 조건 | 사용자가 악성 스크립트를 직접 실행하게 유도 | 사용자가 로그인한 상태에서 공격자가 서버로 요청을 보내게 유도 |
실행 위치 | 피해자 브라우저 안에서 | 피해자의 인증된 세션을 통해 서버에서 |
예시 | <script>alert('XSS')</script> | <form method=POST ~~ 요청> |
쿠키 활용 | 불필요 (JS로 직접 조작) | 필요 (자동 쿠키 포함으로 인증 요청 유도) |
방어 | htmlspecialchars(), strip_tags() 등 | CSRF Token, Referer 검증, SameSite 쿠키 |
CSRF 방어 방법
1. CSRF 토큰
- 요청마다 임의 토큰을 부여하고, 서버는 이 값이 맞는지 검증
- 이 예시에는 update.php 에 CSRF 토큰을 삽입하고, update_proc.php 에서 검증을 한다
① update.php 에 CSRF 토큰 생성
<?php
session_start();
// CSRF 토큰 생성 (세션에 저장)
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['csrf_token'];
?>
...중략
- random_bytes(32) : 매 요청모다 고유하게 생성 가능(유일성)
- 세션 기반 : 토큰은 세션에 저장되어 서버 기준 유효성 검증 가능
② 토큰을 update.php form 안에 <input type="hidden">으로 추가
...중략
<form action="proc/update_proc.php" method="POST">
<input type="password" name="pw" placeholder="새 비밀번호" required><br>
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($token) ?>">
<input type="submit" value="비밀번호 변경">
</form>
...중략
- hidden input 이라서 사용자 모르게 자동 제출
③ update_proc.php 에서 토큰 검증 로직 추가
<?php
session_start();
// CSRF 토큰 검증
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die("CSRF 공격 의심: 요청이 거부되었습니다.");
}
③ - ① 더 자세한 결과를 위해 update_proc.php 추가
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
echo "POST 토큰: " . htmlspecialchars($_POST['csrf_token'] ?? '없음') . "<br>";
echo "SESSION 토큰: " . htmlspecialchars($_SESSION['csrf_token'] ?? '없음') . "<br>";
die("CSRF 공격 의심: 요청이 거부되었습니다.");
}
- 검증 성공 시 정상적으로 비밀번호 변경 로직 실행
- 실패 시 요청 중단
해시 값이 클릭 전, 후로 동일한 것을 확인
비밀번호 변경 요청이 서버에서 거부되었다.
2. SameSite 쿠키
- PHP 7.2 이하 : SameSite 공식으로 미지원
- PHP 7.3 이상 : SameSite 공식 지원
① /var/www/html/include/session_secure.php 파일에 아래 내용 추가
<?php
session_set_cookie_params(
0,
'/; samesite=Strict',
'',
true,
true
);
session_start();
- path + SameSite 속성 우회하여 삽입
② 모든 페이지 상단에서 다음을 추가
require_once("../include/session_secure.php");
- 현재 폴더 구조는 상단으로 한 번 올라가야 /var/www/html 인 구조
🔐 OWASP TOP 10(2021)과의 연관
OWASP TOP 10 공식문서중 일부
"Cross-Site Request Forgery (CSRF) vulnerabilities allow attackers to induce users to perform actions they do not intend to. CSRF attacks exploit the trust that a site has in a user's browser."
1. A01: Broken Access Control
- 서버가 인증된 사용자의 의도를 검증하지 않고 민감 요청을 수행
2. A07 : Identification & Authentication Failures
- 인증된 요청이라도 별도의 확인 절차 없이 민감 작업 수행 시 포함
'주요정보통신기반시설가이드 > Web 취약점 점검' 카테고리의 다른 글
[IN (상)] 17. 불충분한 인가 (0) | 2025.05.13 |
---|---|
[SE (상)] 16. 세션 예측 (0) | 2025.05.13 |
[PR (상)] 14. 취약한 패스워드 복구 (0) | 2025.05.13 |
[IA (상)] 13. 불충분한 인증 (1) | 2025.05.13 |
[BF (상)] 12. 약한 문자열 강도 (0) | 2025.05.13 |