---
title: 'Su Kuyusu Saldırıları'
source: 'https://academia.sh/tr/kurslar/saldiri-teknikleri/su-kuyusu-saldirilari'
course: 'Saldırı Teknikleri ve Tehdit Ortamı'
language: tr
updated: '2026-08-17T18:08:33+00:00'
license: 'CC BY-SA 4.0'
---

# Su Kuyusu Saldırıları

Su kuyusu saldırısını paylaşılan bağımlılık olarak modellemek: altı iç uygulamanın gittiği sekiz dış kaynak, tek bir kaynağın kaç kullanıcıyı aynı anda ilgilendirdiği, altı adımlık zincirin kaynak başına hangi halkada kırıldığı, kaynak bütünlüğü karmasının kırdığı üç zincir ve sürüm sabitlemesinin yılda 48 günlük gecikme bedeli.

Önceki dersin taklidi hedefi kendisine çağırıyordu: bir ad kaydediliyor ve hedefin ona gitmesi
bekleniyordu. Tersi de mümkündür — hedefin **zaten gittiği** bir yerin bozulması. Kurum içindeki
kullanıcıların bir bölümü her gün aynı dış kaynağa uğrar: ortak bir betik kütüphanesi, bir yazı
tipi kaynağı, bir belge deposu, bir sektör duyuru sayfası. Bu kaynaklar kurumun denetiminde
değildir ve her biri tek bir noktadır.

Su kuyusu saldırısı bu yüzden hedefe değil, hedefin **bağımlılığına** yönelir. Ölçüsü de buradan
çıkar: bir dış kaynak bozulduğunda kaç kullanıcı aynı anda ilgilenir ve bu kullanıcıların zinciri
hangi halkada kırılır? Kaynak türü burada belirleyicidir, çünkü hangi denetimin uygulanabildiğini
tür belirler. Sürüm sabitlenebilen bir kaynağın karması hesaplanabilir; kullanıcının doğrudan
gittiği bir dış sayfanın karması yoktur. Zincirin sonundaki adım — sürükle–bırak indirmesi
(drive-by download) sonrası tutunma — başka bir kursta ölçülmüştü; burada yalnız zincirin son
halkası olarak geçer.

- **SM31.** Uygulamalar, kullanıcı sayıları ve dış kaynak listesi kurgusal bölgesel ölçüm ağına
  aittir. Gerçek bir kaynak çağrılmıyor; ölçülen şey `node` ile kurulan modeldir.
- **SM32.** Uygulamaların kullanıcı kümeleri ayrık sayıldı. Gerçekte bir kullanıcı birden çok
  uygulamayı kullanır; ayrıklık toplam kullanıcıyı olduğundan **büyük**, örtüşen kaynak paylaşımını
  olduğundan **küçük** gösterir.
- **SM33.** Bir kaynağa uygulanabilen denetimler modelde sabit yazıldı. Gerçekte bir kaynağın
  sürümü sabitlenebilir mi sorusunun cevabı sağlayıcıya bağlıdır ve zamanla değişir.
- **SM34.** Zincirin ikinci adımı — kaynağın bozulması — kurumun denetim alanının dışındadır ve bu
  yüzden hiçbir denetimle eşlenmedi. Sağlayıcının kendi savunması modellenmedi.
- **SM35.** Düşen kalem, o adımdan sonra erişilebilir hale gelen oturum, dosya ve uç kaleminin
  sayısıdır. Kalem türleri ayrı ağırlıklandırılmadı.
- **SM36.** Elle onay gecikmesi ve yıllık güncelleme sayısı kurgudur. İkisi de kaynak türüne göre
  büyük ölçüde değişir; sabit değer bedelin **yönünü** gösterir, büyüklüğünü değil.

## Paylaşım Kaç Kullanıcı Demek

