Password Strength Policy Bypass via Server-Side Validation Flaw

medium.com · rozzen · 7 days ago · research
quality 7/10 · good
0 net
Tags
Password Strength Policy Bypass via Server-Side Validation Flaw | by rozzen - Freedium Milestone: 20GB Reached We’ve reached 20GB of stored data — thank you for helping us grow! Patreon Ko-fi Liberapay Close < Go to the original Password Strength Policy Bypass via Server-Side Validation Flaw Ringkasan Eksekutif rozzen Follow ~3 min read · April 3, 2026 (Updated: April 3, 2026) · Free: Yes Ringkasan Eksekutif Kerentanan ini terjadi ketika aplikasi hanya menerapkan kebijakan kekuatan password (password strength policy) di sisi klien (browser) tanpa validasi yang memadai di sisi server. Akibatnya, penyerang dapat dengan mudah mem-bypass aturan password dengan mengintercept dan memodifikasi request HTTP sebelum dikirim ke server . "Sebelum melangkah lebih jauh, saya perlu sampaikan bahwa tulisan ini adalah bentuk catatan belajar saya dari membaca berbagai laporan kerentanan publik (write-up bug bounty) dari para peneliti keamanan. Saya bukan penemu asli dari kerentanan berikut, dan tidak ada maksud mengklaim temuan orang lain. ( Tucows (VDP) | Report #3523703 — Password Strength Policy Bypass via Server-Side Validation Flaw | HackerOne ) " Analisis Teknis Root Cause Validasi password hanya dilakukan menggunakan JavaScript di sisi klien. Server tidak melakukan validasi ulang terhadap password yang dikirimkan. Ini merupakan Client-Side Enforcement of Server-Side Security (CWE-602) . Ilustrasi Kode yang Rentan Berikut contoh kode rentan (berdasarkan temuan serupa): // UserController.php - KODE RENTAN public function update(Request $request, User $user) { $user->password = bcrypt($request->password); $user->save(); } Pada kode di atas, server langsung menerima password dari request dan meng-hash-nya tanpa validasi apakah password tersebut memenuhi kebijakan kekuatan password . Kode yang Aman (Remediasi) // UserController.php - KODE AMAN public function update(Request $request, User $user) { $password = $request->password; // Validasi password di sisi server if (!$this->isPasswordValid($password)) { return response()->json([ 'message' => 'Password does not meet the policy requirements' ], 400); } $user->password = bcrypt($password); $user->save(); } private function isPasswordValid($password) { // Contoh validasi: minimal 8 karakter, kombinasi huruf, angka, special char if (strlen($password) < 8) return false; if (!preg_match('/[A-Z]/', $password)) return false; if (!preg_match('/[a-z]/', $password)) return false; if (!preg_match('/[0-9]/', $password)) return false; if (!preg_match('/[^A-Za-z0-9]/', $password)) return false; return true; } Proof of Concept (PoC) — Langkah Reproduksi Langkah 1: Identifikasi Endpoint Buka aplikasi dan akses halaman registrasi/ganti password Buka Developer Tools (F12) → Tab Network Perhatikan request yang dikirim saat submit form Langkah 2: Bypass dengan Intercept Tool Gunakan Burp Suite, OWASP ZAP, atau tool serupa: Setup Proxy: Konfigurasi browser untuk menggunakan proxy (default: 127.0.0.1:8080) Pastikan Burp Suite/ZAP dalam状态 intercept ON 2. Coba Password Lemah: Di form, masukkan password lemah (contoh: "123" atau "a") Biasanya frontend akan langsung menolak dengan pesan error 3. Bypass Client-Side Validation: Opsi A: Nonaktifkan JavaScript di browser Opsi B: Masukkan password kuat (contoh: "P@ssw0rd123!") untuk melewati validasi frontend, lalu intercept request sebelum dikirim 4. Modifikasi Request: Original Request (setelah submit): POST /api/change-password HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded password=P%40ssw0rd123%21&confirm_password=P%40ssw0rd123%21 Ubah menjadi: POST /api/change-password HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded password=123&confirm_password=123 5. Forward Request: Kirim request yang telah dimodifikasi ke server Langkah 3: Verifikasi Jika server menerima password lemah "123", maka kerentanan terkonfirmasi Jika server menolak dengan pesan error, maka server memiliki validasi yang baik 1. Cloudflare Public Bug Bounty (2022) Peneliti menemukan bahwa validasi password policy di Cloudflare hanya dilakukan di frontend. Dengan mengintercept request, penyerang dapat mengubah password menjadi lebih lemah dari yang seharusnya diizinkan . 2. WordPress Plugin — Profile Builder Pengguna melaporkan bahwa plugin Profile Builder versi 2.9.3 memungkinkan bypass password strength dengan cara: Memasukkan password kuat di form (melewati validasi client) Mengintercept request dengan Fiddler/Burp Suite Mengganti nilai password menjadi lemah Server tetap menerima karena tidak ada validasi ulang 3. Fluid Attacks — PHP Application Aplikasi PHP ditemukan memiliki kerentanan serupa di mana fungsi update langsung menyimpan password tanpa validasi server-side Dampak (Impact) Pengguna dapet menggunakan password lemah (e.g., "12345", "password") Peningkatan risiko brute force attack Kompromi akun pengguna (credential stuffing) Pelangaran kepatuhan (GDPR, PCI-DSS, HIPAA) jika mengatur password policy wajib emediasi Rekomendasi Perbaikan untuk Developer Implementasikan Validasi Server-Side: Semua validasi password policy WAJIB diulang di sisi server Jangan pernah hanya mengandalkan validasi client-side 2. Gunakan Library Validasi yang Teruji: PHP: zxcvbn-php (untuk estimasi kekuatan password) Python: zxcvbn-python atau django-password-validators Node.js: zxcvbn atau owasp-password-strength-test Java: passay library 3. Contoh Implementasi di Berbagai Framework: Laravel (PHP): use Illuminate\Validation\Rules\Password; $request->validate([ 'password' => [ 'required', 'confirmed', Password::min(8) ->mixedCase() ->numbers() ->symbols() ], ]); Django (Python): # settings.py AUTH_PASSWORD_VALIDATORS = [ {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': {'min_length': 8}}, {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, ] Spring Boot (java): @Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$", message = "Password must contain at least 8 chars, 1 digit, 1 uppercase, 1 lowercase, 1 special char") private String password; Tambahkan Logging untuk Deteksi Bypass: Catat setiap percobaan yang mencurigakan (client-side validation passed tetapi server-side validation failed) 2. Gunakan CSRF Token: Pastikan setiap request perubahan password dilindungi CSRF token #bug-bounty #cybersecurity Reporting a Problem Sometimes we have problems displaying some Medium posts. If you have a problem that some images aren't loading - try using VPN. Probably you have problem with access to Medium CDN (or fucking Cloudflare's bot detection algorithms are blocking you).