Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Yazı Tipi BoyutlandırıcıAa
  • Anasayfa
  • Teknoloji
    • Siber Güvenlik
    • Yapay Zeka
    • Donanım
    • Bilim
  • Yazılım
  • Savunma & İstihbarat
  • Oyun
  • Yaşam
    • Finans
    • Sinema
    • Dünyadan Haberler
  • İş Birliği
Okuma: Spatie’ye başvurmak yerine kendi RBAC’ımı yazdım ve inceleme bir yetki yükseltme açığını tespit etti.
Paylaş
Yazı Tipi BoyutlandırıcıAa
Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Ara
Bizi Takip Et
  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti
© 2026 Teknomers. All Rights Reserved.

Anasayfa » Spatie’ye başvurmak yerine kendi RBAC’ımı yazdım ve inceleme bir yetki yükseltme açığını tespit etti.

Yazılım

Spatie’ye başvurmak yerine kendi RBAC’ımı yazdım ve inceleme bir yetki yükseltme açığını tespit etti.

teknomers
Son güncelleme: 4 Haziran 2026 03:06
teknomers
Paylaş
Paylaş

Bu yazı, gerçek bir üretim Laravel CRM’sini modüler bir SaaS çekirdeğine dönüştürdüğüm bir serinin parçasıdır. İlk bölümlerde temel katman, Fortify ile kimlik doğrulama ve çoklu kiracılık konularını ele almıştım. Şimdi, v0.4.0: roller ve izinler konusuna giriş yapacağım.


Spatie Kullanmadım

spatie/laravel-permission mükemmel bir pakettir. Kendi projelerimde kullandım. Yeni bir uygulama başlatıyorsanız, bunu tercih edebilirsiniz.

Ancak benim durumumda bir sebep var: CRM’imdeki RBAC (Role-Based Access Control) başlangıçta kiracı kapsamlıydı ve bu bir düşünce sonrası değil, başından beri böyle tasarlanmıştı. Her rol ataması ve her bireysel izin tahsisi ait olduğu şirketle bağlantılıdır. Aynı kullanıcı, şirket A’da admin, şirket B’de ise yalnızca okuma izni olan bir üye olabilir; A’da verilecek bir izin asla B’ye sızmamalıdır. Çoklu kiracılık katmanım, (önceki sürüm) company_id‘yı kiracı anahtarı olarak kullandı ve erişim katmanı da bu şekilde baştan tasarlandı.

Özelleştirilmiş bir paketi sarmak için ek çalışma yapmaktansa, daha önce bunu gerçekleştiren kodu alıp modernize etmeyi tercih ettim. (Evet, bunu her yazımda “kendim yazdım, Spatie değil” şeklinde belirtiyorum; çünkü kamuya açık bir şekilde inşa etmenin amacı bu dürüstlükte yatıyor.)


Yapının Şekli

Beş tablo, sıradan:

  • permissions – izinlerin katalogu. module.action biçiminde global olarak benzersiz etiketler içerir, örneğin: company.roles.update. Konfigürasyondan tohumlanır, çalışma zamanında asla yaratılmaz.
  • roles – izinlerin adlandırılmış grupları. company_id (nullable) bir rolü bir kiracıya tahsis eder. Bayraklar, bir rolün global mi, şablon mu yoksa özel bir rol mu olduğunu belirtir.
  • role_permissions – bir rolün hangi izinleri verdiği.
  • user_roles – bir kullanıcının rollerini tutar; her satır bir company_id (kiracı) taşır.
  • user_permissions – bireysel izinlerin verilmesi ve geri alınması, yine kiracı kapsamlıdır ve is_revoked bayrağını taşır.

İlginç olan, tablolar değil, kontrol mekanizmasıdır. Bir izin sorgusu öncelik sırasına göre bir cümle gibi çalışır:

public function hasPermissionTo(Permission|string $permission, Company|int|null $company = null): bool
{
    if ($this->isSuperAdmin()) {
        return true;
    }

    if ($company !== null && $this->userOwns($company)) {
        return true;
    }

    $slug = $permission instanceof Permission ? $permission->slug : $permission;

    return $this->getAllPermissions($company)->contains($slug);
}

