Web Güvenliği OWASP Top 10 ve Modern Güvenlik Tehditleri

Yunus Emre Güzel
6 Ocak 202515 dkSecurity
Web Güvenliği OWASP Top 10 ve Modern Güvenlik Tehditleri

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

Kaynaklar