← Blog
·10 blog.minutes

Guvenli Kod Yazma Uygulamalari: Web Gelistiricileri Icin Rehber

Enjeksiyon saldirilari, kimlik dogrulama, yetkilendirme, guvenli konfigurasyon ve bagimlilik yonetimi dahil olmak uzere web uygulamalari icin pratik guvenlik rehberi.

Guvenlik cogu gelistirici icin ikinci plandadir. Bunun nedeni kotu niyet degil, uretim baskisidir. Bir ozelligi zamaninda gondermek, guvenlik acigini kapatmaktan daha acil gorunur. Ancak guvenlik aciklari, bir kez istismar edildiklerinde, en iyi ihtimalle itibar kaybina ve en kotu ihtimalle yasal sonuclara yol acar.

Bu yazi, her web gelistiricisinin bilmesi gereken temel guvenlik uygulamalarini ele aliyor. Amac korku salmak degil, kodunuzu yazarken guvenligi dogal bir refleks haline getirmektir. Her baslik altinda, sorunu, sonuclarini ve cozumu pratik bir sekilde aciklayacagim.

Enjeksiyon saldirilari

Enjeksiyon, bir saldirganin yorumlanacak bir girdiye zararli kod eklemesidir. SQL enjeksiyonu en bilinenidir ancak NoSQL, LDAP, OS komutu ve HTML enjeksiyonu da ayni kategoridedir. Temel sorun, kod ile verinin birbirine karismasidir.

// Vulnerable: string interpolation in SQL
const query = `SELECT * FROM users WHERE id = '${userId}'`;

// Safe: parameterized query
const query = "SELECT * FROM users WHERE id = $1";
const result = await db.query(query, [userId]);

// Also bad: string concatenation for NoSQL
const filter = { username: userInput };  // { $ne: null } can bypass this

// Safe: validate input before using it in queries
if (typeof userInput !== "string") throw new Error("Invalid input");

Enjeksiyonu onlemenin tek guvenli yolu, parametrelendirilmis sorgular (prepared statements) kullanmaktir. Kullanicidan gelen veriyi temizlemek (sanitize) ikinci bir savunma katmanidir ancak birincil cozum degildir. ORM kullaniyorsaniz bile, ORM in sorgu olusturma mekanizmasini anlamaniz ve enjeksiyona acik olmadigindan emin olmaniz gerekir.

Kimlik dogrulama ve yetkilendirme

Kimlik dogrulama (authentication), kullanicinin kim oldugunu dogrulamaktir. Yetkilendirme (authorization), kullanicinin ne yapmasina izin verildigini belirlemektir. Bu iki kavram siklikla birbirine karistirilir ve her ikisi de dogru uygulanmadiginda guvenlik acigina yol acar.

Sifre yonetimi

Sifreler hicbir zaman duz metin olarak saklanmamalıdır. Sifreleri saklamak icin bcrypt, scrypt veya Argon2 gibi bir tuzlama (salting) ve yavas karma (slow hashing) algoritmasi kullanin. SHA-256 gibi hizli hash algoritmalari, sifre kirma saldirilarina karsi korumasizdir.

import bcrypt from "bcrypt";

// Registration: hash the password
const saltRounds = 12;
const hashedPassword = await bcrypt.hash(password, saltRounds);
await db.execute("INSERT INTO users (email, password) VALUES ($1, $2)", [
  email,
  hashedPassword,
]);

// Login: compare with stored hash
const stored = await db.query("SELECT password FROM users WHERE email = $1", [email]);
const match = await bcrypt.compare(password, stored.rows[0].password);
if (!match) throw new Error("Invalid credentials");

Sifre politikasi da onemlidir. Minimum 8 karakter, buyuk harf, kucuk harf, rakkam ve ozel karakter gereksinimleri yaygindir ancak kullanici deneyimini olumsuz etkiler. Daha modern bir yaklasim, minimum 12 karakter ve bir parola yoneticisinin olusturdugu sifrelere izin vermektir.

JWT ve oturum yonetimi

JSON Web Token lari (JWT), kimlik dogrulama icin yaygin bir cozumdur. Ancak JWT kullanirken dikkat edilmesi gereken birkac nokta vardir. Token imzasi icin guclu bir gizli anahtar (en az 256 bit) kullanin. Token suresini sinirli tutun (15-60 dakika erisim token i icin uygundur). Refresh token lari daha uzun omurlu olabilir ancak guvenli bir sekilde saklanmalidir.

JWT nin zayif yonu, gecersiz kilmanin (revoke) zor olmasidir. Bir token calindiginda, token in suresi dolana kadar gecerlidir. Cozum olarak, kara liste (blacklist) kullanabilir veya token suresini kisa tutup refresh token mekanizmasi ile yenileyebilirsiniz.