```js
// kaynak.mjs — ic uygulamalar, paylasilan dis kaynaklar ve su kuyusu zinciri; model
// [uygulama, gunluk kullanici]
export const UYGULAMA = [
  ['saha is emri uygulamasi', 180], ['abone portali', 1400], ['fatura uretim arayuzu', 60],
  ['sube uc panosu', 90], ['olcum izleme panosu', 240], ['ic duyuru sayfasi', 620],
];
export const kullanici = (ad) => UYGULAMA.find((u) => u[0] === ad)[1];
const [S, A, F, U, O, D] = UYGULAMA.map((u) => u[0]);
// denetim -> zincirin kactaki adimini kiriyor
export const DENETIM = { karma: 3, politika: 4, imza: 5, 'uc nokta': 6 };
// [dis kaynak, tur, kullanan uygulamalar, uygulanabilen denetimler, yillik guncelleme]
export const KAYNAK = [
  ['ortak betik kutuphanesi', 'betik', [S, A, F, U, O, D], ['karma', 'politika', 'uc nokta'], 12],
  ['yazi tipi kaynagi', 'yazi tipi', [A, O, D], ['karma', 'politika', 'uc nokta'], 2],
  ['grafik cizim kutuphanesi', 'betik', [F, O], ['karma', 'politika', 'uc nokta'], 6],
  ['harita karo hizmeti', 'gorsel', [S, O], ['politika', 'uc nokta'], 0],
  ['olcum arac indirmesi', 'ikili', [S, U], ['imza', 'uc nokta'], 4],
  ['takvim beslemesi', 'veri', [A, D], ['politika', 'uc nokta'], 0],
  ['ortak belge deposu', 'dis sayfa', [S, F, U, D], ['uc nokta'], 0],
  ['sektor duyuru sayfasi', 'dis sayfa', [F, D], ['uc nokta'], 0],
];
// [adim, onkosul, adim bitince dusen kalem]
export const ZINCIR = [
  ['paylasilan kaynagin belirlenmesi', 'dis kaynak listesinin disaridan gorulmesi', 0],
  ['kaynagin bozulmasi', 'kaynak saglayicisi tarafinda erisim', 0],
  ['teslim', 'istemcinin kaynagi cekmesi', 1],
  ['istemcide calisma', 'istemcinin kaynagi calistirmasi', 2],
  ['yerel indirme', 'kullanici onayi', 3],
  ['tutunma', 'calistirma izni', 6],
];
export const KUMUL = (() => { let s = 0; return ZINCIR.map((a) => (s += a[2])); })();
export const erisen = (k) => k[2].reduce((a, u) => a + kullanici(u), 0);
export function halkalar(k, karmaVar = true) {
  return k[3].filter((d) => karmaVar || d !== 'karma').map((d) => DENETIM[d]).sort((a, b) => a - b);
}
export const dusen = (h) => (h.length ? KUMUL[h[0] - 2] ?? 0 : KUMUL[ZINCIR.length - 1]);
```

