- Sunucu tarafında izin listesine dayalı girdi doğrulaması yazmak
- En az yetki ilkesini veri tabanlarına ve hizmetlere uygulamak
- Sırları koddan çıkarmak ve bir sızıntıdan sonra doğru davranmak
- CVE, CVSS ve bağımlılık denetimi araçlarını anlamak
Zafiyetlerin çoğu egzotik hilelerden değil, sıradan programcı alışkanlıklarından doğar: girdiye güvenmek, bir hizmeti yönetici yetkisiyle çalıştırmak, bir parolayı Git deposuna yazmak, üç yıldır güncellenmemiş bir kütüphane. Bu derste kodunu her gün daha güvenli yapan dört alışkanlığı öğreneceksin.
1. Girdi doğrulama: izin listesi
Her girdi güvenilmezdir: formlar, URL parametreleri, başlıklar, çerezler, yüklenen dosyalar, hatta kendi mobil uygulamandan gelen istekler (değiştirilebilirler). Doğrulama sunucuda yapılmalıdır; tarayıcıdaki kontroller yalnızca kullanıcının rahatlığı içindir. Türü, uzunluğu, aralığı ve biçimi kontrol et; kötü karakterleri aramak yerine neyin geçerli olduğunu tanımla.
BAD = ['<script>', 'DROP TABLE', '--']
def is_safe(text):
return not any(bad in text for bad in BAD)
is_safe('<SCRIPT>') # True - uppercase slips throughimport re
def is_valid_username(text):
return re.fullmatch(r'[a-z0-9_]{3,16}', text) is not None
is_valid_username('<SCRIPT>') # Falseimport re
USERNAME = re.compile(r'[a-z0-9_]{3,16}')
def validate_signup(username, age):
errors = []
if not USERNAME.fullmatch(username):
errors.append('username: 3-16 of a-z 0-9 _')
if not (type(age) is int and 10 <= age <= 120):
errors.append('age: whole number 10-120')
return errors or ['OK']
for username, age in [('aysel_07', 15), ('Murad!', 16), ('elvin', -3), ('x', 200)]:
print(username.ljust(9), validate_signup(username, age))▸ Beklenen çıktı
aysel_07 ['OK'] Murad! ['username: 3-16 of a-z 0-9 _'] elvin ['age: whole number 10-120'] x ['username: 3-16 of a-z 0-9 _', 'age: whole number 10-120']
fullmatch, dizenin tamamının biçime uymasını ister.2. En az yetki ilkesi
Her kullanıcı, süreç ve hizmet yalnızca işi için gereken yetkileri ve yalnızca gerektiği süre boyunca almalıdır. Bir web uygulamasının veri tabanı hesabı yönetici olmamalı, hizmetler root ya da Administrator olarak çalışmamalı, yönetim işleri için ayrı bir hesap olmalıdır. Uygulama ele geçirilse bile hasar yarıçapı küçük kalır.
GRANT ALL PRIVILEGES ON *.* TO 'shop_app'@'%';GRANT SELECT, INSERT, UPDATE ON shop.orders TO 'shop_app'@'10.0.0.%';
GRANT SELECT ON shop.products TO 'shop_app'@'10.0.0.%';DROP DATABASE çalıştıramaz ya da başka veri tabanlarını okuyamaz, çünkü bu yetkiler ona hiç verilmedi.Bu ilkenin iki yakın “akrabası” vardır. Güvenli varsayılanlar: yeni bir hesap, dosya ya da API anahtarı başta hiçbir şeye izin vermez, yetkiler sonradan bilinçli olarak eklenir. Kapalı konumda kalmak (fail closed): bir kontrol hatayla biterse, örneğin yetkilendirme sunucusu yanıt vermezse, kod isteği “ne olur ne olmaz” diye geçirmek yerine erişimi reddetmelidir.
3. Sırların yönetimi
Parolalar, API anahtarları, belirteçler ve gizli anahtarlar asla kodda saklanmaz. Git geçmişi silinmiş dosyaları bile sonsuza dek hatırlar ve botlar herkese açık depolarda anahtar arar. Sırları ortam değişkenlerinde ya da bir sır yöneticisinde (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) tut, .env dosyasını .gitignore'a ekle ve commit'ten önce bir sır tarayıcısı (örneğin gitleaks) çalıştır.
DB_PASSWORD = 'Baku2024!' # now in Git history forever
connect(user='shop_app', password=DB_PASSWORD)import os
DB_PASSWORD = os.environ['DB_PASSWORD'] # set by the server or a secrets manager
connect(user='shop_app', password=DB_PASSWORD)4. Bağımlılıklardaki zafiyetler
Modern bir uygulamanın kodunun büyük kısmı başkalarının kütüphaneleridir. Bilinen bir zafiyet bir CVE kimliği ve bir CVSS puanı (0–10) alır. npm audit, pip-audit, Dependabot ve OWASP Dependency-Check gibi araçlar bağımlılıklarını bu veri tabanlarıyla karşılaştırır. Kilit dosyaları (package-lock.json, poetry.lock) tam sürümleri sabitler, bir SBOM ise tüm bileşenleri listeler. Popüler paketlere benzer adlı sahte paketlere (typosquatting) de dikkat et.
| CVSS puanı | Önem derecesi | Ne yapmalı |
|---|---|---|
| 0,1–3,9 | Düşük | bir sonraki planlı güncellemede düzelt |
| 4,0–6,9 | Orta | birkaç hafta içinde düzelt |
| 7,0–8,9 | Yüksek | öncelik ver, birkaç gün içinde düzelt |
| 9,0–10,0 | Kritik | hemen güncelle ya da geçici bir önlem uygula |
# JavaScript project: check dependencies against known vulnerabilities
npm audit
# Python project
pip install pip-audit
pip-auditBir sipariş formundaki “miktar” alanı için is_valid_quantity(text) fonksiyonunu yaz: yalnızca 1'den 99'a kadar bir tam sayıyı gösteren dizeler ([0-9] rakamları, 1–2 karakter) True döndürsün. Boşluk, eksi işareti, 5e3 ve ² gibi karakterler reddedilmeli ve fonksiyon asla çökmemelidir.
import re
def is_valid_quantity(text):
# allow-list: 1-2 ASCII digits, value 1..99
return False
for value in ['3', '99', '0', '100', '-1', ' 7', '5e3', '²']:
print(repr(value), is_valid_quantity(value))▸ Beklenen çıktı
'3' True '99' True '0' False '100' False '-1' False ' 7' False '5e3' False '²' False
Önemli noktalar
- Her girdiyi sunucuda izin listesiyle doğrula: tür, uzunluk, aralık, biçim.
- Doğrulama, parametreli sorguların ve kaçışlamanın yerini tutmaz.
- En az yetki, ele geçirilen bir bileşenin verebileceği zararı sınırlar.
- Sırlar kodda değil, ortamda ya da bir sır yöneticisinde tutulur; sızan sır hemen değiştirilir.
- Bağımlılıkları denetim araçlarıyla kontrol et, CVSS puanına göre önceliklendir ve bir SBOM tut.
Kendini test et
10 soru. Her doğru cevap XP kazandırır.