Öncelik sırası: öncelikle süper admin. Ardından şirket sahibi (kendi şirkete ait her şey). Ardından geri kalan herkes için ise çözülmüş izin seti:

(şirket rollerinden izinler) artı (global rollerden izinler) artı
(bireysel izinler) eksi (bireysel geri almalar).

(user, permission, company) satırı benzersizdir; bir izin ya verilir ya da geri alınır, ikisi birden asla olmaz. Bu nedenle, izin değerlendirmesi, eski “geri alma, verme, rol” sırasını tam olarak yeniden üretir; tüm set yalnızca bir istek başına çözülür, böylece her kontrol için ayrı bir sorgu yapılması gerekmez.

İki atlama noktası var ve yalnızca ikisi. Sahip atlaması, kiracılık katmanında zaten bulunan is_owner bayrağını yeniden kullanır. Bu sayede RBAC, çoklu kiracılığın üzerinde durur ve mülkiyet kavramını tekrar etmez. Süper admin ise, kimlik doğrulama katmanında çözülen bir kimlik bayrağıdır, bu nedenle yanlışlıkla rol yönetim ekranından verilmez.


Nihayet Çalışan Kanca

Çoklu kiracılığı teslim ettiğimde, şirket oluşturma işlemi bir CompanyCreated olayı yayınladı, ancak henüz bir şey yapmadı. Önceki sürümde RBAC’ın bunu ileride dinleyeceğini belirtmiştim.

Şimdi dinliyor. Bir kuyruk dinleyicisi, her yeni şirket oluşturulduğunda bir şablon rol setini kopyalar, böylece yeni bir kiracı makul rollerle başlar, boş bir erişim tablosuyla değil. Bu idempotenttir (bir deneme, tekrar rol oluşturmaz) ve kasıtlı olarak kuyruğa alınmıştır: sahip, zaten sahip atlamasıyla tam erişime sahiptir, bu nedenle kopyalamada beklemeleri gerekmez. Kopyalanan roller yalnızca daha sonra davet edecekleri çalışanlar için önemlidir, bu noktada görev çalıştırılmıştır.


Sonrasında İnceleme Açığı Buldu

Bu serideki her modül, birleştirilmeden önce bir kod incelemesine tabidir ve şimdiye kadar her modülde inceleme gerçek bir sorunu yakalamıştır. Bu modülde bir yetki yükseltme açığı bulundu ve bu oldukça önemliydi çünkü kod doğru görünüyordu.

Sahiplerin çalışan yönetimini devredebilmesini istedim. “Ofis yöneticim insanları davet etsin ve rollerini atasın” gibi bir şey SaaS için mantıklı bir desteklemektir.
Bu nedenle, bir izin mevcut: company.employees.grant_permissions ve bu izni vermek için kontrol edilen son nokta:

public function updatePermissions(Request $request, int $user): RedirectResponse
{
    $this->authorize('company.employees.grant_permissions');
    // ... istenen izin etiketlerini katalog ile doğrula ...
    // ... bunları hedef üyeye ver ...
}

Farkettiniz mi? Geçiş noktası “izin vermeye yetkili misin?” sorusunu kontrol ediyor. Ancak “verdiğin izinleri gerçekten tutuyor musun?” sorusunu kontrol etmiyor. İstenen etiketler yalnızca katalog ile doğrulandı; bu katalog sistemdeki her izni içeriyor, rollerin yönetim izni de dahil.

Bu nedenle, grant_permissions iznine sahip bir delege edilen üye, kendine veya başka birine, herhangi bir izni verebilir hale geliyordu. Bu, company.roles.delete, company.employees.remove veya izin verme izni gibi izinleri içerebilir. Güvendiğiniz ofis yöneticisi, kendini tamamen rol yöneticisi olarak atama imkânına sahipti. Halka açık kaynaklarda bir “kafa karıştırıcı delege” durumuydu: delege eylemde bulunma izni alabiliyordu, ancak neyle eylemde bulunabileceği sınırlandırılmamıştı.