Guvenli konfigurasyon

Guvenlik aciklarinin onemli bir kismi, yanlis yapilandirilmis sistemlerden kaynaklanir. Varsayilan yapilandirmalar genellikle gelistirme kolayligi icin en guvenli olmayan ayarlarla gelir. Uretim ortamina gecmeden once bu ayarlari degistirmek gerekir.

  • Hata mesajlarinda stack trace gostermeyin. Uretimde tum hatalar, kullaniciya genel bir mesaj gostermeli ve detayli hata bilgisi loglara yazilmalidir.
  • CORS yapilandirmasini mumkun oldugunca dar tutun. Yalnizca guvendiginiz alan adlarina izin verin. Access-Control-Allow-Origin: * kullanmayin.
  • HTTP basliklarini guvenli sekilde yapilandirin: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security.
  • Rate limiting uygulayin. Kullanici basina dakikada belirli sayida istege izin vererek brute force saldirilarini engelleyin.
  • Env dosyalarini (environment variables) versiyon kontrolune eklemeyin. Ornek bir .env.example dosyasi ekleyin ancak gercek secret lari asla commit etmeyin.

Bagimlilik yonetimi

Modern bir web uygulamasi, yuzlerce bagimliliga sahiptir. Bu bagimliliklarin her biri, potansiyel bir guvenlik acigi kaynagidir. Bagimlilik yonetimi, guvenligin en cok ihmal edilen alanlarindan biridir.

Bagimliliklari duzenli olarak tarayin. npm audit, yarn audit, pip audit veya Snyk gibi araclar, bilinen guvenlik aciklarini tespit eder. CI pipeline iniza bu taramayi entegre edin ve yuksek onemli aciklari pipeline i bloke edecek sekilde yapilandirin.

Bagimliliklari guncel tutmak da onemlidir. Ancak her guncelleme, uyumluluk sorunlarina yol acabilir. Bu nedenle, bagimliliklari duzenli olarak (ornegin haftada bir) guncelleyin ve testlerden gecirin. Dependabot veya Renovate gibi araclar, bu sureci otomatiklestirir.

Yaygin guvenlik aciklari

OWASP Top 10, web uygulamalari icin en kritik guvenlik risklerini listeler. Is basvurusu yaparken veya bir projeyi degerlendirirken bu listeyi bilmek faydalidir. Ancak guncel liste degisse de, bazi temel aciklar yillar boyunca ayni kalir.

  • XSS (Cross-Site Scripting): Kullanicidan alinan veriyi dogrudan HTML icine yerlestirmeyin. React, Vue ve diger modern frameworkler, varsayilan olarak XSS e karsi korumalidir ancak dangerouslySetInnerHTML gibi ozellikleri kullanirken dikkatli olun.
  • CSRF (Cross-Site Request Forgery): Form gonderimlerinde CSRF token i kullanin. Modern frameworkler bu token lari otomatik olarak yonetir.
  • IDOR (Insecure Direct Object Reference): Kullanicinin kendine ait olmayan bir kaynaga erisip erisemedigini kontrol edin. /api/users/123/profil gibi bir uca noktada, kullanicinin 123 ID si dahilinde olup olmadigini dogrulayin.
  • SSRF (Server-Side Request Forgery): Sunucunun kullanicidan gelen bir URL ye istek gondermesine izin veriyorsaniz, bu URL nin ic ag adreslerine yonlendirilmediginden emin olun.
  • Open Redirect: Kullanicinin girdigi bir URL ye yonlendirme yapiyorsaniz, bu URL nin guvenilir bir alan adina ait oldugunu dogrulayin.

Guvenlik, bir kere yapilip bitirilecek bir is degildir. Surekli bir suretir ve her yeni ozellikle birlikte guvenligi de dusunmek gerekir. Bu aliskanligi edinmek, bir guvenlik acigini istismar edildikten sonra duzeltmekten cok daha az maliyetlidir.

Guvenlik test araclari

Guvenligi saglamak icin cesitli test araclari kullanabilirsiniz. Statik analiz araclari (SAST), kodu calistirmadan guvenlik aciklarini tespit eder. Dinamik analiz araclari (DAST), calisan bir uygulamayi test eder. Her iki yaklasim da birbirini tamamlar.

  • SAST: SonarQube, ESLint guvenlik kurallari (eslint-plugin-security), Semgrep, CodeQL.
  • DAST: OWASP ZAP, Burp Suite, Acunetix.
  • Bagimlilik taramasi: Snyk, Dependabot, npm audit, Trivy.
  • Secret taramasi: git-secrets, truffleHog, Gitleaks.

Guvenlik, bir urun degil, bir surectir. Kodunuzu yazarken, test ederken ve dagitirken guvenligi dusunmek, saglam ve guvenilir yazilimlar gelistirmenin temelidir.