İçeriğe atla
0 XP 0
13 dkderinleşmeyle 14 dk50 XP7 etkinlik

Sızmış sırrı yakalamak ve insan gözüyle okumak

Bu derste
  • Sır taraması koda ve commit geçmişine sızmış anahtarı arar; güvenlik incelemesi ise araçların göremediği iş mantığı hatasını yakalar.
  • gitleaks ve detect-secrets çıktısını oku. Gizli anahtarları birden fazla kontrolle korumayı ve sızıntıya doğru sırayla müdahale etmeyi öğren. İnceleme yorumunu ilgili ASVS maddesine bağla.

Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +50 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.

Altay Kargo'da bir geliştirici, depo servisinin API anahtarını sınamak için koda yapıştırdı. Commit'i gönderdi, ertesi gün fark edip satırı sildi. Bir ay sonra anahtar, depoyu klonlayan bir yüklenicinin kaybolan dizüstü bilgisayarından çıkan dosyalarda göründü.

SAST, DAST ve IaC taraması bir zayıflık deseni arar. Sır taraması (secret scanning) başka bir şey arar: sırrın kendisini. Parola, API anahtarı, bağlantı dizesi, özel anahtar ve bulut kimlik bilgisi kod tabanına düz metin olarak girmemelidir.

Girdiğinde onu sürüm kontrolünden temizlemek sandığından zordur. Bu derste sırrın neden geçmişte kaldığını, araçların onu nasıl bulduğunu ve hangi katmanda durdurulduğunu görürsün. İkinci yarıda otomasyonun göremediği alana dönersin: insan gözüyle güvenlik kod incelemesi.

Geçmiş unutmaz

Git her commit'i bir anlık görüntü olarak saklar. Bir satırı silen yeni commit son hâli değiştirir, ama eski commit deponun tarihinde aynen durur. Depo bir kez klonlandıysa eski commit her kopyada da vardır. Bu yüzden anahtarı silip yeni commit göndermek sızıntıyı kapatmaz.

Geçmişi yeniden yazmak, örneğin git filter-repo ile, yalnız senin kopyandaki izi temizler. Başkalarının klonları, çatallar, CI önbellekleri ve derleme günlükleri eski hâli tutmaya devam edebilir.

Gerçek çözüm anahtarı geçersiz kılmaktır. Sır tarayıcıları da bu yüzden yalnız son hâle değil, commit geçmişinin tamamına bakar. Aynı şeyi elle de görebilirsin. Aşağıdaki iki komut Altay Kargo'nun deposunda anahtarın izini sürer.

$ git log -S 'sk_live_' --oneline
802b844 Anahtar ortam değişkenine taşındı
e123c7d Depo durum servisi
$ git show e123c7d:depo_durum.py | sed -n 4p
DEPO_API_ANAHTARI = "sk_live_51H8x9K2mQaZ7f3jN0pR"
Silinen anahtar eski commit'ten aynen okunur.

-S seçeneği, verilen dizgenin dosyalardaki geçiş sayısını değiştiren commit'leri listeler. İki commit çıkar: e123c7d anahtarı ekledi, 802b844 anahtarı sildi. git show komutu commit kimliği ile dosya yolunu iki nokta üst üsteyle birleştirir ve dosyanın o anki hâlini basar.

sed -n 4p yalnız dördüncü satırı gösterir. Sonuç açıktır: bugünkü dosyada anahtar yok, ama depoyu klonlayan herkes onu iki komutla okur. Saldırganlar da açık depolarda tam olarak bunu yapar ve geçmişi otomatik araçlarla tarar.

Etkinlik 1 / 7

Doğru mu, yanlış mı?

Güncel koddan silinen bir API anahtarı, eski bir commit'te okunabilir durumda kalır.

Sır tarayıcıları nasıl bulur

