---
title: 'Yaygın Web Riskleri'
source: 'https://academia.sh/tr/kurslar/frontend-kalitesi/yaygin-web-riskleri'
course: 'Frontend Kalitesi'
language: tr
updated: '2026-08-17T18:09:22+00:00'
license: 'CC BY-SA 4.0'
---

# Yaygın Web Riskleri

Sık görülen açık sınıflarının istemci tarafındaki karşılıkları; arayüzde verilen yetki kararları, açık yönlendirme, istemciye ulaşan veriye duyulan güven ve pakete sızan sırlar.

Bu konudaki altı ders belirli mekanizmalar kurdu: çıkışta kaçırma, içerik güvenlik
politikası, kaynaklar arası paylaşım kuralları, istek belirteçleri, güvenlik başlıkları ve
alt kaynak bütünlüğü. Her biri adı konmuş bir saldırı sınıfına karşılık geliyordu.

Uygulamada karşılaşılan sorunların bir bölümü bu sınıfların dışında kalır ve ortak bir
kökene sahiptir: istemcinin bir güvenlik sınırı sanılması. Bu ders, sık görülen açık
sınıflarını istemci tarafındaki izdüşümleriyle ele alır ve her biri için ölçülebilir bir
kural verir.

## Arayüzde Gizlemek Yetki Vermemekle Aynı Şey Değil

Kuzey Yamaç Ölçüm İstasyonu arayüzünde ölçüm kaydını düzenleme düğmesi yalnız düzenleyici
rolündeki kullanıcılara gösteriliyor. Bu doğru bir arayüz kararıdır ve yanlış bir güvenlik
kararıdır. Düğmenin görünmemesi, düğmenin tetiklediği isteğin gönderilemeyeceği anlamına
gelmez; istek bir adres ve bir gövdeden ibarettir.

```js
// yetki.mjs — istemci gizlemesi ile sunucu yetkilendirmesinin bagimsizligi
function arayuzGosterir(kullanici) {
  return kullanici.roller.includes('duzenleyici');
}

function sunucuIzinVerir(oturum, kayit) {
  if (!oturum.dogrulandi) return false;
  if (!oturum.roller.includes('duzenleyici')) return false;
  return kayit.istasyon === oturum.istasyon;
}

const kayit = { istasyon: 'kuzey-yamac', olcumNo: 4417 };
const durumlar = [
  ['duzenleyici, kendi istasyonu', { dogrulandi: true, roller: ['duzenleyici'], istasyon: 'kuzey-yamac' }],
  ['duzenleyici, baska istasyon', { dogrulandi: true, roller: ['duzenleyici'], istasyon: 'guney-sirt' }],
  ['yalniz okuyucu', { dogrulandi: true, roller: ['okuyucu'], istasyon: 'kuzey-yamac' }],
  ['dogrulanmamis', { dogrulandi: false, roller: ['duzenleyici'], istasyon: 'kuzey-yamac' }],
];

console.log('durum'.padEnd(30), 'dugme gorunur', 'istek kabul');
for (const [ad, oturum] of durumlar) {
  const gorunur = arayuzGosterir({ roller: oturum.roller }) ? 'evet' : 'hayir';
  const kabul = sunucuIzinVerir(oturum, kayit) ? 'evet' : 'hayir';
  console.log(ad.padEnd(30), gorunur.padEnd(14), kabul);
}
```

```
$ node yetki.mjs
durum                          dugme gorunur istek kabul
duzenleyici, kendi istasyonu   evet           evet
duzenleyici, baska istasyon    evet           hayir
yalniz okuyucu                 hayir          hayir
dogrulanmamis                  evet           hayir
```

İki sütunun ayrı ayrı hesaplanması bilerek yapıldı. İkinci ve dördüncü satırlar, arayüzün
"evet" dediği ama sunucunun "hayır" dediği durumlardır; arayüz tarafındaki karar yalnız
rolü görür, sunucu tarafındaki karar kaydın hangi istasyona ait olduğunu ve oturumun
doğrulanıp doğrulanmadığını da görür.

Bu ayrım iki alt sınıfın kökenidir. **Bozuk nesne düzeyinde erişim denetimi**, bir kaydın
tanımlayıcısı değiştirildiğinde sunucunun sahiplik denetimi yapmamasıdır; arayüz o kaydı
hiç göstermediği için sorun geç fark edilir. **Dikey yetki yükselmesi**, yalnız arayüzde
gizlenmiş bir yönetim işleminin doğrudan çağrılabilmesidir. İkisinin de savunması aynı
cümledir: her istek, isteği yapanın kim olduğuna ve neye eriştiğine bakılarak sunucuda
yeniden değerlendirilir.

Aynı kural doğrulamaya da uygulanır. Formların istemci tarafındaki kısıt doğrulaması bir
kullanılabilirlik özelliğidir; hatayı kullanıcıya erken gösterir. Veri bütünlüğünü sağlayan
denetim sunucudakidir ve istemci tarafındaki kuralın varlığı onu gereksizleştirmez.

