작업 환경

  • 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 구성

  • 해당 실습은 비밀번호 수정 페이지에 한해서 진행됨
IN (상) 17. 불충분한 인가
취약점 개요
점검 내용 민감한 데이터 또는 기능에 접근 및 수정 시 통제 여부 점검
점검 목적 접근 권한에 대한 검증 로직을 구현하여 비인가자의 악의적인 접근을 차단하기 위함
 보안 위협 접근제어가 필요한 중요 페이지의 통제수단이 미흡한 경우, 비인가자가 URL 파라미터 값 변경 등의 방법으로
중요 페이지에 접근하여 민감한 정보 열람 및 변조 가능함
판단 기준

양호 : 접근제어가 필요한 중요 페이지의 통제수단이 적절하여 비인가자의 접근이 불가능한 경우
취약 : 접근제어가 필요한 중요 페이지의 통제수단이 미흡하여 비인가자의 접근이 가능한 경우
참고 OWASP TOP 10 항목 중 
A01 : Broken Access Control
에 해당한다고 판단

 

 

점검 방법

  • Step 1) 비밀 게시글(또는 개인정보 변경, 패스워드 변경 등) 페이지에서 다른 사용자와의 구분을 ID, 일련번호 등의 단순한 값을 사용하는지 조사

URL 상 표시 X
세션 ID 값으로 사용자 구별

  • Step 2) 게시글을 구분하는 파라미터 값을 변경하는 것만으로 다른 사용자의 비밀 게시글 (또는 개인정보 변경, 패스워드 변경 등)에 접근 가능한지 확인

 

BurpSuite 를 사용하여도 해당 유저의 값만 바꿀 수 있음

다른 사용자의 패스워드에는 접근 불가능


보안 설정 방법

  • 접근제어가 필요한 중요 페이지는 세션을 통한 인증 등 통제수단을 구현하여 인가된 사용자 여부를 검증 후 해당 페이지에 접근할 수 있도록 함
  • 페이지별 권한 매트릭스를 작성하여 접근제어가 필요한 모든 페이지에서 권한 체크가 이뤄지도록 구현하여야 함

참고

🔐 OWASP TOP 10(2021)과의 연관

OSASP TOP 10 공식 문서중 일부
"Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification or destruction of all data or performing a business function outside of the user's limits."

1. A01:  Broken Access Control

  • URL 또는 요청 파라미터를 조작하여 다른 사용자의 데이터에 접근하는 경우
  • 로그인하지 않은 상태에서 인증이 필요한 페이지에 접근하는 경우
  • 일반 사용자가 관리자 권한이 필요한 기능을 수행할 수 있는 경우

작업 환경

  • 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 구성

  • 해당 실습은 비밀번호 수정 페이지에 한해서 진행됨
SE (상) 16. 세션 예측
취약점 개요
점검 내용 단순한 방법(연속된 숫자 할당 등)으로 생성되는 세션 ID를 예측하여 세션 탈취 여부 점검
점검 목적 사용자의 세션ID를 추측 불가능하도록 난수로 생성하여 공격자의 불법적인 접근을 차단하기 위함
 보안 위협 사용자에게 전달하는 세션 ID가 일정한 패턴을 가지고 있는 경우 공격자가
세션 ID를 추측하여 불법적인 접근을 시도할 수 있음
판단 기준

양호 : 추측 불가능한 세션 ID가 발급되는 경우
취약 : 세션 ID가 일정한 패턴으로 발급되는 경우
참고 OWASP TOP 10 항목 중 
A07 : Identification and Authentication Failures
에 해당한다고 판단

 

 

PHP의 경우에는 session start(); 를 사용하면 임의의 세션 ID를 발급해준다.

추가적인 설정과 세션에 대해서는 참고 확인

 

점검 방법

  • Step 1) 각기 다른 IP 주소와 다른 사용자명, 시간적 차이로 세션 ID를 발급받음
  • Step 2) 발급받은 세션 ID에 일정한 패턴이 있는지 조사
  • Step 3) 일정한 패턴이 확인되고, 패턴에 의해 사용 가능한 세션 ID의 예측이 가능한지 확인

 