Tarayıcılar üç yöntemi birleştirir. İlki kalıptır. Birçok sağlayıcı anahtarına sabit bir önek koyar: AWS erişim anahtarı AKIA ile, GitHub kişisel erişim jetonu ghp_ ile başlar. Önek ve uzunluk birlikte yazılmış bir düzenli ifade, bu anahtarları yüksek isabetle bulur.

İkincisi entropidir. Rastgele üretilmiş bir dize, insanın yazdığı metinden daha düzensizdir. Shannon entropisi bu düzensizliği ölçer ve önek taşımayan anahtarlar böyle yakalanır. Bedeli gürültüdür; sabit UUID'ler, özet değerleri ve test verisi de yüksek entropi taşır.

Üçüncüsü canlılık doğrulamasıdır. TruffleHog gibi araçlar bulduğu anahtarı sağlayıcının API'sine sorar ve anahtarın çalışıp çalışmadığını söyler. Doğrulama yanlış pozitifi büyük ölçüde siler, ama dış bir servise istek yollar. Bunu yalnız kendi deponda ve izinle kullan.

Altay Kargo'nun deposunda gitleaks'i iki ayrı modda çalıştırırsın. dir alt komutu yalnız dosyaların bugünkü hâline bakar ve klasördeki her dosyayı okur. git alt komutu ise commit geçmişini tarar ve her commit'in getirdiği değişikliği tek tek inceler.

-v seçeneği her bulgunun ayrıntısını basar. Aynı depo iki modda iki farklı sonuç verir. Fark, geçmişe bakmayan bir taramanın neden yetmediğini tek ekranda gösterir.

$ gitleaks dir .
INF scanned ~266 bytes (266 bytes) in 1.94ms
INF no leaks found

$ gitleaks git . -v
Finding:     ...EPO_API_ANAHTARI = "sk_live_51H8x9K2mQaZ7f3jN0pR"
Secret:      sk_live_51H8x9K2mQaZ7f3jN0pR
RuleID:      stripe-access-token
Entropy:     4.735926
File:        depo_durum.py
Line:        4
Commit:      e123c7d8ef6950c22d7b9064a184bb4429c45296
Author:      Deniz Ak
Email:       [email protected]
Date:        2026-08-27T09:14:02Z
Fingerprint: e123c7d8ef6950c22d7b9064a184bb4429c45296:depo_durum.py:stripe-access-token:4

INF 2 commits scanned.
WRN leaks found: 1
gitleaks 8.30 çıktısı. Bugünkü dosya temiz, geçmiş değil.

dir modu temiz der, çünkü bugünkü dosya anahtarı ortam değişkeninden okuyor. git modu iki commit'i tarar ve ilk commit'te anahtarı bulur. RuleID eşleşen kuraldır: sk_live_ önekiyle başlayan bir ödeme anahtarı. Entropy, dizenin düzensizlik puanıdır.

Commit, Author ve Date satırları sızıntının ne zaman ve kimden geldiğini söyler; olay kaydı için gereken bilgi budur. Fingerprint satırı bulgunun parmak izidir ve commit, dosya, kural ve satırdan oluşur. Bulgu incelenip zararsız çıkarsa bu parmak izi .gitleaksignore dosyasına yazılır ve tarama onu bir daha göstermez. gitleaks bulgu varsa 1 koduyla çıkar, böylece hat durur.

Etkinlik 2 / 7

Gizli anahtar tarayıcısı bu dosyada hangi satırı işaretler?

Zafiyetli satıra tıkla.

Katmanlı savunma: editörden sunucuya

Sırrı en ucuz durduracağın yer commit'ten öncesidir. Altay Kargo beş katman kullanır. Birinci katman editör eklentisidir ve anahtar yapıştırıldığı anda uyarır.

İkinci katman pre-commit kancasıdır. gitleaks'in kancası commit'e girecek değişiklikleri tarar ve sır bulursa commit'i durdurur.