```js
// kosum1.mjs — paylasilan dis kaynaklarin kullanici sayisi ve zincirin en erken kirilan halkasi
import { UYGULAMA, KAYNAK, ZINCIR, KUMUL, erisen, halkalar, dusen } from './kaynak.mjs';

const toplam = UYGULAMA.reduce((a, u) => a + u[1], 0);
console.log(`${UYGULAMA.length} ic uygulama, gunluk ${toplam} kullanici; ${KAYNAK.length} paylasilan dis kaynak`);
console.log(`zincir ${ZINCIR.length} adim, hic kirilmazsa dusen kalem ${KUMUL[ZINCIR.length - 1]}\n`);
console.log(`${'#'.padStart(2)} ${'adim'.padEnd(33)} ${'onkosul'.padEnd(42)} ${'dusen'.padStart(5)}`);
ZINCIR.forEach((a, i) => console.log(`${String(i + 1).padStart(2)} ${a[0].padEnd(33)} ${a[1].padEnd(42)} ${String(KUMUL[i]).padStart(5)}`));
console.log(`\n${'dis kaynak'.padEnd(25)} ${'tur'.padEnd(10)} ${'uygulama'.padStart(8)} ${'kullanici'.padStart(9)} ` +
  `${'denetim'.padStart(7)} ${'en erken halka'.padStart(14)} ${'dusen'.padStart(5)}`);
const sirali = [...KAYNAK].sort((a, b) => erisen(b) - erisen(a));
for (const k of sirali) {
  const h = halkalar(k);
  console.log(`${k[0].padEnd(25)} ${k[1].padEnd(10)} ${String(k[2].length).padStart(8)} ${String(erisen(k)).padStart(9)} ` +
    `${String(h.length).padStart(7)} ${String(h[0]).padStart(14)} ${String(dusen(h)).padStart(5)}`);
}
const eslesme = KAYNAK.reduce((a, k) => a + erisen(k), 0);
console.log(`\ntoplam kullanici-kaynak eslesmesi ${eslesme}; en cok paylasilan kaynak ${sirali[0][0]} ` +
  `(${sirali[0][2].length}/${UYGULAMA.length} uygulama, ${erisen(sirali[0])} kullanici)`);
console.log(`tek bir kaynagin bozulmasi en fazla ${erisen(sirali[0])} kullaniciyi ayni anda ilgilendirir, ` +
  `bu toplam kullanicinin %${Math.round((erisen(sirali[0]) / toplam) * 100)}'idir`);
```

```
6 ic uygulama, gunluk 2590 kullanici; 8 paylasilan dis kaynak
zincir 6 adim, hic kirilmazsa dusen kalem 12

 # adim                              onkosul                                    dusen
 1 paylasilan kaynagin belirlenmesi  dis kaynak listesinin disaridan gorulmesi      0
 2 kaynagin bozulmasi                kaynak saglayicisi tarafinda erisim            0
 3 teslim                            istemcinin kaynagi cekmesi                     1
 4 istemcide calisma                 istemcinin kaynagi calistirmasi                3
 5 yerel indirme                     kullanici onayi                                6
 6 tutunma                           calistirma izni                               12

dis kaynak                tur        uygulama kullanici denetim en erken halka dusen
ortak betik kutuphanesi   betik             6      2590       3              3     0
yazi tipi kaynagi         yazi tipi         3      2260       3              3     0
takvim beslemesi          veri              2      2020       2              4     1
ortak belge deposu        dis sayfa         4       950       1              6     6
sektor duyuru sayfasi     dis sayfa         2       680       1              6     6
harita karo hizmeti       gorsel            2       420       2              4     1
grafik cizim kutuphanesi  betik             2       300       3              3     0
olcum arac indirmesi      ikili             2       270       2              5     3

toplam kullanici-kaynak eslesmesi 9490; en cok paylasilan kaynak ortak betik kutuphanesi (6/6 uygulama, 2590 kullanici)
tek bir kaynagin bozulmasi en fazla 2590 kullaniciyi ayni anda ilgilendirir, bu toplam kullanicinin %100'idir
```

Kaynak tablosunun ilk satırı ölçünün tamamını taşıyor. Ortak betik kütüphanesi altı uygulamanın
altısında da kullanılıyor ve 2.590 kullanıcının hepsine ulaşıyor — modeldeki toplam kullanıcının
yüzde yüzü. Bir tek dış kaynağın bozulması, kurumun içinde hiçbir şeye dokunmadan bütün
kullanıcıları aynı anda ilgilendirir. Kimlik avında hedef listesi kurulur; burada hedef listesi
zaten kuruludur ve onu kuran kurumun kendi bağımlılık seçimidir.

Kullanıcı sayısı ile uygulama sayısı aynı sıralamayı vermiyor. Takvim beslemesi yalnız iki
uygulamada kullanılıyor ama 2.020 kullanıcıya ulaşıyor; ortak belge deposu dört uygulamada
kullanılıyor ve 950 kullanıcıya. Paylaşımın ölçüsü kaç uygulamanın kullandığı değil, o
uygulamaların **kaç kişiye** hizmet ettiğidir. Bağımlılık envanterini uygulama sayısına göre
sıralayan bir çalışma yanlış üç kalemi öne çıkarır.

Son iki sütun zincirin nerede kırıldığını gösteriyor. Üç kaynakta en erken halka üçüncü adımdır ve
orada düşen kalem sıfırdır. İki dış sayfada en erken halka altıncı adımdır — zincirin son
adımı — ve oraya gelindiğinde altı kalem düşmüştür. Aradaki fark denetim sayısındadır: birinde üç
denetim uygulanabiliyor, ötekinde bir.

## Bütünlük Denetiminin Kazancı ve Bedeli

```js
// kosum2.mjs — kaynak butunlugu denetiminin kirdigi zincir sayisi, kullanici agirlikli kazanc ve bedeli
import { UYGULAMA, KAYNAK, KUMUL, erisen, halkalar, dusen } from './kaynak.mjs';

