# User Enumeration Django lewat Timing Attack: CVE-2024-39329

> Kerentanan autentikasi Django memungkinkan penghitungan pengguna melalui perbedaan waktu dalam validasi password.

**URL:** https://www.ciptadusa.com/blog/django-user-enumeration-timing-attack-cve-2024-39329  
**Type:** blog  
**Author:** PT Cipta Dua Saudara  
**Category:** Keamanan Aplikasi  
**Published:** 2026-05-30  
**Cover:** https://www.ciptadusa.com/media/defaults/blog-cover.svg  

## Article

# Enumeration Pengguna Django melalui Timing Attack: CVE-2024-39329

## Ringkasan

Kerentanan keamanan ditemukan dalam sistem autentikasi Django yang memungkinkan penyerang jarak jauh menghitung nama pengguna yang valid melalui serangan waktu. Dilacak sebagai CVE-2024-39329, kerentanan ini mempengaruhi Django 5.0 sebelum 5.0.7 dan 4.2 sebelum 4.2.14.

## Detail teknis

### Deskripsi Kerentanan

Kerentanan ada pada metode `django.contrib.auth.backends.ModelBackend.authenticate()`. Saat memproses permintaan login untuk pengguna dengan password yang tidak dapat digunakan, backend autentikasi menunjukkan perbedaan waktu yang dapat diukur oleh penyerang.

### Root cause

Sistem autentikasi Django menetapkan "password yang tidak dapat digunakan" untuk pengguna yang seharusnya tidak dapat masuk melalui autentikasi password. Metode `authenticate()` memproses pengguna ini secara berbeda, sehingga menciptakan variasi waktu yang terukur.

### Mekanisme Serangan

```python
# Simplified representation of the vulnerability
def authenticate(self, request, username=None, password=None):
    try:
        user = User.objects.get(username=username)
        if user.has_usable_password():
            # Path 1: Check password (takes longer)
            if user.check_password(password):
                return user
        else:
            # Path 2: Quick return for unusable password (takes less time)
            return None
    except User.DoesNotExist:
        # Path 3: User doesn't exist (intermediate time)
        return None
```

### Analisis Waktu

Penyerang dapat mengukur waktu respons untuk menentukan:
1. **Pengguna ada dengan password yang dapat digunakan**: Waktu respons lebih lama
2. **Ada pengguna dengan password yang tidak dapat digunakan**: Waktu respons lebih singkat
3. **Pengguna tidak ada**: Waktu respons menengah

## Eksploitasi

### Skenario Serangan

1. Penyerang mengirimkan beberapa permintaan login dengan nama pengguna berbeda
2. Mengukur waktu respons untuk setiap permintaan
3. Mengidentifikasi nama pengguna yang valid berdasarkan pola waktu
4. Menggunakan nama pengguna yang disebutkan untuk serangan yang ditargetkan

### Alat dan Teknik

```python
# Example timing measurement (simplified)
import requests
import time

def measure_login_time(username):
    start = time.time()
    response = requests.post('/login/', data={
        'username': username,
        'password': 'wrong_password'
    })
    end = time.time()
    return end - start

# Analyze timing differences
usernames = ['admin', 'user1', 'nonexistent', 'test']
for username in usernames:
    timing = measure_login_time(username)
    print(f"{username}: {timing:.4f}s")
```

## Dampak

### Tingkat Keparahan: Sedang

- **Kerahasiaan**: Sedang - Enumeration nama pengguna
- **Integritas**: Tidak ada
- **Ketersediaan**: Tidak ada

### Dampak Bisnis

- Memungkinkan serangan brute force yang ditargetkan
- Memfasilitasi isian kredensial
- Membantu upaya teknologi sosial
- Melanggar ekspektasi privasi

## Mitigasi

### Langkah cepat

1. **Perbarui Django** ke versi yang ditambal:
   - Django 5.0.7 atau lebih baru
   - Django 4.2.14 atau lebih baru

2. **Pembatasan tingkat penerapan**:
   ```python
   # Using django-ratelimit
   from ratelimit.decorators import ratelimit
   
   @ratelimit(key='ip', rate='5/m', method=['POST'])
   def login_view(request):
       # Login logic
   ```

### Pertahanan Secara Mendalam

```python
# Custom authentication backend with constant-time comparison
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
import hmac

class SecureModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None:
            username = kwargs.get(User.USERNAME_FIELD)
        
        # Always perform password hash even for non-existent users
        try:
            user = User.objects.get(**{User.USERNAME_FIELD: username})
        except User.DoesNotExist:
            # Run hasher to prevent timing-based user enumeration
            User().set_password(password)
            return None
        
        if user.check_password(password) and self.user_can_authenticate(user):
            return user
        return None
```

### Perlindungan Tambahan

```python
# settings.py - Security configurations

# Account lockout after failed attempts
ACCOUNT_LOCKOUT_ATTEMPTS = 5
ACCOUNT_LOCKOUT_TIMEOUT = 1800  # 30 minutes

# Session security
SESSION_COOKIE_AGE = 3600  # 1 hour
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True

# CSRF protection
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
```

## Monitoring dan Deteksi

### Indikator Kompromi

1. **Pola login yang tidak biasa**: Beberapa kali gagal pada nama pengguna yang berbeda
2. **Permintaan analisis waktu**: Interval permintaan yang konsisten
3. **Upaya terdistribusi**: Upaya login dari beberapa IP

### Pengaturan Monitoring

```python
# Log authentication attempts
import logging

logger = logging.getLogger('django.security')

def log_login_attempt(request, username, success):
    logger.info(f"Login attempt: username={username}, success={success}, "
                f"ip={request.META.get('REMOTE_ADDR')}, "
                f"user_agentt={request.META.get('HTTP_USER_AGENT')}")
```

## Praktik Terbaik untuk Keamanan Autentikasi

### Kebijakan Kata Sandi

1. **Hashing kuat**: Gunakan bcrypt, Argon2, atau PBKDF2
2. **Keunikan garam**: Pastikan garam unik per password
3. **Penyetelan faktor kerja**: Menyesuaikan berdasarkan kemampuan server

### Manajemen Sesi

```python
# Secure session configuration
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
```

### Autentikasi Multi-Faktor

```python
# Consider adding MFA
# Using django-otp or similar packages
INSTALLED_APPS = [
    'django_otp',
    'django_otp.plugins.otp_totp',
    # ...
]

MIDDLEWARE = [
    'django_otp.middleware.OTPMiddleware',
    # ...
]
```

## Penutup

CVE-2024-39329 menunjukkan bahwa perbedaan waktu yang tidak kentara sekalipun dalam sistem autentikasi dapat dieksploitasi. Dengan memperbarui Django dan menerapkan langkah-langkah keamanan tambahan, developer dapat melindungi aplikasi mereka dari serangan enumerasi pengguna.

## Referensi

- [NVD - CVE-2024-39329](https://nvd.nist.gov/vuln/detail/CVE-2024-39329)
- [Rilis Keamanan Django](https://docs.djangoproject.com/en/dev/releases/security/)
- [OWASP - Enumeration Nama Pengguna](https://owasp.org/www-community/attacks/Username_enumeration)

---

*Markdown version of https://www.ciptadusa.com/blog/django-user-enumeration-timing-attack-cve-2024-39329 — generated for AI agents and LLM crawlers.*