① jijibaeee 계정으로 로그인한 경우

jijibaeeee 로 로그인한 경우

 

② test123 계정으로 로그인한 경우

test123으로 로그인한 경우

 

 

③ (②) 에서 로그아웃을 하고 다시 test123 계정으로 로그인한 경우

다시 test123 으로 로그인한 경우

 


보안 설정 방법

  • 아무리 길이가 길고 복잡한 항목으로 세션 ID가 만들어져도 공격자가 충분한 시간과 자원이 있다면 뚫는 것은 불가능하지 않으므로 강력한 세션 ID를 생성하여야 함 주된 목적은 수많은 대역폭과 처리 자원을 가지고 있는 공격자가 하나의 유효한 세션 ID를 추측하는데 최대한 오랜 시간이 걸리게 하여 쉽게 추측하지 못하게 하는 것에 있음
  • 단순 조합보다는 상용 웹 서버나 웹 애플리케이션 플랫폼에서 제공하는 세션 ID를 사용하고, 가능하다면 맞춤형 세션 관리 체계를 권고함
  • 세션 ID는 로그인 시마다 추측할 수 없는 새로운 세션 ID로 발급하여야 함

참고

📌 세션 ID란 ?

웹 애플리케이션에서 사용자의 상태를 유지하기 위해 생성되는 고유한 식별자

  • 세션 값에 접근하기 위한 키(Key) 역할을 하는 고유 식별자
  • 즉, 브라우저에 저장되는 임의의 고유 식별자
  • 난수를 사용하고 위 점검 예시의 Value 에 해당
    • Name 은 세션 이름(Key)

 

📌 세션값이란 ?

세션에 저장된 실제 데이터

  • 사용자 이름, 권한과 같은 데이터
  • 브라우저에 안 보임 → 서버에 저장
    • $_SESSION['user_id'] 및 $_SESSION['nickname'] 과 같은 사용자의 정보임
  • 사용자의 정보이므로 난수가 아님

 

비유

요소 역할
세션 이름 (PHPSESSID) “출입증 이름” – 고정된 이름표
세션 ID (bgceffgcap...) “출입증 번호” – 고유 번호 (매번 새로 발급 가능)
세션값 ($_SESSION) “출입증 내부 데이터” – 사용자 이름, 권한 등 서버가 관리하는 상태

 

 

PHP에서 세션 설정 

  • session_start() 호출 시 PHP가 자동으로 세션을 설정
  • 기본값으로 설정한 경우 아래의 기본 설정이 들어감 → 충분히 강력하여 무작위 대입 공격 불가
    • session.sid_length : 26
    • session.sid_bits_per_character : 5
    • session.hash_function : sha1 또는 php

 

/etc/php.ini 에서 추가로 설정해보기

session.sid_length = 128
session.sid_bits_per_character = 6
session.hash_function = sha512
  • sid_length : 세션 ID의 전체 길이
  • sid_bits_per_character : 세션 ID를 구성할 때 한 문자당 몇 비트를 사용할지 (6 이상 권장)
  • hash_function : 내부적으로 세션 ID를 생성할 때 사용할 해시 알고리즘 (sha512 권장)

 

② 로그인 시마다 세션 ID 재발급

  • 로그인 성공 시 아래의 코드에 발급
/var/www/html/proc/login_proc.php

session_start();
session_regenerate_id(true);
  • session_regenerate_id(true) : 세션 ID를 로그인 시마다 재발급 받음으로 세션 하이재킹 방지
  • 세션 고정(Session Fixation) 공격 방지

 

 

🔐 OWASP TOP 10(2021)과의 연관

OWASP TOP 10 공식문서중 일부
"CWE-384: Session Fixation – The application does not assign a new session ID upon successful login. This allows an attacker to set or predict a user’s session identifier and hijack their session once they log in."

1. A07 :  Identification and Authentication Failures

  • 세션 ID가 단순하거나 순차적으로 생성되어 공격자가 쉽게 추측할 수 있는 경우
  • 사용자가 로그인하기 전에 세션 ID가 고정되어 있어, 공격자가 해당 세션 ID를 이용하여 사용자의 세션을 탈취할 수 있는 경우