Üçüncü katman sunucu tarafıdır. GitHub'ın push koruması (push protection), bilinen biçimdeki sırrı gönderim anında engeller. Geliştirici engeli üç gerekçeden biriyle aşabilir: testte kullanılıyor, yanlış pozitif ya da sonra düzelteceğim. Son gerekçe açık bir uyarı bırakır, ilk ikisi kapalı uyarı olarak kaydedilir ve atlama denetim günlüğüne düşer.

Dördüncü katman bütün geçmişin düzenli taramasıdır. Beşinci katman depo dışını kapsar, çünkü konteyner imaj katmanları ve CI günlükleri de sır taşır.

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.30.0
    hooks:
      - id: gitleaks
Kanca her commit'te gitleaks git --pre-commit --redact --staged --verbose komutunu çalıştırır.

Eski bir depoya tarayıcı eklediğinde onlarca eski bulgu çıkar. Hepsini aynı gün kapatamazsın, ama yenilerin eklenmesini durdurabilirsin. detect-secrets bunun için temel çizgi (baseline) dosyası kullanır. scan komutu var olan bulguları .secrets.baseline dosyasına yazar.

audit komutu her bulguyu tek tek gezer ve gerçek mi, yanlış pozitif mi diye işaretlemeni ister. Kanca artık yalnız temel çizgide olmayan yeni sırda durur. Aşağıdaki örnekte biri dosyaya yeni bir AWS anahtarı ekledi ve kanca commit'i durdurdu.

$ detect-secrets scan > .secrets.baseline
$ detect-secrets audit .secrets.baseline
$ detect-secrets-hook --baseline .secrets.baseline depo_durum.py
ERROR: Potential secrets about to be committed to git repo!

Secret Type: AWS Access Key
Location:    depo_durum.py:10
detect-secrets 1.5 kancası. Temel çizgideki eski bulgu sessiz kalır, yeni anahtar commit'i durdurur.

Temel çizgi dosyasına bakınca ilginç bir ayrıntı görürsün. Eski ödeme anahtarı orada Base64 High Entropy String türüyle kayıtlıdır. detect-secrets'ın ödeme sağlayıcısı kalıbı önekten sonra tam 24 karakter bekler, bu anahtarda ise 20 karakter var.

Kalıp eşleşmedi, entropi eklentisi yakaladı. gitleaks aynı anahtarı kendi kalıbıyla buldu, çünkü onun kuralı daha geniş bir uzunluk aralığı kabul eder. Tek bir yönteme ya da tek bir araca güvenmemenin nedeni budur.

Etkinlik 3 / 7

Bir sırrın karşılaştığı savunma katmanlarını, geliştiricinin klavyesinden başlayarak sırala.

Sürükleyip doğru sıraya koy.

Bir öğeye odaklan, yukarı ve aşağı ok tuşlarıyla taşı. Home tuşu en üste, End tuşu en alta alır.

  • 1pre-commit kancası commit'i durdurur
  • 2Gece çalışan tam geçmiş taraması eski commit'leri okur
  • 3Sunucunun push koruması gönderimi engeller
  • 4Editör eklentisi yapıştırılan anahtarı işaretler

İnsan gözüyle güvenlik incelemesi

Otomatik araçlar kalıp arar. Kalıba uymayan hata, yani iş mantığı ya da eksik yetki denetimi, hiçbir taramada görünmez. Bu boşluğu güvenlik kod incelemesi kapatır.

İyi bir inceleme her dosyayı eşit okumaz. Önce riskli dosyaları seçer: kimlik doğrulama, yetkilendirme, ödeme, dosya yükleme, şablon ve sorgu kuran katmanlar. Sonra değişikliği kaynaktan hedefe izler.

Yeni bir parametre nereden giriyor, hangi denetimden geçiyor, nerede kullanılıyor? Altay Kargo bu dosyalar için bir CODEOWNERS kuralı yazdı ve dal korumasında kod sahibi onayını zorunlu kıldı. Büyük değişiklik ayrı bir risktir. Bin satırlık bir çekme isteği tek oturumda dikkatle okunamaz; incelemeyi parçalara bölmek isabeti artırır.