const ONAY_GUN = 2; // kurgu: surum sabitlemede bir guncellemenin elle onay gecikmesi
console.log(`${'dis kaynak'.padEnd(25)} ${'kullanici'.padStart(9)} ${'karmasiz halka'.padStart(14)} ${'dusen'.padStart(5)} ` +
  `${'karmali halka'.padStart(13)} ${'dusen'.padStart(5)} ${'kazanc'.padStart(6)}`);
let kiran = 0, agirlikli = 0;
for (const k of [...KAYNAK].sort((a, b) => erisen(b) - erisen(a))) {
  const y = halkalar(k, false), v = halkalar(k, true), dy = dusen(y), dv = dusen(v);
  if (dy !== dv) { kiran++; agirlikli += (dy - dv) * erisen(k); }
  console.log(`${k[0].padEnd(25)} ${String(erisen(k)).padStart(9)} ${String(y[0]).padStart(14)} ${String(dy).padStart(5)} ` +
    `${String(v[0]).padStart(13)} ${String(dv).padStart(5)} ${String(dy - dv).padStart(6)}`);
}
const karmali = KAYNAK.filter((k) => k[3].includes('karma'));
const eslesme = KAYNAK.reduce((a, k) => a + erisen(k), 0);
console.log(`\nkaynak butunlugu karmasi ${kiran}/${KAYNAK.length} zinciri daha erken kiriyor; ` +
  `kapsadigi kullanici-kaynak eslesmesi ${karmali.reduce((a, k) => a + erisen(k), 0)}/${eslesme} (%${Math.round(karmali.reduce((a, k) => a + erisen(k), 0) / eslesme * 100)})`);
console.log(`kullanici agirlikli erken kirma kazanci ${agirlikli} kalem-kullanici`);
const gec = KAYNAK.filter((k) => halkalar(k)[0] === 6);
console.log(`en gec kirilan zincirler (halka 6, dusen ${KUMUL[4]}): ${gec.map((k) => `${k[0]} (${erisen(k)} kullanici)`).join('; ')}`);
console.log(`bu iki kaynakta karma uygulanamaz; ikisi de kurumun denetiminde olmayan dis sayfadir`);
const imzali = KAYNAK.filter((k) => k[3].includes('imza'));
const onay = [...karmali, ...imzali].reduce((a, k) => a + k[4], 0); // sabitlenen kaynaklarin yillik guncellemesi
console.log(`\nbedel: surum sabitlemesi gereken ${karmali.length + imzali.length} kaynak, yilda ${onay} elle onay, ` +
  `onay basina ${ONAY_GUN} gun gecikme = ${onay * ONAY_GUN} gun/yil kaynak eskimesi`);
console.log(`kapsam disi kalan ${KAYNAK.length - karmali.length - imzali.length} kaynak, ` +
  `${KAYNAK.filter((k) => !k[3].includes('karma') && !k[3].includes('imza')).reduce((a, k) => a + erisen(k), 0)} kullanici-kaynak eslesmesi`);
