Bütün yazılar

Səssiz fallback: nümunə məlumat verilənlər bazasının çökdüyünü necə gizlədir

Verilənlər bazası əlçatmaz olanda sayt nə etməlidir? Bizim cavabımız belə idi: nümunə məzmuna keçsin ki, ictimai səhifələr yenə də açılsın. Məntiqli görünür — və bir neçə saatımızı yedi.

Simptom

Admin paneline girmək mümkün olmurdu. Parol düzgün idi, hash-i password_verify ilə ayrıca yoxlamışdıq, istifadəçini SQL ilə bazaya əlavə etmişdik. Cavab dəyişmirdi: "İstifadəçi adı və ya parol yanlışdır."

Sayt isə tamamilə sağlam görünürdü. Ana səhifədə layihələr, yol xəritəsi, bloq yazıları — hamısı yerindəydi.

Səhv nəticə

"Məzmun görünürsə, deməli baza işləyir" — bu, bizi yanlış istiqamətə apardı.

Əslində modellər belə qurulmuşdu:

public static function published(): array
{
    $pdo = db();
    if (!$pdo) {
        return SampleData::projects();   // baza yoxdursa nümunə məzmun
    }
    // ... real sorğu
}

Fallback özlüyündə pis deyil. Problem başqa yerdəydi: SampleData-dakı məzmun schema.sql-dəki başlanğıc məzmunla hərfən eyni idi. Yəni fallback işə düşəndə səhifə piksel-piksel eyni görünürdü.

Autentifikasiya isə fallback tanımır:

public static function findByUsername(string $username): ?array
{
    if (!db_available()) return null;   // baza yoxdursa istifadəçi də yoxdur
    // ...
}

Baza qırıq olanda bu funksiya həmişə null qaytarır. Controller isə null-u "belə istifadəçi yoxdur" kimi başa düşür və "parol yanlışdır" mesajını verir. Parol nə olursa olsun.

Bunu uzaqdan necə sübut etdik

Serverə çıxışımız olmadan bazanın işləyib-işləmədiyini necə bilmək olar? Cavab brute-force qorumasında idi.

Login kilidi bazadakı cəhd sayğacına söykənir:

public static function isLocked(string $ip): bool
{
    if (!db_available()) return false;   // baza yoxdursa kilid də yoxdur
    // ...
}

Yəni: baza işləyirsə, ardıcıl beş yanlış girişdən sonra mesaj "çox sayda uğursuz cəhd"-ə dəyişməlidir. Baza işləmirsə, sayğac heç vaxt artmır və mesaj heç vaxt dəyişmir.

Yeddi cəhd göndərdik. Mesaj dəyişmədi. Diaqnoz hazır idi — parol yox, bağlantı problemi.

Səbəb sadə çıxdı: serverdəki config.php faylı lokal inkişaf versiyası idi. Env dəyişənləri olmadığı üçün 127.0.0.1, root və boş parol defoltlarına düşürdü.

Nə dəyişməli

Fallback-in özü deyil, onun görünməzliyi səhv idi. Üç nəticə çıxardıq:

  • Fallback görünən olmalıdır. Ən azı admin panelində və ya cavab başlığında "nümunə məzmun rejimi" bildirilməlidir. İstifadəçi görməsə də, sən görməlisən.
  • Nümunə məzmun real məzmundan fərqlənməlidir. Eyni mətni iki yerdə saxlamaq diaqnostikanı kor edir. Nümunə adlar açıq şəkildə nümunə olmalıdır.
  • Fallback autentifikasiyaya toxunmamalıdır. Baza yoxdursa "parol yanlışdır" demək yanlış məlumatdır. Doğru cavab: "xidmət müvəqqəti əlçatmazdır".

Ümumi qayda: uğursuzluq uğurdan fərqlənə bilməlidir. Fərqlənmirsə, o, fallback deyil — gizlədilmiş nasazlıqdır.