Düzeltme, tek bir kuraldır: sadece sahip olduğunuz izni verebilirsiniz.

$held = $request->user()->getAllPermissions($company);

foreach ($validated['grant'] ?? [] as $slug) {
    abort_unless($held->contains($slug), 403);
}

Aktörün kendi etkili izin seti, her izin vermeyi sınırlar. Sahipler ve süper yöneticiler tüm katalogu elinde tutuyor (atlama her şeyi getirir), bu yüzden onlar için hiçbir şey değişmez. Delege edilen bir üye yalnızca kendi erişimi kadar yetki verir ve asla bunun dışına çıkamaz. Aynı kural, rollerin atanması için de geçerlidir: yalnızca sahip olduğunuz izinlerin alt kümesini içeren bir rol atayabilirsiniz, dolayısıyla güçlü bir rolü, izinlerini doğrudan veremediğiniz birine veremezsiniz. Eğer bu iki durum ihlal edilirse, bu durumda ikisi de açık bir dizi ile başarısız olur.


Akışta Gizli İkinci Bir Hata

İnceleme, tek bir fonksiyonun ortaya koyamayacağı daha sessiz bir hatayı da buldu, çünkü bu, akış boyunca durumun nasıl hareket ettiğine dair bir sorudur.

Bir üyeyi bir şirkette çıkarmak, yumuşak bir silme işlemidir: üyelik satırı denetim için tutulur, ancak kaldırma durumu bayrağıyla işaretlenir. Ancak bir üyenin kaldırılması, onların rol atamalarında hiçbir değişikliğe neden olmadı. Bu user_roles satırları olduğu gibi yerinde kaldı. iki sonuç: yalnızca kaldırılan üyelerin sahip olduğu özel bir rol sıfır sahip konumuna ulaşamayacağı için, UI üzerinden kalıcı olarak silinemez hale geldi; ayrıca kaldırılan üyenin izinleri, gelecekteki bir kod akışında çözülme olasılığı ile tablonun içinde kaldı.

Düzeltme, doğru yükseklikte yer almaktadır. Kiracılık katmanı zaten bir
EmployeeRemoved olayı yayınlıyor. RBAC bunu dinliyor:

class RevokeAccessOnEmployeeRemoval 
{
    public function handle(EmployeeRemoved $event): void
    {
        $employee = $event->employee;
        $companyId = $event->company->getKey();

        $employee->roles()->wherePivot('company_id', $companyId)->detach();
        $employee->permissions()->wherePivot('company_id', $companyId)->detach();
    }
}

Bir şirketten ayrıldığınızda, o şirketteki erişiminiz kaldırılır. Global roller (her kullanıcının sahip olduğu temel “kimlik doğrulanmış” rol gibi) korunur; çünkü bir şirketten ayrılmak, her yerde kimliğinizin değişmesini sağlamamalıdır.


Ne Olmayı İstemiyor

Her sürümümde eklediğim dürüstlük notu. v0.4.0, RBAC motorunu ve tam olarak bir nötr başlangıç rolü sunar. İzinler, envanter, faturalama işlemleri gibi iş izinleri içermez. Bunlar, yukarıda inşa ettiğiniz uygulamanıza aittir; temel yapı sadece mekanizmayı ve genişletme yapacağınız bir konfigürasyon katalogunu sunar.

Faturalama ile ilgili erişim kontrolü hala bir arayüzün arkasında, stuba aittir (henüz dönüyor, “izne izin ver” diyor) ve API/token çözümleyici daha sonraki bir aşamada geliyor. Küçük bir dürüst motor göndermeyi, büyük bir yanıltıcı motor göndermekten daha çok isterim.


Testler ve Kapanış

Paketimiz yeşil: RBAC takımı kontrol önceliğini, kiracı izolasyonunu, oluşturma işlemi sırasında kopyalamayı, yukarıda belirtilen iki güvenlik düzeltmesini ve Vue izin seçici de dahil olmak üzere host entegrasyon testlerini kapsar. Tüm bunlar gerçek uygulamayla ve gerçek middleware yığınıyla entegre edilmiştir.

