# VC-104 · Yetki testleri yalnız izinli kullanıcıyı deniyor, reddedilmesi gereken yollar eksik

Kayıt sahibi işlemi yapabiliyor ve test bu sonucu doğruluyor. Başka kullanıcı, başka ekip veya oturumsuz istek hiç denenmediği için eksik yetki kontrolü aynı testten geçebiliyor.

- Önem: YÜKSEK. Etkisi orta. Her gün, sıradan kullanımda tetiklenir.
- Önem notu: Her kabulde yalnız izinli yolun sınanması temel alınır. Risk, uygulamanın sahiplik ve rol sınırlarına bağlıdır. Eksik test mevcut yetki açığını tek başına kanıtlamaz, bu açığı yakalama güvencesini azaltır.
- Eksen ve kategori: Sağlamlık, 16 Sözleşmeler ve testler
- Yığın: Her yığın
- Yapay zekâ kodunda: ölçülmedi. Dayanak: uzman görüşü.
- Ne zaman bakılır: İlk yayından önce, Her ay
- CWE: yok. Ret testinin yokluğu erişim kontrolünün gerçekten eksik olduğunu kanıtlamaz. Test açığı ile bulunmuş yetki zayıflığını ayırmak için doğrudan CWE eşlemesi yapılmaz.
- Checklist ifadesi: Yetki testleri reddedilmesi gereken kullanıcıları ve yolları da deniyor.
- Son inceleme: 4 Ekim 2026, Komünite editörlüğü
- Adres: https://vibecheck.komunite.com.tr/madde/yetki-icin-basarisizlik-testleri-yok

## 60 saniyelik kontrol

Yalnız kendi uygulamanda ya da yazılı izin aldığın sistemde dene. Bu bir sızma testi değildir.

1. İşlem için izinli ve reddedilecek kimliklerin test matrisini çıkar.
2. Başka ekipten gerçek kayıt kimliğiyle deneme bulunduğunu kontrol et.
3. Ret sonrası verinin değişmediğini ve yan etkinin oluşmadığını doğrula.
4. Yetki denetimini kaldıran varyantın mevcut testi geçirip geçirmediğine bak.

## Ne oluyor

Editör belgeyi değiştirebiliyor ve test yeni başlığı görüyor. Normal kullanımın çalıştığı kanıtlanmış oluyor. Fakat aynı test, yetki denetimi tamamen kaldırılmış bir sürümde de geçebilir. Başka ekipten kullanıcı veya oturumsuz istek hiç denenmediyse izin sınırının kapalı olduğu sonucu çıkarılamaz. İzinli yolun başarısı, yasak yolun reddedildiğini göstermez.

Yetki sözleşmesi hem kimin ne yapabildiğini hem kimin yapamaması gerektiğini içerir. Kimlik, rol, sahiplik, kiracı ve işlem türü farklı boyutlardır. Birini sınamak diğerlerini otomatik kapsamaz. Salt okuyan kullanıcı aynı ekibin belgesini görebilir ama değiştirememelidir. Başka ekibin editörü kendi ekibinde yetkili olsa da bu belgeye yazamamalıdır.

Ret yanıtı da tek başına yeterli olmayabilir. İşlev önce veriyi değiştirip sonra hata döndürüyorsa arayüz başarısızlık gösterir, veritabanı ise değişmiştir. Testin yanıtla birlikte son veri durumunu incelemesi gerekir. Dış e-posta, ücret veya dosya işlemi varsa o yan etki de değerlendirilmelidir. Bu madde mevcut bir açık varsaymadan, testin erişim sınırını gerçekten koruyup korumadığını sorgular.

## Gerçek olay

Burada yeni bir AI olayına veya ölçülmüş hata oranına yer vermiyoruz. OWASP yetkilendirme rehberi, erişim mantığı için birim ve entegrasyon testleri hazırlanmasını öneriyor. Varsayılan ret, olağandışı koşulda güvenli sonlanma ve özelliklere bağlı erişim kurallarının testte ele alınmasını açıkça anlatıyor. [Yetki testleri](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html)

NIST doğrulama rehberi de yazılımın yapmaması gereken şeyleri olumsuz test kapsamına alıyor. [Kod doğrulama](https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-supply-chain-security-guidance-3) Bu kaynaklar test eksikliğini doğrudan sömürülebilir açık ilan etmiyor. Aynı ayrımı burada koruyoruz. Uygulamada doğru bir denetim bulunabilir, fakat onu gelecekteki değişikliklere karşı sınayan test olmayabilir. CWE eşlemesi yapmak için gerçek kod zayıflığı ayrıca belirlenmelidir. Örneğimiz test gücünü, kontrollü bozuk varyantlarla karşılaştırır.

## Yapay zekâ bunu neden üretiyor

**Model kullanıcı hikâyesinin olumlu yolunu izler.** İstek bir editörün belgeyi güncellemesi olarak yazıldığında ajan testte de editörü kullanır. Belgenin değişmesi görevin başarılı bittiğini gösterir. Yasak kullanıcılar ürün hikâyesinde yer almıyorsa kabul senaryosundan düşebilir. Kimlerin hangi koşulda reddedileceğini açıkça yazmak, test tasarımının giriş verisini değiştirir. Yalnız başarılı örnek vermek izin matrisini tamamlamaz.