console.log(`toplam gunluk kullanici ${UYGULAMA.reduce((a, u) => a + u[1], 0)}; kapsam disi eslesme bunun ` +
  `${(KAYNAK.filter((k) => !k[3].includes('karma') && !k[3].includes('imza')).reduce((a, k) => a + erisen(k), 0) / UYGULAMA.reduce((a, u) => a + u[1], 0)).toFixed(2)} kati`);
```

```
dis kaynak                kullanici karmasiz halka dusen karmali halka dusen kazanc
ortak betik kutuphanesi        2590              4     1             3     0      1
yazi tipi kaynagi              2260              4     1             3     0      1
takvim beslemesi               2020              4     1             4     1      0
ortak belge deposu              950              6     6             6     6      0
sektor duyuru sayfasi           680              6     6             6     6      0
harita karo hizmeti             420              4     1             4     1      0
grafik cizim kutuphanesi        300              4     1             3     0      1
olcum arac indirmesi            270              5     3             5     3      0

kaynak butunlugu karmasi 3/8 zinciri daha erken kiriyor; kapsadigi kullanici-kaynak eslesmesi 5150/9490 (%54)
kullanici agirlikli erken kirma kazanci 5150 kalem-kullanici
en gec kirilan zincirler (halka 6, dusen 6): ortak belge deposu (950 kullanici); sektor duyuru sayfasi (680 kullanici)
bu iki kaynakta karma uygulanamaz; ikisi de kurumun denetiminde olmayan dis sayfadir