# .github/CODEOWNERS
/src/odeme/   @altaykargo/guvenlik
/src/kimlik/  @altaykargo/guvenlik
odeme ve kimlik klasörlerine dokunan her çekme isteği güvenlik ekibinin onayını bekler.

Bulgu kadar, bulguyu nasıl yazdığın da önemlidir. Zayıf bir yorum yalnız bir sorun olduğunu söyler. Geliştirici neyi, neden ve nasıl değiştireceğini bilemez, tartışma da kişisel görüşe döner. İyi bir yorum dört parça taşır: bulgu, etki, somut düzeltme ve referans.

Referans olarak CWE kimliği ve ASVS bölümü yazarsın. Böylece tartışma ortak bir standarda dayanır. Aşağıdaki iki yorum aynı satır için yazıldı.

Zayıf yorum:
  Bu satır güvensiz, düzeltir misin?

İyi yorum:
  Bulgu: /iade/<id> ucu iadenin sahibini denetlemiyor.
  Etki: Oturum açmış her kullanıcı, kimliği değiştirerek başkasının iadesini görür.
  Düzeltme: Sorguya kullanici_id = oturum.kullanici_id koşulunu ekle, eşleşme yoksa 404 dön.
  Referans: CWE-639, ASVS 5.0 V8 Authorization.
Aynı bulgu için iki inceleme yorumu.

Her dilin kendine özgü tuzakları var ve inceleme listesi bunları da taşır. JavaScript'te nesneleri derinlemesine birleştiren fonksiyonlar, __proto__ anahtarıyla prototip kirlenmesine (prototype pollution) açılır. PHP'de == ile yapılan gevşek karşılaştırma, 0e ile başlayıp rakamla süren iki özet değerini eşit sayabilir. Python'da pickle.loads ve güvensiz yükleyiciyle çağrılan yaml.load, güvenilmeyen veriden nesne kurar ve kod çalıştırabilir.

Java'da ObjectInputStream ile yapılan nesne serileştirmesi aynı riski taşır. Araçlar bu çağrıları çoğu zaman işaretler. Verinin güvenilir olup olmadığına karar vermek ise inceleyene kalır.

Etkinlik 4 / 7

Aşağıdaki bulguları, hangi yöntemin daha kolay yakaladığına göre ayır.

Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.

0/4 seçenek yerleşti.

Fark okurken yalnız eklenen satırlara bakma. Silinen bir satır, eklenen bir satır kadar risk taşıyabilir. Kaldırılan bir yetki denetimi ya da güvenli bir çağrının güvensiz kardeşiyle değişmesi, farkta tek bir eksi ve tek bir artı satırı olarak görünür.

Değişikliğin nedenini çekme isteğinin açıklamasında ara, açıklama yoksa sor. Yalnız "düzeltildi" diyen kısa bir açıklama ayrıca dikkat ister. Böyle bir farkta incelemeyi yavaşlat ve her eksi satırın neden gittiğini tek tek sor.

Etkinlik 5 / 7

Altay Kargo'nun ayar servisine bir çekme isteği geldi. Açıklamada yalnız "YAML okuma düzeltildi" yazıyor. Bu farkta inceleyenin durdurması gereken satır hangisi?

Zafiyetli satıra tıkla.

Sızıntıya müdahale

Sızıntı fark edildiğinde ilk iş anahtarı geçersiz kılmaktır. Anahtar geçerli kaldıkça depoyu temizlemek zararı durdurmaz.

Sağlayıcı panelinden ya da sır yöneticisinden eski anahtarı iptal eder, yerine yenisini üretirsin. Bu işleme anahtar döndürme (key rotation) denir. Sonra kapsamı belirlersin: anahtar hangi yetkileri taşıyordu, sağlayıcının erişim kayıtlarında sızıntı tarihinden beri tanımadığın bir adres var mı? Ardından kodu ve gerekiyorsa geçmişi temizlersin.