Bu seride sürekli tekrar eden bir şablon: çıkartma işleminin kendisi genelde hataların bulunduğu yer değildir. Hatlar daha çok bir ikinci geçişte, durumun bir bütün akış boyunca nasıl hareket ettiğini ya da “bu kapı eylemde bulunmanı sağlıyor, ama hangi izinlerle eylemde bulunabiliyorsun?” sorusunu sorduğunda ortaya çıkar. İşte burada yavaşlamak önemlidir.

Sonraki aşama, aktivite günlüğü olacaktır.

Paket, herkese açık olarak GitHub’da mevcuttur: https://github.com/dmitryisaenko/larafoundry

Kaynak: Orijinal Makale

Contents
  • Spatie Kullanmadım
  • Yapının Şekli
  • Nihayet Çalışan Kanca
  • Sonrasında İnceleme Açığı Buldu
  • Akışta Gizli İkinci Bir Hata
  • Ne Olmayı İstemiyor
  • Testler ve Kapanış
macOS’ta Docker Kullanmadan Tam Bir Yerel PHP Geliştirme Ortamı Nasıl Kurulur
Laravel Fast2SMS v2.0.0 — WhatsApp Desteği, Bildirim Kanalları ve Daha Akıllı Kullanıcı Deneyimi
Laravel Komutları: Basit ve Etkileşimli CLI
Mühendislik Pratikliği: Modern Muhasebe SaaS’ının Bir Araç Gibi Hissettirmesi Gereken Nedenler
Laravel Kuyruk Mimarisi: Üretimde Arka Plan İşlemleri için Cron Görevlerini Kullanmayı Neden Bıraktım
Bu Makaleyi Paylaş
Facebook Bağlantıyı Kopyala Yazdır
Paylaş
Önceki Makale Kritik: Otonom AI Aracı Redis’te 2 Yıllık RCE Açığını Buldu
Sonraki Makale Phantom Blade Zero’nun İyi Versiyonuyla Çıkış Tarihi Güncellendi

Sanal Medya

FacebookBeğen
452Takip Et
PinterestSabitle
237Takip Et

Son Eklenenler

Kritik: NSO Group’un Yeni WhatsApp Phishing Saldırısı ve Yasal Süreçler
Siber Güvenlik
Apple ebeveynlere çocukların iPhone kullanımlarında yeniden kontrol sağlıyor
Genel
Apple Ekran Süresini Yeniden Tasarlıyor ve Çocuk Kontrollerini Gözden Geçiriyor
Liste
Kritik UniFi OS açığı: Hırsızlar kimlik doğrulamasız kök erişimi elde ediyor
Siber Güvenlik
Meta, Akıllı Gözlüklerindeki Yüz Tanıma Sistemini Kaldırdı!
Genel
WWDC 2026: Siri, iOS 27 ve Apple İnovasyonları Açıklandı
Yapay Zeka
//

Siber güvenlik, yapay zeka ve savunma sanayiinden; finans ve sinema dünyasına uzanan geniş bir yelpaze. Teknomers; teknoloji, strateji ve yazılım dünyasını sade bir dille sizlerle buluşturuyor.

Kurumsal

  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti

Kategoriler

  • Teknoloji
  • Oyun
  • Sinema
  • Siber Güvenlik
  • Bilim
  • Finans
  • Dünyadan Güncel Haberler

Populer

  • TV'de Ücretsiz İzlenebilen Şifresiz Erotik Kanallar (2025 Güncel Frekans Listesi)

  • The Last of Us PC Kontrolleri: Hızlı Silah Değiştirme ve Tüm Tuşlar (2025)

  • Hogwarts Legacy'de Odaklanma İksiri Nasıl Yapılır?

Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Bizi Takip Et
© 2026 Teknomers. All Rights Reserved.
Welcome Back!

Sign in to your account

Kullanıcı Adı veya E-posta Adresi
Şifre

Şifrenizi mi unuttunuz?