## Açık Yönlendirme

Giriş akışı, kullanıcıyı doğrulamadan sonra geldiği sayfaya geri gönderir. Hedef adres
genellikle sorgu dizgisinde taşınır ve doğrulanmazsa uygulama, herhangi bir adrese
yönlendirme yapan bir araca dönüşür. Zararı doğrudan değildir: uygulamanın alan adı,
kullanıcıyı başka bir yere göndermek için kullanılır.

```js
// yonlendirme.mjs — gerisdonus adresini izin listesine gore dogrular
const KENDI_KAYNAGI = 'https://olcum.ornek.test';
const IZINLI_KAYNAKLAR = new Set([KENDI_KAYNAGI, 'https://rapor.ornek.test']);
const VARSAYILAN = KENDI_KAYNAGI + '/istasyon';

function gerisdonusHedefi(ham) {
  if (typeof ham !== 'string' || ham === '') return VARSAYILAN;
  let adres;
  try {
    adres = new URL(ham, KENDI_KAYNAGI);
  } catch {
    return VARSAYILAN;
  }
  if (!['http:', 'https:'].includes(adres.protocol)) return VARSAYILAN;
  if (!IZINLI_KAYNAKLAR.has(adres.origin)) return VARSAYILAN;
  return adres.href;
}

const adaylar = [
  '/istasyon/kuzey-yamac?gun=12',
  'https://rapor.ornek.test/ozet',
  'https://baska.ornek.test/giris',
  '//baska.ornek.test/giris',
  'https://olcum.ornek.test.baska.test/giris',
  'olcum-uygulamasi://ac',
  '',
];

for (const aday of adaylar) {
  console.log(gerisdonusHedefi(aday).padEnd(52), '<-', aday === '' ? '(bos)' : aday);
}
```

```
$ node yonlendirme.mjs
https://olcum.ornek.test/istasyon/kuzey-yamac?gun=12 <- /istasyon/kuzey-yamac?gun=12
https://rapor.ornek.test/ozet                        <- https://rapor.ornek.test/ozet
https://olcum.ornek.test/istasyon                    <- https://baska.ornek.test/giris
https://olcum.ornek.test/istasyon                    <- //baska.ornek.test/giris
https://olcum.ornek.test/istasyon                    <- https://olcum.ornek.test.baska.test/giris
https://olcum.ornek.test/istasyon                    <- olcum-uygulamasi://ac
https://olcum.ornek.test/istasyon                    <- (bos)
```

Dördüncü ve beşinci satırlar denetimin neden dizgi karşılaştırmasıyla yazılamayacağını
gösterir. Şema olmadan iki bölü işaretiyle başlayan bir adres, sayfanın şemasını devralarak
başka bir konağa gider; "kendi alan adımızla başlıyor" ölçütü ise `ornek.test.baska.test`
adını geçirir. Karşılaştırma çözümlenmiş adresin `origin` bileşeni üzerinde yapılır ve
doğrulanamayan her girdi izin listesine değil, sabit bir varsayılana düşer.

## İstemciye Ulaşan Veriye Duyulan Güven

Yerel depolamadan okunan bir tercih kaydı, adres parçasından çözülen bir durum veya bir
uçtan gelen yapılandırma nesnesi, uygulamanın kendi ürettiği veri değildir. Bu veriyi
uygulama nesnelerine birleştiren kod, anahtar adlarının da veri olduğunu varsaymalıdır.

```js
// birlestirme.mjs — disaridan gelen ayarlari prototip zincirine dokunmadan birlestirir
const TEHLIKELI_ANAHTARLAR = new Set(['__proto__', 'prototype', 'constructor']);

function guvenliBirlestir(taban, gelen) {
  const sonuc = Object.create(null);
  for (const [anahtar, deger] of Object.entries(taban)) sonuc[anahtar] = deger;
  for (const [anahtar, deger] of Object.entries(gelen)) {
    if (TEHLIKELI_ANAHTARLAR.has(anahtar)) {
      console.log('  atlanan anahtar:', anahtar);
      continue;
    }
    sonuc[anahtar] = deger;
  }
  return sonuc;
}

const varsayilan = { birim: 'santigrat', esik: -5, otomatikYenile: true };
const kayittanGelen = JSON.parse('{"esik": -12, "__proto__": {"yonetici": true}, "birim": "kelvin"}');

console.log('birlestirme:');
const ayarlar = guvenliBirlestir(varsayilan, kayittanGelen);

console.log('sonuc:', JSON.stringify(ayarlar));
console.log('prototip zinciri:', Object.getPrototypeOf(ayarlar));
console.log('sirada olmayan nesnede yonetici alani:', ({}).yonetici);
```