**Tek hesap bütün ilişkileri aynı yapar.** Geliştirme verisinde tek ekip ve tek kullanıcı varsa sahiplik ile kiracı koşulları ayırt edilemez. Ajan bunlardan birini kaldırsa test yine aynı sonucu verebilir. Farklı ekip ve roller içeren sentetik veri, denetimlerin ayrı ayrı etkisini gösterir. Çok kayıt eklemek tek başına yeterli değildir. Kayıtların izin ilişkileri farklı olmalıdır.

**Sahte yetki cevabı asıl kararı gizler.** Test `canAccess` işlevini doğrudan ret döndürecek biçimde taklit ederse yalnız ret işleme yolunu sınar. Gerçek yetki işlevinin başka kiracıyı ayırdığını kanıtlamaz. Bu test yararlı olabilir, ancak kapsamı doğru anlatılmalıdır. Kararın kendisi ve kararın uçta uygulanması için farklı kontroller gerekebilir. Bir katmanın sahte olması diğerine kanıt sağlamaz.

**Hata kodu veri durumunun önüne geçer.** Ajan ret yanıtını görünce güvenli sonucu elde ettiğini düşünebilir. Yazma çağrısının denetimden önce yapılması veya dış yan etkinin başlaması testte görünmez kalır. Reddedilen isteğin ardından veriyi yeniden okumak bu açığı yakalayabilir. Bunlar olası üretim mekanizmalarıdır. Model ailesine göre sıklık, başarı oranı veya bütün ajanlar hakkında ölçüm iddiası değildir.

## Etki

Eksik yetki testi gelecekteki bir değişikliğin sınırı kaldırmasını fark etmeyebilir. Sahip veya ekip filtresi yanlış düzenlendiğinde normal kullanıcı testi yeşil kalır. Başka kullanıcıların verisine erişim veya yazma mümkün hale gelirse bunun iş etkisi yüksek olabilir.

Ancak test boşluğu böyle bir erişimin bugün gerçekten mümkün olduğunu göstermez. İnceleme bu iki sonucu ayrı raporlamalıdır. Bir yanda kodun davranışı, diğer yanda onu sürekli doğrulayan kabul kapsamı vardır. Bu madde ikinci alana odaklanır. Bulunan gerçek yetki hatası ayrıca düzeltilmeli ve regresyon testiyle bağlanmalıdır.

## Nasıl anlarsın

İşlem için küçük bir izin matrisi çıkar. İzinli editör, salt okuyan üye, başka ekipteki editör ve oturumsuz istek nasıl sonuçlanmalı? Her birinin teste karşılığı var mı? Deneme gerçek kayıt kimliğini kullanmalı. Var olmayan kimlikten gelen hata, başka sahibin kaydının korunduğunu göstermez.

Örnekte test yordamı gerçek SQLite kullanan küçük uygulama varyantlarıyla çalışır. Yetkiyi doğru uygulayan sürüm geçer. Oturumsuza izin veren, kiracıyı atlayan, rolü yok sayan ve yazdıktan sonra ret döndüren sürümler düşer. Böylece yalnız olumlu yolu kontrol eden testin kaçırdığı farklı hatalar görünür olur. Gerçek oturum ve RLS zinciri bu yerel deneyde kurulmaz.

## Nasıl düzeltirsin

1. **İzin matrisini yaz.** Kimlik, rol, kiracı ve işlem boyutlarını ürün sözleşmesinden çıkar. Her olasılığı körlemesine çoğaltmak yerine farklı sınırları temsil et.
2. **Veriyi ayır.** Farklı ekip ve yetkiler için ayrı sentetik kayıtlar oluştur. Bütün denemeleri yönetici hesabıyla çalıştırma.
3. **Reddin sonucunu ölç.** Hata durumunu ve değişmeyen veriyi birlikte doğrula. Gerekli olduğunda dış çağrı sayısını da kontrol et.
4. **İzinli yolu koru.** Herkesi reddeden çözüm de yanlıştır. Normal kullanıcının işi tamamlayabildiğini aynı kabul kapsamına ekle.
5. **Katmanı doğru seç.** Birim testi karar mantığını, entegrasyon testi gerçek oturum veya veritabanı sınırını inceleyebilir. Yetki bağımlılığı hata verdiğinde ne olduğunu ayrıca planla.

## Bir daha olmasın

Yeni rol veya yeni kiracı ilişkisi eklendiğinde ret matrisini güncelle. Test raporunda hangi katmanın gerçek, hangisinin taklit olduğunu açıkça belirt.

## Sınır

