Öğretmek için yazılmış
bir PHP yönetim paneli
Çalışan kod ile doğru kod arasındaki farkı göstermeyi amaçlar. Katmanlı mimari, rol tabanlı yetkilendirme ve baştan sona güvenlik; Composer, framework ve CDN olmadan. Her satırın neden öyle yazıldığı kaynak dosyalarda açıklanmıştır.
- PHP (nesne yönelimli, katmanlı)
- MySQL / MariaDB
- PDO + hazırlanmış ifadeler
- AJAX tabanlı CRUD
- Sunucu taraflı veri tablosu
- Composer / framework yok
Üç rol, net sınırlar
Yetkiler tek bir tabloda tanımlıdır. Kodda rol adı değil yetki adı kullanılır; böylece yeni bir rol eklemek tek bir dosyaya satır eklemekten ibarettir.
Sistemin tam sorumlusu. Kullanıcı yönetiminin tamamına, rol atamaya ve sistem denetimine erişir.
İçerik/kullanıcı sorumlusu. Kullanıcı ekler ve düzenler; ancak kayıt silemez, rol ve hesap durumu değiştiremez.
Standart kullanıcı. Panele girer, kontrol panelini ve yalnızca kendi hesabını görüntüleyip düzenler.
Bunlara ek olarak, yetki tablosuyla ifade edilemeyen koruma kuralları vardır: kimse kendi rolünü değiştiremez, kendini pasifleştiremez ve sistemdeki son aktif yönetici silinemez. Ayrıntılı karşılaştırma tablosu panel içindeki Roller ve Yetkiler sayfasındadır.
Neler var, neden var?
Her madde bir soruna karşılık gelir. Tekniğin adını bilmek kadar hangi saldırıyı veya hatayı engellediğini bilmek de önemlidir.
Güvenlik
7- SQL Injection koruması
- Her sorgu hazırlanmış ifade (prepared statement) kullanır; kullanıcı verisi hiçbir zaman SQL metnine yapıştırılmaz. Sıralama sütunu gibi bağlanamayan parçalar beyaz listeden geçer.
- XSS koruması
- Ekrana basılan her dinamik değer kaçışlanır; JavaScript tarafında metin, HTML olarak değil düz metin olarak yazılır. İkinci hat olarak Content-Security-Policy satır içi script çalıştırmayı engeller.
- CSRF koruması
- Veri değiştiren her istek oturuma özel, tahmin edilemez bir anahtar taşır. Karşılaştırma sabit sürelidir; anahtar zamanlama ölçülerek tahmin edilemez.
- Kaba kuvvet koruması
- Hatalı girişler e-posta ve IP birlikte sayılır, sınır aşılınca geçici kilit uygulanır. Sayaç oturumda değil veritabanında tutulur; çerez silerek sıfırlanamaz.
- Kullanıcı sayımına karşı önlem
- Hatalı e-posta ile hatalı parola aynı mesajı ve aynı süreyi üretir. Kayıtlı olmayan adres için de gerçek bir parola doğrulaması çalıştırılır; yanıt süresinden hesap varlığı anlaşılamaz.
- Güvenli parola saklama
- Parolalar bcrypt ile geri çevrilemez biçimde özetlenir. Algoritma güçlendiğinde özet, kullanıcı giriş yaparken sessizce yenilenir.
- Güvenli dosya yükleme
- Dosyanın görsel olduğu içeriğinden doğrulanır, adını ve uzantısını sunucu belirler, görsel yeniden üretilerek gömülü veri atılır ve yükleme klasöründe PHP çalıştırma kapatılır.
Oturum ve erişim
6- Rol tabanlı yetkilendirme
- Kodda rol adı değil yetki adı kullanılır. Kurallar tek bir tabloda toplandığı için "kim neyi yapabilir" sorusunun tek bir cevabı vardır.
- Ara katmanlarla koruma
- Yetki kontrolü rota tanımında yapılır; denetleyicinin içine tek tek yazılmadığı için bir sayfada unutulması zorlaşır.
- Sertleştirilmiş oturum
- Çerez JavaScript tarafından okunamaz, oturum kimliği giriş anında ve periyodik olarak yenilenir, uzun süre işlem yapılmayan oturum düşürülür.
- "Beni hatırla" (güvenli)
- İki parçalı anahtar kullanılır; sır veritabanında düz değil özetlenmiş durur. Anahtar tek kullanımlıktır, her otomatik girişte yenilenir ve parola değişince tüm cihazlarda iptal edilir.
- Taze yetki kontrolü
- Rol ve hesap durumu oturumda saklanmaz, her istekte veritabanından okunur. Böylece bir hesap kapatıldığında veya rolü düşürüldüğünde etki anında geçerli olur.
- İşlem günlüğü
- Giriş, çıkış, kayıt ekleme/güncelleme/silme ve parola değişikliği kim, ne zaman, hangi IP bilgisiyle kaydedilir.
Veri ve doğrulama
5- Sunucu taraflı doğrulama
- Ad, e-posta, telefon, parola ve metin uzunlukları sunucuda denetlenir. Tarayıcıdaki kontroller yalnızca kolaylıktır; son söz her zaman sunucunundur.
- Toplu atama koruması
- Güncellemede yalnızca izin verilen sütunlar yazılır. Forma gizli bir "role" alanı eklemek işe yaramaz.
- IDOR koruması
- Kendi profilini güncellerken hedef kayıt kimliği formdan değil oturumdan alınır; başkasının kaydı hedeflenemez.
- Sunucu taraflı tablo
- Arama, sıralama ve sayfalama veritabanında yapılır. Kayıt sayısı büyüdüğünde tarayıcıya tüm veri gönderilmez.
- Veritabanı düzeyinde tutarlılık
- Benzersiz e-posta kısıtı, rol için ENUM ve yabancı anahtarlar; uygulama hata yapsa bile veritabanı son savunma hattı olarak durur.
Mimari
6- Katmanlı yapı
- Core / Models / Repositories / Controllers / Views ayrımı. Denetleyicide SQL, depoda HTML bulunmaz; her katmanın tek bir sorumluluğu vardır.
- Tek giriş noktası
- Tüm istekler tek bir dosyadan geçer. Oturum, güvenlik başlıkları ve hata yakalama tek yerde kurulur; bir sayfada atlanamaz.
- Sıfır bağımlılık
- Composer, framework veya CDN gerekmez. Kendi otomatik yükleyicisiyle çalışır; indirip veritabanını içe aktarmak yeterlidir.
- Temiz adresler
- Adresler koddan bağımsızdır. Sunucuda yeniden yazma kapalıysa uygulama tek ayarla klasik biçime döner, hiçbir kod değişmez.
- Kişiye bağlı arayüz tercihi
- Açık/koyu tema seçimi hesapta saklanır; kullanıcı başka bir cihazdan girdiğinde de kendi düzenini bulur.
- Mobil uyumlu tasarım
- Menü dar ekranda çekmeceye dönüşür, dokunma hedefleri büyütülür, tabloda ikincil sütunlar gizlenirken bilgi kaybolmaz.
Demo hesaplarla hemen deneyin
Giriş ekranındaki demo kartlarına tıklayarak formu tek hamlede doldurabilirsiniz. Üç farklı rolle giriş yapıp yetkilerin arayüzü nasıl değiştirdiğini görebilirsiniz — yetkisi olmayan düğmeler gizlenmekle kalmaz, sunucu tarafında da reddedilir.
Panele Giriş