Web Güvenliği: OWASP Top 10 ve Modern Güvenlik Tehditleri
Web uygulamalarının güvenliği, modern yazılım geliştirmenin en kritik konularından biridir. Bu yazıda, OWASP Top 10 listesindeki yaygın güvenlik açıklarını inceleyecek ve bunlara karşı koruma yöntemlerini öğreneceğiz.
1. Injection Attacks
Injection saldırıları, kötü niyetli kodun uygulamaya enjekte edilmesiyle gerçekleşir. En yaygın türleri SQL Injection ve XSS'tir.
SQL Injection Örneği ve Korunma
// ❌ Güvensiz kod const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`; // ✅ Parametreli sorgu ile güvenli kod import { pool } from './db' async function authenticateUser(username: string, password: string) { const query = 'SELECT * FROM users WHERE username = $1 AND password = $2' try { const result = await pool.query(query, [username, password]) return result.rows[0] } catch (error) { console.error('Authentication error:', error) throw new Error('Authentication failed') } }
Cross-Site Scripting (XSS) Önleme
// ❌ Güvensiz kod const userInput = '<script>alert("Hack!");</script>'; element.innerHTML = userInput; // ✅ Güvenli kod - DOMPurify kullanımı import DOMPurify from 'dompurify'; function renderUserContent(content: string) { const sanitizedContent = DOMPurify.sanitize(content, { ALLOWED_TAGS: ['p', 'b', 'i', 'em', 'strong'], ALLOWED_ATTR: ['class'] }); element.innerHTML = sanitizedContent; }
2. Broken Authentication
Kimlik doğrulama ve oturum yönetimi hataları, hesap ele geçirme saldırılarına yol açabilir.
Güvenli Password Hashing
import * as bcrypt from 'bcrypt'; async function hashPassword(password: string): Promise<string> { const saltRounds = 12; return bcrypt.hash(password, saltRounds); } async function verifyPassword(password: string, hash: string): Promise<boolean> { return bcrypt.compare(password, hash); } // Kullanım örneği async function createUser(username: string, password: string) { const hashedPassword = await hashPassword(password); // Veritabanına hashedPassword'ü kaydet }
JWT ile Güvenli Oturum Yönetimi
import * as jwt from 'jsonwebtoken'; const JWT_SECRET = process.env.JWT_SECRET!; interface TokenPayload { userId: string; role: string; } function generateToken(payload: TokenPayload): string { return jwt.sign(payload, JWT_SECRET, { expiresIn: '1h', algorithm: 'HS256' }); } function verifyToken(token: string): TokenPayload { try { return jwt.verify(token, JWT_SECRET) as TokenPayload; } catch (error) { throw new Error('Invalid token'); } }
3. Sensitive Data Exposure
Hassas verilerin uygun şekilde şifrelenmemesi veya korunmaması ciddi güvenlik riskleri oluşturur.
Veri Şifreleme Örneği
import { createCipheriv, createDecipheriv, randomBytes } from 'crypto'; class Encryption { private readonly algorithm = 'aes-256-gcm'; private readonly key: Buffer; constructor(secretKey: string) { this.key = Buffer.from(secretKey, 'hex'); } encrypt(text: string): { encryptedData: string; iv: string; authTag: string } { const iv = randomBytes(12); const cipher = createCipheriv(this.algorithm, this.key, iv); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return { encryptedData: encrypted, iv: iv.toString('hex'), authTag: cipher.getAuthTag().toString('hex') }; } decrypt(encrypted: string, iv: string, authTag: string): string { const decipher = createDecipheriv( this.algorithm, this.key, Buffer.from(iv, 'hex') ); decipher.setAuthTag(Buffer.from(authTag, 'hex')); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } }
4. Security Headers ve CSP
Modern web uygulamalarında güvenlik başlıkları ve Content Security Policy kullanımı önemlidir.
Express.js Güvenlik Middleware'leri
import express from 'express'; import helmet from 'helmet'; const app = express(); // Temel güvenlik başlıkları app.use(helmet()); // Özel CSP kuralları app.use( helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:", "https:"], connectSrc: ["'self'", "https://api.example.com"], fontSrc: ["'self'", "https://fonts.gstatic.com"], objectSrc: ["'none'"], mediaSrc: ["'self'"], frameSrc: ["'none'"], }, }) ); // CORS yapılandırması app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'https://trusted-origin.com'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); next(); });
5. Rate Limiting ve Brute Force Protection
API'leri ve kimlik doğrulama endpoint'lerini korumak için rate limiting uygulanmalıdır.
import rateLimit from 'express-rate-limit'; import RedisStore from 'rate-limit-redis'; import Redis from 'ioredis'; const redis = new Redis({ host: 'localhost', port: 6379 }); // API Rate Limiter const apiLimiter = rateLimit({ store: new RedisStore({ sendCommand: (...args: string[]) => redis.call(...args), }), windowMs: 15 * 60 * 1000, // 15 dakika max: 100, // IP başına maksimum istek message: 'Too many requests, please try again later.' }); // Login Rate Limiter const loginLimiter = rateLimit({ store: new RedisStore({ sendCommand: (...args: string[]) => redis.call(...args), }), windowMs: 60 * 60 * 1000, // 1 saat max: 5, // IP başına maksimum login denemesi message: 'Too many login attempts, please try again later.' }); // Kullanım app.use('/api/', apiLimiter); app.post('/login', loginLimiter, loginHandler);
6. Input Validation ve Sanitization
Kullanıcı girdilerinin doğrulanması ve temizlenmesi güvenlik açısından kritiktir.
import { z } from 'zod'; // Validation şeması const UserSchema = z.object({ username: z.string() .min(3, 'Username must be at least 3 characters') .max(50, 'Username must be at most 50 characters') .regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers and underscore'), email: z.string() .email('Invalid email address') .toLowerCase(), password: z.string() .min(8, 'Password must be at least 8 characters') .regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/, 'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character') }); // Kullanım örneği async function createUser(userData: unknown) { try { const validatedData = UserSchema.parse(userData); // Veritabanına kaydet return await db.users.create(validatedData); } catch (error) { if (error instanceof z.ZodError) { throw new Error(`Validation error: ${error.errors.map(e => e.message).join(', ')}`); } throw error; } }
Sonuç
Web güvenliği, sürekli gelişen ve değişen bir alandır. Önemli noktalar:
- Güvenliği geliştirme sürecinin başından itibaren düşünün
- OWASP güncellemelerini takip edin
- Düzenli güvenlik testleri yapın
- Üçüncü parti kütüphaneleri güncel tutun
- Güvenlik açıklarını ciddiye alın ve hızlıca müdahale edin
İlgili Etiketler: #WebSecurity #OWASP #Cybersecurity #Authentication #Encryption #SecurityHeaders #InputValidation