bedel: surum sabitlemesi gereken 4 kaynak, yilda 24 elle onay, onay basina 2 gun gecikme = 48 gun/yil kaynak eskimesi
kapsam disi kalan 4 kaynak, 4070 kullanici-kaynak eslesmesi
toplam gunluk kullanici 2590; kapsam disi eslesme bunun 1.57 kati
```

Karma sütunları kaynak bütünlüğü denetiminin ne yaptığını sayıyor: sekiz zincirin üçünü bir halka
daha erken kırıyor. Kazanç sütunu kaynak başına yalnız bir kalemdir, ama kapsadığı kullanıcı sayısı
büyüktür — kullanıcı ağırlıklı kazanç 5.150 kalem-kullanıcıdır ve toplam eşleşmenin yüzde elli
dördünü karşılar. Denetimin değeri kalem sayısında değil, o kalemin kaç kullanıcıda birden
düşmemesinde toplanıyor.

Kalan beş kaynakta karma hiçbir şey değiştirmiyor. İki dış sayfada bunun nedeni açıktır: kullanıcı
oraya doğrudan gidiyor ve çekilen şey sabit bir sürüm değil, o anki sayfadır. Bu iki kaynak zinciri
en geç kıran ikisidir — altıncı halka, altı kalem düşmüşken — ve birlikte 1.630 kullanıcıya
ulaşıyorlar. Bir kaynağın **paylaşılması** ile **denetlenebilmesi** arasında bir ilişki yoktur; en
çok paylaşılan kaynak en denetlenebilir olanıydı, en geç kırılan iki kaynak ise orta sıralarda
duruyor.

Bedel iki kalemde toplanıyor. Sürüm sabitlemesi gereken dört kaynak yılda yirmi dört elle onay
üretiyor; onay başına iki günlük gecikmeyle bu, yılda kırk sekiz gün boyunca kaynağın güncel
olmayan bir sürümde tutulması demektir. Bu gecikme kendi başına bir açıklık üretir: sağlayıcının
kapattığı bir sorun, onay tamamlanana kadar kurumda açık kalır. Denetimin bedeli burada bir işgücü
kalemi değil, **karşı yönde bir risk**tir.

Kapsam dışı kalan dört kaynak 4.070 kullanıcı-kaynak eşleşmesi taşıyor; bu, günlük toplam kullanıcı
sayısının 1,57 katıdır. Yani ortalama bir kullanıcı, hiçbir bütünlük denetimi bulunmayan bir buçuk
dış kaynağa her gün uğruyor. Zincirin bu kaynaklar üzerinden kırılması yalnız uç nokta korumasına
kalıyor ve orada düşen kalem altıdır.

## Kırılamayan İlk İki Halka

Zincir tablosunun ilk iki adımının karşısında hiçbir denetim yok ve nedenleri farklıdır. Birinci
adım — paylaşılan kaynağın belirlenmesi — kurumun içinden görünmez, çünkü dış kaynak listesi
istemcinin çektiği her şeyde zaten yazılıdır; onu gizlemek diye bir seçenek yoktur. İkinci adım
kaynağın kendi tarafında geçer ve kurumun denetim alanının tamamen dışındadır.

Bu iki halka kırılamadığına göre geriye tek bir kaldıraç kalır: **kaç kaynağa bağımlı olunduğunu
azaltmak.** Tablo bunun ölçüsünü de veriyor. Ortak betik kütüphanesi kurum içine alınırsa 2.590
kullanıcılık eşleşme dış listeden düşer, ama kalem kurumun envanterine geçer ve güncel tutulması
kurumun işi olur. Kapsam dışı kalan dört kaynağın 4.070 eşleşmesi ise böyle taşınamaz: ikisi
kullanıcının doğrudan gittiği dış sayfadır ve içeri alınacak bir sürümleri yoktur.

Ölçünün kaydığı yer buradadır. İlk iki halka kırılamıyorsa kalan iş **tespittir**: hangi kaynağın
ne zaman değiştiğini gören bir kayıt, zinciri kırmaz ama üçüncü halkadaki denetimin ne zaman
devreye girdiğini gösterir. Bağımlılık envanteri bu yüzden bir belge değil, bir ölçüm kalemidir:
kaç kaynak, kaç kullanıcı, kaçında denetim var.

## Özet

- 6 iç uygulama günde 2.590 kullanıcıya hizmet ediyor ve 8 dış kaynağı paylaşıyor. En çok paylaşılan
  kaynak 6 uygulamanın hepsinde kullanılıyor ve kullanıcıların %100'üne ulaşıyor.
- Kullanıcı sayısı ile uygulama sayısı aynı sıralamayı vermiyor: 2 uygulamada kullanılan bir kaynak
  2.020 kullanıcıya, 4 uygulamada kullanılan bir başkası 950 kullanıcıya ulaşıyor.
- Zincir 6 adım; hiç kırılmazsa düşen kalem 12'dir. 3 kaynakta en erken halka 3. adımdır (0 kalem),
  2 dış sayfada 6. adımdır (6 kalem).
- Kaynak bütünlüğü karması 8 zincirin 3'ünü bir halka erken kırıyor. Kullanıcı ağırlıklı kazanç
  5.150 kalem-kullanıcı, toplam eşleşmenin %54'ü.
- Karmanın uygulanamadığı 2 dış sayfa 1.630 kullanıcıya ulaşıyor ve zinciri en geç kıran ikisidir.
  Paylaşım derecesi ile denetlenebilirlik arasında bir ilişki çıkmıyor.
- Bedel: 4 kaynakta sürüm sabitlemesi, yılda 24 elle onay, 48 gün/yıl güncel olmayan sürüm. Kapsam
  dışı 4 kaynak 4.070 eşleşme taşıyor — günlük kullanıcı sayısının 1,57 katı.

## Sonraki Adım

Altı ders boyunca ölçülen her denetim teknikti: bir yordam, bir eşik, bir kapı, bir karma. Oysa
zincirlerin çoğunda kırılabilen halka bir kişinin verdiği karara bağlıydı — geri arayıp aramamaya,
bir göstergeyi fark edip bildirmeye, bir kapıyı tutup tutmamaya. O kararın kendisi eğitilebilir bir
davranıştır ve eğitimin etkisi ölçülebilir. Sonraki dersin sorusu budur: bir farkındalık programı
iki ölçütte — bildirim oranı ve tıklama oranı — kaç puan kazandırıyor, bu kazanç kaç hafta sonra
eski değerine dönüyor ve programın kendi bedeli nedir. Konunun kapanış dersidir.