```
$ node birlestirme.mjs
birlestirme:
  atlanan anahtar: __proto__
sonuc: {"birim":"kelvin","esik":-12,"otomatikYenile":true}
prototip zinciri: null
sirada olmayan nesnede yonetici alani: undefined
```

JavaScript'te Nesneler ve Fonksiyonlar kursunda tanıtılan prototip zinciri burada bir saldırı yüzeyine
dönüşür: ortak bir prototipe yazılan bir alan, o prototipten türeyen bütün nesnelerde
görünür. Savunma iki parçalıdır. Birleştirme sırasında zincire ulaşan anahtarlar atlanır ve
hedef nesne **prototipsiz nesne** olarak oluşturulur; son satır, ilgisiz bir nesnenin
etkilenmediğini doğrular.

Aynı ilkenin başka bir uygulaması, dış veriyi bir şemaya karşı doğrulamaktır. Uygulama
Mimarisi kursundaki doğrulama şemaları dersinde kurulan yaklaşım burada güvenlik değeri
kazanır: beklenen alanları sayan bir şema, beklenmeyen anahtarları yapısal olarak eler.

## Pakete Sızan Sırlar

İstemciye gönderilen her şey herkese açıktır. Bu cümle bir uyarı değil, bir tanımdır: paket
dosyası indirilebilir, ağ paneli açılabilir, kaynak haritası okunabilir.

Buradan üç kural çıkar. Bir dış hizmetin gizli anahtarı istemci paketine konmaz; istemcinin
gerektirdiği çağrılar kendi sunucusu üzerinden yapılır. Yalnız istemci tarafında anlamlı
olan yapılandırma ile sunucu tarafındaki sır ayrı yerlerde tutulur ve derleme aracının
istemci paketine hangi değişkenleri gömdüğü açıkça denetlenir. Kaynak haritalarının üretim
ortamında herkese açık sunulup sunulmayacağı bilinçli bir karardır; hata izleme için
gerekiyorsa, tarayıcıya değil hata toplama katmanına verilir.

Aynı kural hata yüzeyine de uygulanır. İstemciye dönen hata iletileri iç yapı bilgisi
taşımaz; istemciden toplanan hata kayıtları ise kullanıcı verisi taşıyabilir ve toplanmadan
önce ayıklanmalıdır.

## Sınıfları Bir Arada Okumak

Bu konudaki yedi dersin ortak dokusu tek bir ölçütte toplanır: bir denetimin nerede
çalıştığı, o denetimin ne kadar güvenilebilir olduğunu belirler. İstemcide çalışan her
denetim kullanıcı deneyimine hizmet eder ve kullanıcının denetimindedir. Tarayıcının
uyguladığı denetimler (aynı kaynak politikası, içerik güvenlik politikası, çerez
nitelikleri, bütünlük doğrulaması) sunucunun bildirdiği kurallara dayanır ve kullanıcının
tarayıcısını korur. Sunucuda çalışan denetimler ise uygulamanın verisini korur ve
diğerlerinin hiçbiri onların yerine geçmez.

Üç katmanın karıştırılması, bu konuda anlatılan açık sınıflarının çoğunun ortak nedenidir.

## Özet

- Arayüzde bir denetimi gizlemek yetkilendirme değildir; her istek sunucuda, isteği yapanın
  kimliğine ve eriştiği kayda bakılarak yeniden değerlendirilir.
- İstemci tarafındaki kısıt doğrulaması kullanılabilirlik içindir; veri bütünlüğünü
  sunucudaki doğrulama sağlar.
- Yönlendirme hedefi çözümlenmiş adresin kaynağı üzerinden izin listesine karşı sınanır;
  doğrulanamayan girdi sabit bir varsayılana düşer.
- Dış kaynaktan gelen nesnelerde anahtar adları da veridir; birleştirme prototip zincirine
  ulaşan anahtarları eler ve hedefi prototipsiz nesne olarak kurar.
- İstemciye gönderilen her şey herkese açıktır; gizli anahtarlar pakete girmez, kaynak
  haritalarının yayımlanması bilinçli bir karardır.
- Bir denetimin güvenilirliği nerede çalıştığına bağlıdır: istemci, tarayıcı ve sunucu
  katmanları birbirinin yerine geçmez.

## Sonraki Adım

Bu konu boyunca kurulan savunmaların ortak bir zayıflığı vardır: hepsi sessizce bozulabilir.
Bir kaçırma noktası atlanır, bir politika yönergesi gevşetilir, bir çerez niteliği düşer, bir
bütünlük değeri güncellenmeden bırakılır — ve arayüz her durumda çalışmayı sürdürür. Kalitenin
son ekseni bu yüzden ölçmedir. Sonraki konu, davranışın beklendiği gibi kaldığını doğrulayan
sınamalarla başlar: Birim ve Bileşen Testleri dersi, bileşenlerin gerçekten ne yaptığını
davranış üzerinden sınamanın kurallarını kurar.
