πŸ”“ WEB-12: IDOR (κΆŒν•œ 검증 λΆ€μž¬)

μ‚¬μš©μž ID둜 직접 객체 μ°Έμ‘° μ‹œ κΆŒν•œ 검증 μ—†μ–΄ 타인 정보 쑰회/μˆ˜μ • κ°€λŠ₯

πŸ‘₯ μ‚¬μš©μž λͺ©λ‘ (μ„ νƒν•˜μ—¬ 쑰회)

πŸ’‘ IDOR 곡격:
β€’ URL 직접 μˆ˜μ •: ?user_id=3 β†’ λ‹€λ₯Έ μ‚¬μš©μž 정보 쑰회
β€’ 순차적으둜 ID 증가: 1, 2, 3, ... β†’ λͺ¨λ“  μ‚¬μš©μž 정보 μˆ˜μ§‘ (정보 μˆ˜μ§‘)
β€’ API 호좜 μžλ™ν™”: for i in range(1,100): fetch('/api/user/'+i)

βœ… λ°©μ–΄ 방법

1. κΆŒν•œ 검증 μΆ”κ°€:

$requested_id = $_POST['user_id'];
$current_user_id = $_SESSION['user_id'];

// μžμ‹ μ˜ μ •λ³΄λ§Œ 쑰회 κ°€λŠ₯
if ($requested_id !== $current_user_id) {
  die('Unauthorized');
}

// λ˜λŠ” κ΄€λ¦¬μž κΆŒν•œ 확인
if ($current_user['role'] !== 'admin') {
  die('Admin only');
}

2. κ°„μ ‘ μ°Έμ‘° (Indirect Reference) μ‚¬μš©:

// 직접 ID λŒ€μ‹  UUID λ˜λŠ” ν•΄μ‹œ μ‚¬μš©
$user_hash = md5($user_id . $secret);
$stmt = $db->prepare("SELECT * FROM users WHERE hash = ? AND id = ?");
$stmt->execute([$user_hash, $requested_id]);

3. μ ‘κ·Ό μ œμ–΄ λͺ©λ‘ (ACL):

// κΆŒν•œ ν…Œμ΄λΈ”λ‘œ 확인
$stmt = $db->prepare("SELECT 1 FROM acl WHERE user_id = ? AND can_access_user = ?");
$stmt->execute([$current_user_id, $requested_id]);

4. λ‘œκΉ… 및 λͺ¨λ‹ˆν„°λ§:

// κΆŒν•œ μ—†λŠ” μ ‘κ·Ό μ‹œλ„ 기둝
log_security_event([
  'type' => 'UNAUTHORIZED_ACCESS',
  'user_id' => $current_user_id,
  'target_id' => $requested_id,
  'timestamp' => time()
]);