Skip to main content
Miraç AĞCABAY
Tüm yazılar
Siber GüvenlikWeb

Web Uygulama Güvenliği: OWASP Top 10'un Derinlerine

15 Mart 2025  ·  10 dk okuma

Her yıl milyonlarca web uygulaması güvenlik açıklarından etkileniyor. Bu açıkların büyük çoğunluğu önlenebilir türde. OWASP (Open Web Application Security Project) Top 10, geliştiricilerin odaklanması gereken kritik riskleri listeler.

A01: Broken Access Control

2021'den bu yana listedeki ilk sıra. Yetkilendirme hataları, kullanıcıların yetkisiz kaynaklara erişmesine izin verir.

// ❌ Güvensiz: Kullanıcı ID'si parametreden alınıyor
app.get("/api/users/:id/profile", async (req, res) => {
  const profile = await db.users.findById(req.params.id);
  res.json(profile);
});
 
// ✅ Güvenli: Oturum açmış kullanıcının kendi profilini doğrula
app.get("/api/users/:id/profile", authenticate, async (req, res) => {
  if (req.user.id !== req.params.id && !req.user.isAdmin) {
    return res.status(403).json({ error: "Forbidden" });
  }
  const profile = await db.users.findById(req.params.id);
  res.json(profile);
});

Temel kural: Her isteği, her seferinde yetkilendirin. Session'a değil, token'a güvenin.

A02: Cryptographic Failures

Hassas verilerin şifresiz veya zayıf algoritmalarla saklanması.

# ❌ MD5 veya SHA-1 ile parola hashleme — kırılabilir
import hashlib
hashed = hashlib.md5(password.encode()).hexdigest()
 
# ❌ bcrypt doğru kullanılmamış — salt rounds çok düşük
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=4))
 
# ✅ Argon2id — OWASP'ın önerdiği modern algoritma
from argon2 import PasswordHasher
ph = PasswordHasher(time_cost=2, memory_cost=65536, parallelism=2)
hashed = ph.hash(password)

Veritabanındaki tüm hassas alanlar (TC kimlik, IBAN, sağlık verileri) AES-256-GCM ile şifrelenmelidir.

A03: Injection

SQL, NoSQL, OS Command, LDAP injection. Hâlâ en yaygın saldırı vektörlerinden biri.

// ❌ SQL Injection'a açık
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Saldırı: email = "' OR '1'='1'; DROP TABLE users;--"
 
// ✅ Parametreli sorgu (Prepared Statement)
const result = await db.query(
  "SELECT * FROM users WHERE email = $1",
  [email]
);
 
// ✅ ORM ile (Prisma/TypeORM otomatik parametre binding yapar)
const user = await prisma.user.findUnique({
  where: { email }, // otomatik olarak güvenli
});

NoSQL injection'a dikkat:

// ❌ MongoDB injection
User.findOne({ email: req.body.email, password: req.body.password });
// Saldırı: { "password": { "$ne": null } }
 
// ✅ Validasyon + schema enforcement
const { email, password } = z.object({
  email: z.string().email(),
  password: z.string().min(8).max(128),
}).parse(req.body);

A05: Security Misconfiguration

Varsayılan yapılandırmalar genellikle güvensizdir.

// ❌ Express'te güvensiz varsayılanlar
app.use(express.json()); // Boyut limiti yok → DoS
app.get("/debug", (req, res) => res.json(process.env)); // Env değişkenleri sızdı!
 
// ✅ Güvenli yapılandırma
import helmet from "helmet";
import rateLimit from "express-rate-limit";
 
app.use(helmet());                            // Security headers
app.use(express.json({ limit: "10kb" }));     // Boyut limiti
app.use(rateLimit({                           // Brute-force koruması
  windowMs: 15 * 60 * 1000,
  max: 100,
}));
 
// Üretimde debug endpoint'leri kapatın
if (process.env.NODE_ENV !== "production") {
  app.use("/debug", debugRouter);
}

A07: Identification and Authentication Failures

Zayıf oturum yönetimi ve kimlik doğrulama açıkları.

// JWT güvenli kullanımı
import jwt from "jsonwebtoken";
 
// ❌ Zayıf: Kısa ömürlü token yok, algoritma belirtilmemiş
const token = jwt.sign({ userId }, secret);
 
// ✅ Güvenli
const accessToken = jwt.sign(
  { userId, iat: Date.now() },
  process.env.JWT_SECRET!,
  {
    algorithm: "RS256",   // Asimetrik — public key doğrulama
    expiresIn: "15m",     // Kısa ömür
    issuer: "myapp.com",
  }
);
 
// Refresh token → rotation + blacklist
const refreshToken = crypto.randomBytes(64).toString("hex");
await db.refreshTokens.create({
  token: await hash(refreshToken),
  userId,
  expiresAt: addDays(new Date(), 30),
});

Güvenlik Testi Araçları

# OWASP ZAP ile otomatik tarama
docker run -t owasp/zap2docker-stable zap-baseline.py \
  -t https://yourtarget.com
 
# Nikto ile web sunucu taraması
nikto -h https://yourtarget.com
 
# SQLMap ile SQL injection testi (yalnızca yetkili sistemlerde!)
sqlmap -u "https://target.com/page?id=1" --dbs

Güvenli Yazılım Geliştirme Kültürü

Güvenlik bir özellik değil, bir kalite göstergesidir. Bu prensipler günlük geliştirme sürecinize entegre edilmeli:

  1. Threat modeling: Her yeni özellik için "Bu nasıl kötüye kullanılabilir?" sorusunu sorun
  2. Dependency audit: npm audit, pip-audit gibi araçları CI/CD'ye ekleyin
  3. Secret management: Gizli bilgileri asla koda gömmeyin — Vault, AWS Secrets Manager kullanın
  4. SAST/DAST: Statik ve dinamik analiz araçlarını geliştirme pipeline'ınıza dahil edin

Güvenlik açıkları çoğunlukla kötü niyet değil, dikkatsizlikten kaynaklanır. Farkındalık, en güçlü savunmadır.