Web Güvenliği ve Modern Siber Tehditler 2024
Web uygulamalarının güvenliği, modern yazılım geliştirmenin en kritik konularından biridir. Günümüzde siber saldırılar giderek daha karmaşık hale geliyor ve her geçen gün yeni güvenlik tehditleri ortaya çıkıyor. Bu makalede, en yaygın siber tehditleri, bunların nasıl çalıştığını ve bu tehditlere karşı nasıl önlemler alabileceğimizi detaylıca inceleyeceğiz.
Modern Web Güvenlik Tehditleri
Modern web uygulamaları, çeşitli güvenlik tehditleriyle karşı karşıyadır. Bu tehditler, kullanıcı verilerinin çalınmasından, sistemlerin ele geçirilmesine kadar geniş bir yelpazede yer alır.
1. Cross-Site Scripting (XSS)
XSS saldırıları, web uygulamalarında en yaygın güvenlik açıklarından biridir. Bu saldırı türünde, saldırganlar zararlı JavaScript kodlarını web sayfalarına enjekte ederek kullanıcıların:
- Oturum bilgilerini çalabilir
- Hassas verilerini ele geçirebilir
- Tarayıcılarını manipüle edebilir
- Kötü amaçlı yazılımları yükleyebilir
XSS saldırılarının üç ana türü vardır:
- Stored XSS: Zararlı kod veritabanında saklanır ve diğer kullanıcılara gösterilir
- Reflected XSS: Zararlı kod URL parametreleri üzerinden yansıtılır
- DOM-based XSS: Saldırı client-side JavaScript üzerinden gerçekleştirilir
// Güvensiz kod örneği - XSS'e açık const userInput = "<script>alert('XSS!')</script>"; document.getElementById('content').innerHTML = userInput; // Güvenli kod örneği - DOMPurify ile sanitization import DOMPurify from 'dompurify'; const userInput = "<script>alert('XSS!')</script>"; const sanitizedInput = DOMPurify.sanitize(userInput); document.getElementById('content').innerHTML = sanitizedInput; // DOMPurify, HTML içeriğini güvenli bir şekilde temizler: // - Tehlikeli HTML etiketlerini kaldırır // - Zararlı JavaScript kodlarını temizler // - XSS açıklarını önler
2. SQL Injection
SQL Injection, veritabanı sorgularına zararlı kod enjekte ederek gerçekleştirilen bir saldırı türüdür. Bu saldırılar şu riskleri taşır:
- Veritabanındaki hassas verilerin sızdırılması
- Veritabanı tablolarının silinmesi veya değiştirilmesi
- Yetkisiz erişim sağlanması
- Sistem komutlarının çalıştırılması
SQL Injection saldırılarına karşı en etkili önlemler:
- Prepared Statements kullanımı
- ORM (Object-Relational Mapping) kullanımı
- Input validation ve sanitization
- En az yetki prensibi
// Güvensiz kod örneği - SQL Injection'a açık const query = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`; // Saldırgan input: username = "admin'--" // Bu durumda password kontrolü bypass edilir // Güvenli kod örneği - Prepared Statements import { pool } from './database'; async function getUser(username: string, password: string) { // Parametreli sorgu kullanımı const query = 'SELECT * FROM users WHERE username = $1 AND password = $2'; const values = [username, password]; try { const result = await pool.query(query, values); return result.rows[0]; } catch (error) { console.error('Database error:', error); throw error; } } // Prepared Statements'ın avantajları: // 1. Sorgu ve veriler ayrı işlenir // 2. SQL injection saldırıları önlenir // 3. Sorgu önbelleğe alınabilir // 4. Performans artışı sağlanır
Modern Güvenlik Önlemleri
Modern web uygulamalarında güvenlik, katmanlı bir yaklaşım gerektirir. Her katmanda farklı güvenlik önlemleri uygulanmalıdır.
1. Security Headers
HTTP Security Headers, web uygulamalarının güvenliğini artırmak için tarayıcılara talimatlar veren başlıklardır. Bu başlıklar:
- XSS saldırılarını önler
- Clickjacking'i engeller
- MIME-type sniffing'i kontrol eder
- SSL/TLS güvenliğini artırır
- Kaynakların yüklenmesini kontrol eder
// Express.js güvenlik başlıkları örneği import helmet from 'helmet'; import express from 'express'; const app = express(); app.use(helmet({ // Content Security Policy (CSP) // Hangi kaynakların yüklenebileceğini belirler contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], // Sadece aynı origin'den kaynak yükleme scriptSrc: ["'self'", "'unsafe-inline'"], // Script kaynaklarını kısıtlama styleSrc: ["'self'", "'unsafe-inline'"], // Style kaynaklarını kısıtlama imgSrc: ["'self'", "data:", "https:"], // Resim kaynaklarını kısıtlama }, }, // Cross-Origin politikaları crossOriginEmbedderPolicy: true, // Cross-origin kaynakları kontrol eder crossOriginOpenerPolicy: true, // Popup'ları kontrol eder crossOriginResourcePolicy: { policy: "cross-origin" }, // Kaynakların paylaşımını kontrol eder // Diğer güvenlik başlıkları dnsPrefetchControl: true, // DNS prefetch'i kontrol eder frameguard: { action: "deny" }, // Clickjacking koruması hidePoweredBy: true, // X-Powered-By başlığını gizler hsts: true, // HTTPS kullanımını zorunlu kılar ieNoOpen: true, // IE'de dosya indirme davranışını kontrol eder noSniff: true, // MIME-type sniffing'i engeller referrerPolicy: { policy: "strict-origin-when-cross-origin" }, // Referrer bilgisini kontrol eder xssFilter: true, // XSS koruması sağlar }));
2. Authentication ve Authorization
Güvenli kimlik doğrulama ve yetkilendirme, modern web uygulamalarının temel gereksinimleridir. JWT (JSON Web Token) kullanımı, stateless authentication sağlar ve microservice mimarilerde yaygın olarak kullanılır.
JWT'nin avantajları:
- Stateless authentication
- Kolay ölçeklenebilirlik
- Cross-domain authentication desteği
- Düşük sunucu yükü
// JWT Authentication örneği import jwt from 'jsonwebtoken'; interface TokenPayload { userId: string; role: string; } class AuthService { private readonly SECRET_KEY = process.env.JWT_SECRET!; // Token oluşturma generateToken(payload: TokenPayload): string { return jwt.sign(payload, this.SECRET_KEY, { expiresIn: '1h', // Token geçerlilik süresi algorithm: 'HS256' // İmzalama algoritması }); } // Token doğrulama verifyToken(token: string): TokenPayload { try { return jwt.verify(token, this.SECRET_KEY) as TokenPayload; } catch (error) { throw new Error('Invalid token'); } } } // Role tabanlı yetkilendirme middleware'i const authorize = (allowedRoles: string[]) => { return (req: Request, res: Response, next: NextFunction) => { // Token'ı Bearer header'dan al const token = req.headers.authorization?.split(' ')[1]; if (!token) { return res.status(401).json({ message: 'No token provided' }); } try { const authService = new AuthService(); const payload = authService.verifyToken(token); // Rol kontrolü if (!allowedRoles.includes(payload.role)) { return res.status(403).json({ message: 'Insufficient permissions' }); } next(); } catch (error) { return res.status(401).json({ message: 'Invalid token' }); } }; }; // Middleware kullanım örneği: // app.get('/admin', authorize(['admin']), adminController); // app.get('/user', authorize(['user', 'admin']), userController);
OWASP Top 10 ve Güvenlik Pratikleri
OWASP (Open Web Application Security Project), web uygulama güvenliği konusunda en önemli kaynaklardan biridir. OWASP Top 10, en kritik web uygulama güvenlik risklerini listeler.
1. Input Validation
Kullanıcı girdilerinin doğrulanması, güvenli bir web uygulaması için kritik öneme sahiptir. Zod gibi type-safe validation kütüphaneleri kullanarak:
- Veri formatını kontrol edebilir
- Güvenlik kurallarını uygulayabilir
- Runtime type safety sağlayabilir
- Validation hatalarını yönetebilirsiniz
// Input validation örneği - Zod ile type-safe validation import { z } from 'zod'; // Kullanıcı şeması tanımlama const UserSchema = z.object({ // Username validasyonu username: z.string() .min(3, 'Username must be at least 3 characters') .max(50, 'Username must not exceed 50 characters') .regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers and underscore'), // Email validasyonu email: z.string() .email('Invalid email format') .toLowerCase(), // Güçlü parola politikası 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' ) }); // Validation kullanımı async function createUser(userData: unknown) { try { // Runtime type checking ve validation const validatedData = UserSchema.parse(userData); // Validated data ile işlem yapılabilir return await saveUser(validatedData); } catch (error) { // Validation hatalarını yönetme if (error instanceof z.ZodError) { throw new Error(`Validation error: ${error.errors.map(e => e.message).join(', ')}`); } throw error; } }
2. Rate Limiting
Rate limiting, API'leri DDoS saldırılarından ve kötüye kullanımdan korumak için kritik bir güvenlik önlemidir. Rate limiting ile:
- Brute force saldırılarını önleyebilir
- API kaynaklarını koruyabilir
- Servis kalitesini artırabilir
- Maliyetleri kontrol edebilirsiniz
// Rate limiting örneği - Redis ile distributed rate limiting import rateLimit from 'express-rate-limit'; import RedisStore from 'rate-limit-redis'; import Redis from 'ioredis'; // Redis bağlantısı const redis = new Redis({ host: process.env.REDIS_HOST, port: Number(process.env.REDIS_PORT), password: process.env.REDIS_PASSWORD }); // Rate limiter konfigürasyonu const limiter = rateLimit({ store: new RedisStore({ sendCommand: (...args: string[]) => redis.call(...args), }), windowMs: 15 * 60 * 1000, // 15 dakikalık pencere max: 100, // IP başına maksimum istek sayısı message: 'Too many requests from this IP, please try again later.', standardHeaders: true, // RateLimit headers legacyHeaders: false, }); // Rate limiting middleware'ini API rotalarına uygulama app.use('/api/', limiter); // Özel rate limiting örnekleri: // Login için daha sıkı limit const loginLimiter = rateLimit({ windowMs: 60 * 60 * 1000, // 1 saat max: 5, // 5 başarısız deneme message: 'Too many login attempts, please try again later' }); app.use('/api/login', loginLimiter);
Güvenlik Testleri ve Monitoring
Güvenlik testleri, uygulamanızın güvenlik açıklarını proaktif olarak tespit etmenizi sağlar. Düzenli güvenlik testleri ile:
- Güvenlik açıklarını erken tespit edebilir
- Güvenlik önlemlerinin etkinliğini ölçebilir
- Uyum gereksinimlerini karşılayabilir
- Güvenlik seviyesini sürekli iyileştirebilirsiniz
1. Security Testing
Otomatize güvenlik testleri, güvenlik açıklarını sürekli olarak kontrol etmenizi sağlar:
// Jest ile güvenlik testi örnekleri describe('Security Tests', () => { // XSS koruması testi it('should properly sanitize user input', () => { const maliciousInput = '<script>alert("XSS")</script>'; const sanitizedOutput = sanitizeInput(maliciousInput); // XSS payload'ının temizlendiğini kontrol et expect(sanitizedOutput).not.toContain('<script>'); expect(sanitizedOutput).not.toContain('</script>'); }); // Parola politikası testi it('should enforce password policy', () => { const weakPassword = 'password123'; const strongPassword = 'P@ssw0rd123!'; // Zayıf ve güçlü parolaları test et expect(isPasswordStrong(weakPassword)).toBeFalsy(); expect(isPasswordStrong(strongPassword)).toBeTruthy(); }); // CSRF token testi it('should validate CSRF token', () => { const validToken = generateCSRFToken(); const invalidToken = 'invalid-token'; expect(validateCSRFToken(validToken)).toBeTruthy(); expect(validateCSRFToken(invalidToken)).toBeFalsy(); }); });
Sonuç
Web güvenliği, sürekli gelişen ve değişen bir alandır. Modern web uygulamalarının güvenliğini sağlamak için aşağıdaki adımları takip etmelisiniz:
Güncel Güvenlik Tehditlerini Takip Edin
- OWASP Top 10 listesini düzenli olarak inceleyin
- Güvenlik bültenlerini takip edin
- Yeni güvenlik açıklarından haberdar olun
OWASP Güvenlik Prensiplerini Uygulayın
- Defense in depth stratejisi kullanın
- Least privilege prensibini uygulayın
- Input validation ve sanitization yapın
- Güvenli varsayılan ayarlar kullanın
Düzenli Güvenlik Testleri Yapın
- Otomatize güvenlik testleri oluşturun
- Penetrasyon testleri yaptırın
- Güvenlik açıklarını düzenli kontrol edin
Güvenlik Güncellemelerini Takip Edin
- Dependency güvenlik açıklarını kontrol edin
- Güvenlik yamalarını hızlıca uygulayın
- Güvenlik araçlarını güncel tutun
Kullanıcı Verilerini Koruyun
- Hassas verileri şifreleyin
- Güvenli iletişim protokolleri kullanın
- Veri sızıntılarına karşı önlem alın
Bu önlemleri uygulamak, uygulamanızı ve kullanıcılarınızı modern siber tehditlerden korumak için kritik öneme sahiptir. Güvenlik, sürekli bir süreçtir ve düzenli olarak gözden geçirilmeli ve güncellenmelidir.