Bütün yetki senaryoları küçük bir matrisle kapsanamaz. Nesne sahipliği, alan düzeyindeki izinler ve yönetici istisnaları ürününe göre genişletilmelidir. Örnekte ağ, gerçek kullanıcı oturumu ve bulut RLS politikası yoktur. Ret durumunda seçilen durum kodu sözleşmeye bağlıdır. Bir uygulama bilgi sızdırmamak için bulunamadı yanıtı kullanabilir, test bu kararı ve değişmeyen veriyi birlikte değerlendirmelidir.

## Düzeltme kodları

### Node.js: Ret matrisi ve veri durumu

Önce:

```js
// yetki/kabul.js, açıklama amaçlı. makeApp yeni sentetik veritabanı açar.
import assert from 'node:assert/strict';
export function verifyAuthorization(makeApp) {
  const app = makeApp();
  try {
    assert.equal(app.update('editor', 'Yeni'), 200);
    assert.equal(app.title(), 'Yeni');
  } finally { app.close(); }
}
// Yalnız izinli editör sınanır.
// Oturumsuz, başka ekipten veya salt okuyan kimlikler hiç denenmez.
// Hata yanıtından önce veri yazılması da görünmez.
// Testin yeşil olması yasak yolların kapalı olduğunu kanıtlamaz.
// Dış hizmet veya gerçek kullanıcı hesabı kullanılmaz.
// Uygulamanın oturum doğrulaması bu yordamın dışındadır.
```

Sonra:

```js
// yetki/kabul.js, açıklama amaçlı. makeApp yeni sentetik veritabanı açar.
import assert from 'node:assert/strict';
export function verifyAuthorization(makeApp) {
  const allowed = makeApp();
  try {
    assert.equal(allowed.update('editor', 'Yeni'), 200);
    assert.equal(allowed.title(), 'Yeni');
  } finally { allowed.close(); }
  for (const actor of [null, 'outsider', 'reader']) {
    const app = makeApp();
    try {
      assert.equal(app.update(actor, 'Yasak'), 403);
      assert.equal(app.title(), 'Eski');
    } finally { app.close(); }
  }
}
// Her ret yeni veritabanında sınanır, önceki deneme sonucu gizleyemez.
// Gerçek RLS, oturum ve dış yan etkiler kendi entegrasyon testini ister.
```

Düzeltmeyi kanıtlayan test:

```js
// yetki/kabul.test.mjs, açıklama amaçlı. Gerçek SQLite üstünde kusurlu varyantlar.
import test from 'node:test';
import assert from 'node:assert/strict';
import { DatabaseSync } from 'node:sqlite';
const { verifyAuthorization } = await import(process.env.ORNEK_DOSYA);
function makeApp(mode = 'correct') {
  const db = new DatabaseSync(':memory:');
  db.exec(`CREATE TABLE doc(id INTEGER, tenant TEXT, title TEXT);
    INSERT INTO doc VALUES(1,'blue','Eski')`);
  const users = { editor: ['blue', 'editor'], reader: ['blue', 'reader'], outsider: ['red', 'editor'] };
  return {
    title: () => db.prepare('SELECT title FROM doc WHERE id=1').get().title,
    close: () => db.close(),
    update: (actor, title) => {
      const user = users[actor];
      const permitted = user?.[0] === 'blue' && user?.[1] === 'editor';
      const bypass = (mode === 'anonymous' && !actor) ||
        (mode === 'tenant' && actor === 'outsider') || (mode === 'role' && actor === 'reader');
      if (!permitted && !bypass) {
        if (mode === 'write-first') db.prepare('UPDATE doc SET title=? WHERE id=1').run(title);
        return 403;
      }
      db.prepare('UPDATE doc SET title=? WHERE id=1').run(title);
      return 200;
    },
  };
}
test('izinli yol korunur, her farklı yetki ihlali denemeyi düşürür', () => {
  assert.doesNotThrow(() => verifyAuthorization(() => makeApp()));
  for (const mode of ['anonymous', 'tenant', 'role', 'write-first']) {
    assert.throws(() => verifyAuthorization(() => makeApp(mode)), { code: 'ERR_ASSERTION' });
  }
});
```

## Ajan kuralı (AGENTS.md)

```md
## Yetki reddi test edilmiyor (vibecheck VC-104)
- Yetki testine izinli ve reddedilecek kimlikler ekle.
- Başka kullanıcı ve kiracı kayıtlarını ayır.
- Ret yanıtıyla birlikte değişmeyen veriyi doğrula.
- Kimlik kontrolü hata yolunu ayrıca sınayacak plan yap.
- İzinli kullanımın hâlâ çalıştığını koru.
```

## Kaynaklar

1. [OWASP Authorization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html), OWASP
2. [Recommended Minimum Standard for Vendor or Developer Verification of Code](https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity/software-supply-chain-security-guidance-3), NIST, 7 Ekim 2021
3. [Node.js Assert API](https://nodejs.org/api/assert.html), Node.js
4. [Node.js SQLite parameter binding](https://nodejs.org/api/sqlite.html), Node.js

---

vibecheck · Komünite editörlüğü. Metin CC BY 4.0, prompt ve kural parçaları MIT-0. Kaynak: https://vibecheck.komunite.com.tr/madde/yetki-icin-basarisizlik-testleri-yok