작업 환경

  • 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 계정 정보 (PW : test123)
test123 계정으로 Lotto 클릭시

 

클릭 후 test123 계정 확인(PW : 1)

 

해시 함수를 사용하여 비밀번호 암호화를 하여도 비밀번호가 변경되는 것을 확인할 수 있으며
이를 이용하여 공격자가 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 공격 의심: 요청이 거부되었습니다.");
}

 

  • 검증 성공 시 정상적으로 비밀번호 변경 로직 실행
  • 실패 시 요청 중단

 

새로운 계정 추가(PW : jijibaeeee)
Lotto 클릭
CSRF 탐지하여 요청 거부
자세한 결과로 확인해보기
DB 확인

해시 값이 클릭 전, 후로 동일한 것을 확인
비밀번호 변경 요청이 서버에서 거부되었다.

 

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

  • 인증된 요청이라도 별도의 확인 절차 없이 민감 작업 수행 시 포함

작업 환경

  • 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 구성

  • 해당 실습은 비밀번호 수정 페이지에 한해서 진행됨
PR (상) 14. 취약한 패스워드 복구
취약점 개요
점검 내용 웹 사이트 내 패스워드 복구 절차의 적절성 점검
점검 목적 패스워드 복구 로직을 유추하기 어렵게 구현하고, 인증된 사용자 메일이나 SMS에서만
복구 패스워드를 확인할 수 있도록하여 비인가자를 통한 사용자 패스워드 획득 및 변경을 방지하기 위함
 보안 위협 취약한 패스워드 복구 로직(패스워드 찾기 등)으로 인하여 공격자가 불법적으로
다른 사용자의 패스워드를 획득, 변경할 수 있음
판단 기준

양호 : 패스워드 재설정 시 난수를 이용하여 재설정되고 인증된 사용자 메일이나
SMS로 재설정된 패스워드 혹은 패스워드 재설정을 위한 링크 전송 시

취약 : 패스워드 재설정 시 일정 패턴으로 재설정되고 웹 사이트 화면에 바로 출력 시
참고 OWASP TOP 10 항목 중 
A07 : Identification and Authentication Failures
에 해당한다고 판단

 

 

점검 방법

  • Step 1) 재설정(또는 패스워드 찾기)되는 패스워드 몇 개를 획득하여 사용자의 연락처, 주소, 메일 주소, 일정 패턴을 패스워드로 이용하고 있는지 확인하고 재설정된 패스워드를 인증된 사용자 메일이나 SMS로 전송하는지 확인

 

해당 점검은 테스트 서버 대상이므로 인증 절차 존재하지 않음


보안 설정 방법

  • 사용자의 개인정보(연락처, 주소, 메일 주소 등)로 패스워드를 생성하지 말아야 하며, 난수를 이용한 불규칙적이고 최소 길이(6자 이상 권고) 이상의 패턴이 없는 패스워드를 발급하여야 함
  • 사용자 패스워드를 발급해주거나 확인해줄 때 웹 사이트 화면에 바로 출력해주는 것이 아니라 인증된 사용자 메일이나 SMS로 전송해주어야 함
  • 패스워드 재발급 검증 실패에 대한 임계값을 설정하여 일정 횟수 이상 실패한 경우 다른 방식으로 패스워드 찾기 기능을 제공하여야 한다. 검증 후 기존의 패스워드가 아닌 임시패스워드를 발급하도록 설계해야 하며, 사용자가 임시패스워드를 발급받은 즉시 새로운 패스워드로 재설정하도록 구현하여야 함

참고

🔐 OWASP TOP 10(2021)과의 연관

OWASP 설명 중 일부:
“Verification mechanisms for password recovery should be just as secure as login mechanisms.”

1. A07 : Identification and Authentication Failures

  • 비밀번호를 재설정하거나 찾는 과정에서 인증이 불충분하거나, 정보 노출, 예측 가능한 토큰 사용 등으로 인해
    계정 탈취로 이어질 수 있는 취약점
  • 복구도 인증 과정