Son adımda olayı kayda geçirir, ekibe bildirir ve kişisel veri etkilendiyse yasal bildirim yükümlülüğünü değerlendirirsin. Kalıcı çözüm, sırrı koddan tümüyle çıkarmaktır. Anahtar ortam değişkeninden ya da bir sır yöneticisinden okunur, mümkünse kısa ömürlü kimlik bilgisi kullanılır.

Etkinlik 6 / 7

Bir sızıntı olayında doğru tepki sırasını kur.

Sürükleyip doğru sıraya koy.

Bir öğeye odaklan, yukarı ve aşağı ok tuşlarıyla taşı. Home tuşu en üste, End tuşu en alta alır.

  • 1Sızıntının kapsamını belirle: hangi sistemler erişti
  • 2Olayı kaydet ve ekibe bildir
  • 3Anahtarı kod ve geçmişten temizle
  • 4Anahtarı hemen iptal et ve yenisini üret

Altay Kargo, depo servisinin anahtarını sızıntının fark edildiği saatte iptal etti. Erişim kayıtlarında 198.51.100.23 adresinden gelen üç tanımadık istek vardı ve üçü de yalnız okuma yapmıştı. Ekip okunan kayıtları listeledi ve kişisel veri içermediklerini doğruladı.

Yeni anahtar sır yöneticisine kondu. Uygulama artık onu açılışta oradan okuyor ve anahtar doksan günde bir kendiliğinden yenileniyor. Olay kaydı, sonraki tatbikatta senaryo olarak kullanılmak üzere ekibin arşivine girdi.

Etkinlik 7 / 7

Sızan bir anahtarı geçersiz kılıp yerine yenisini üretme işlemine anahtar ____ denir.

Derinleş:Geçmişi yeniden yazmak neden yetmez

Bazen geçmişi temizlemek de gerekir, örneğin depo açık kaynak yapılmadan önce eski bir sır bulunduysa. git filter-repo bu iş için yaygın olarak önerilen araçtır. Belirli bir dizgeyi bütün commit'lerde değiştirebilir ya da bir dosyayı geçmişten tümüyle çıkarabilir.

İşlem bütün commit kimliklerini değiştirir. Ekipteki herkes depoyu yeniden klonlamak zorunda kalır, açık çekme istekleri de bozulur. Barındırma hizmetleri eski commit'leri bir süre önbellekte tutabilir.

Çatallar ve başkalarının klonları ise hiç senin denetiminde değildir. GitHub'ın hassas veriyi depodan kaldırma rehberi de işe sırrı iptal ederek başlamayı önerir. Bu yüzden sıra değişmez: önce döndür, sonra temizle. Geçmiş temizliği sızıntıyı geri almaz, yalnız aynı sırrın yeni birine ulaşma olasılığını azaltır.

Derinleş:ASVS 5.0 neyi kapsar

OWASP Uygulama Güvenliği Doğrulama Standardı (ASVS), bir uygulamanın karşılaması gereken güvenlik gereksinimlerini madde madde yazar. 5.0.0 sürümü Mayıs 2025'te yayımlandı ve gereksinimleri 17 bölüme ayırdı. Bölümler kodlama ve temizleme, doğrulama ve iş mantığı, web ön yüzü, API, dosya işleme, kimlik doğrulama, oturum, yetkilendirme, kendi içinde imzalı jetonlar, OAuth ve OIDC, kriptografi, güvenli iletişim, yapılandırma, veri koruma, güvenli kodlama ve mimari, günlük ve hata yönetimi ile WebRTC'dir.

Her madde üç düzeyden birine bağlıdır. Düzey 1 en temel gereksinimleri, Düzey 3 en yüksek güvence isteyen sistemlerin gereksinimlerini toplar. 4.0 sürümünden geçen ekipler için madde numaraları değişti, bu yüzden eski kontrol listelerini yeni numaralara eşlemek gerekir.

Bu derste bir hata mı gördün? Bildir