Security

Marketplace Güvenlik ve Uyumluluk

E-ticaret güvenliği, KVKK, PCI-DSS, SSL/TLS. SQL injection, XSS, CSRF önlemleri, fraud prevention, DDoS koruması ve penetration testing.

🔒Güvenlik Katmanları

E-ticaret güvenliği, veri sızıntısı, fraud ve siber saldırılara karşı çok katmanlı koruma gerektirir. Bir güvenlik ihlali ortalama 3.2M TL zarara yol açar.

Network Security

• SSL/TLS (HTTPS)
• Firewall (WAF)
• DDoS koruması
• VPN, IP whitelisting

Application Security

• SQL Injection önleme
• XSS, CSRF koruması
• Input validation
• Secure authentication

Data Security

• Encryption (AES-256)
• Database encryption
• Secure backups
• KVKK compliance

OWASP Top 10 Önlemleri

# 1. SQL Injection Önleme (Prepared Statements)
# ❌ YANLIŞ (SQL Injection riski)
query = f"SELECT * FROM users WHERE email = '{email}'"
# Saldırgan: email = "' OR '1'='1" → Tüm kullanıcıları döner

# ✅ DOĞRU (Prepared Statement)
import psycopg2

conn = psycopg2.connect(database="marketplace")
cursor = conn.cursor()

# Parameterized query
cursor.execute(
    "SELECT * FROM users WHERE email = %s",
    (email,)  # Parametre tuple olarak
)

# ORM kullanımı (daha güvenli)
from sqlalchemy import create_engine, text

engine = create_engine('postgresql://user:pass@localhost/db')
with engine.connect() as conn:
    result = conn.execute(
        text("SELECT * FROM users WHERE email = :email"),
        {"email": email}
    )

# 2. XSS (Cross-Site Scripting) Önleme
from html import escape
from markupsafe import Markup

# ❌ YANLIŞ
user_comment = request.form['comment']
html = f"<div>{user_comment}</div>"  # XSS riski!
# Saldırgan: <script>alert('XSS')</script>

# ✅ DOĞRU
user_comment = escape(request.form['comment'])  # HTML encode
html = f"<div>{user_comment}</div>"

# React/Next.js otomatik escape yapar
# <div>{userComment}</div>  // Safe

# Sadece güvenilir içerik için:
# <div dangerouslySetInnerHTML={{__html: trustedHtml}} />

# 3. CSRF (Cross-Site Request Forgery) Önleme
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
csrf = CSRFProtect(app)

@app.route('/transfer-money', methods=['POST'])
@csrf.exempt  # Sadece API endpoint'leri için
def transfer():
    # CSRF token otomatik kontrol edilir
    amount = request.form['amount']
    # ...

# Next.js API Route
import { getServerSession } from 'next-auth';

export async function POST(request: Request) {
    const session = await getServerSession();

    // CSRF koruması: Origin header kontrolü
    const origin = request.headers.get('origin');
    if (origin !== process.env.NEXT_PUBLIC_URL) {
        return new Response('Invalid origin', { status: 403 });
    }

    // İşlem...
}

# 4. Broken Authentication Önleme
import bcrypt
import jwt
from datetime import datetime, timedelta

# Password hashing (bcrypt)
def hash_password(password):
    salt = bcrypt.gensalt(rounds=12)  # Cost factor (yüksek = yavaş = güvenli)
    hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
    return hashed

def verify_password(password, hashed):
    return bcrypt.checkpw(password.encode('utf-8'), hashed)

# JWT ile session yönetimi
SECRET_KEY = "your-very-secret-key-min-32-chars"

def create_token(user_id):
    payload = {
        'user_id': user_id,
        'exp': datetime.utcnow() + timedelta(hours=24),
        'iat': datetime.utcnow()
    }
    token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
    return token

def verify_token(token):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
        return payload['user_id']
    except jwt.ExpiredSignatureError:
        return None  # Token expired
    except jwt.InvalidTokenError:
        return None  # Invalid token

# 5. Security Misconfiguration Önleme
# Hassas bilgileri .env dosyasında tut
import os
from dotenv import load_dotenv

load_dotenv()

DATABASE_URL = os.getenv('DATABASE_URL')
SECRET_KEY = os.getenv('SECRET_KEY')
API_KEY = os.getenv('API_KEY')

# .env dosyası .gitignore'a ekle!
# .env.example oluştur (değerler olmadan)

# Production ayarları
if os.getenv('ENVIRONMENT') == 'production':
    DEBUG = False
    ALLOWED_HOSTS = ['yourdomain.com']
else:
    DEBUG = True
    ALLOWED_HOSTS = ['localhost', '127.0.0.1']

PCI-DSS Compliance (Ödeme Güvenliği)

PCI-DSS 12 Gereksinimi:

1. Firewall: Kart verilerini koruyacak firewall kullan
2. Varsayılan şifreler: Sistem varsayılan şifrelerini değiştir
3. Veri saklama: Kart verilerini saklamayı minimize et
4. Şifreleme: Kart verileri açık networklerde şifrelensin
5. Anti-virus: Güncel anti-virus/anti-malware kullan
6. Secure systems: Güvenli sistem ve uygulamalar geliştir
7. Access control: İş ihtiyacına göre erişim kısıtla
8. Unique ID: Her kullanıcıya benzersiz ID
9. Physical access: Kart verilerine fiziksel erişimi kısıtla
10. Logging: Tüm erişimleri logla ve izle
11. Testing: Düzenli güvenlik testleri yap
12. Policy: Bilgi güvenliği politikası oluştur
# PCI-DSS: Kart bilgileri ASLA saklanmamalı!
# Tokenization kullan (iyzico, stripe vb.)

# ❌ YANLIŞ - ASLA YAPMA!
credit_card = {
    'number': '4111111111111111',
    'cvv': '123',
    'expiry': '12/26'
}
db.save(credit_card)  # PCI-DSS ihlali!

# ✅ DOĞRU - Tokenization
import requests

# 1. Kart bilgilerini payment gateway'e gönder
response = requests.post('https://api.iyzico.com/payment/tokenize', {
    'card_number': '4111111111111111',
    'cvv': '123',
    'expiry_month': '12',
    'expiry_year': '26'
})

card_token = response.json()['token']  # "tok_1a2b3c4d"

# 2. Sadece token'ı sakla
db.save({
    'user_id': user_id,
    'card_token': card_token,  # Gerçek kart bilgisi yok!
    'last_4_digits': '1111',  # Son 4 hane (display için)
    'card_brand': 'Visa'
})

# 3. Ödeme yaparken token'ı kullan
payment = requests.post('https://api.iyzico.com/payment/charge', {
    'token': card_token,
    'amount': 10000,  # 100 TL
    'currency': 'TRY'
})

KVKK (GDPR) Uyumluluğu

# KVKK Gereksinimleri
# 1. Açık rıza (Explicit consent)
# 2. Veri minimizasyonu (sadece gerekli veriyi topla)
# 3. Veri taşınabilirliği (kullanıcı verilerini export edebilmeli)
# 4. Unutulma hakkı (kullanıcı verilerini sildirebilmeli)
# 5. Veri güvenliği (encryption, access control)

# Consent Management
from datetime import datetime

class ConsentManager:
    CONSENT_TYPES = [
        'marketing_email',
        'marketing_sms',
        'data_processing',
        'third_party_sharing'
    ]

    @staticmethod
    def record_consent(user_id, consent_type, granted=True):
        """Kullanıcı rızasını kaydet"""
        db.consents.insert({
            'user_id': user_id,
            'consent_type': consent_type,
            'granted': granted,
            'timestamp': datetime.utcnow(),
            'ip_address': request.remote_addr,
            'user_agent': request.headers.get('User-Agent')
        })

    @staticmethod
    def has_consent(user_id, consent_type):
        """Rıza var mı kontrol et"""
        consent = db.consents.find_one({
            'user_id': user_id,
            'consent_type': consent_type
        }, sort=[('timestamp', -1)])  # En son rıza

        return consent and consent['granted']

# Kullanım
if ConsentManager.has_consent(user_id, 'marketing_email'):
    send_marketing_email(user)
else:
    # Rıza yok, email gönderme!
    pass

# Unutulma hakkı (Right to be Forgotten)
@app.route('/api/user/delete-account', methods=['POST'])
def delete_account():
    user_id = get_current_user_id()

    # 1. Kişisel verileri sil/anonimleştir
    db.users.update_one(
        {'_id': user_id},
        {'$set': {
            'name': '[DELETED]',
            'email': f'deleted_{user_id}@anonymized.com',
            'phone': None,
            'address': None,
            'deleted_at': datetime.utcnow()
        }}
    )

    # 2. İlişkili verileri temizle
    db.orders.update_many(
        {'user_id': user_id},
        {'$set': {'user_name': '[DELETED USER]'}}
    )

    # 3. Yasal olarak saklamak zorunda olduğun verileri tut
    # (faturalar, 10 yıl saklanmalı)
    # Sadece anonimleştir

    # 4. Audit log
    log_data_deletion(user_id, reason='user_request')

    return jsonify({'success': True})

# Veri taşınabilirliği (Data Portability)
@app.route('/api/user/export-data', methods=['GET'])
def export_user_data():
    user_id = get_current_user_id()

    # Tüm kullanıcı verilerini topla
    user_data = {
        'personal_info': db.users.find_one({'_id': user_id}),
        'orders': list(db.orders.find({'user_id': user_id})),
        'addresses': list(db.addresses.find({'user_id': user_id})),
        'payment_methods': list(db.payment_methods.find({'user_id': user_id})),
        'reviews': list(db.reviews.find({'user_id': user_id})),
        'consents': list(db.consents.find({'user_id': user_id}))
    }

    # JSON olarak export
    import json
    json_data = json.dumps(user_data, default=str, indent=2)

    return Response(
        json_data,
        mimetype='application/json',
        headers={
            'Content-Disposition': f'attachment; filename=user_data_{user_id}.json'
        }
    )

DDoS Koruması ve Rate Limiting

# Rate Limiting (Flask + Redis)
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
import redis

redis_client = redis.Redis(host='localhost', port=6379)

limiter = Limiter(
    app,
    key_func=get_remote_address,
    storage_uri="redis://localhost:6379"
)

# API endpoint rate limit
@app.route('/api/products')
@limiter.limit("100 per minute")  # Max 100 istek/dakika
def get_products():
    return jsonify(products)

# Login brute force koruması
@app.route('/api/login', methods=['POST'])
@limiter.limit("5 per minute")  # Max 5 deneme/dakika
def login():
    # ...
    pass

# Next.js Middleware (Edge)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const rateLimitMap = new Map<string, number[]>();

export function middleware(request: NextRequest) {
    const ip = request.ip ?? 'unknown';
    const now = Date.now();
    const windowMs = 60000;  // 1 dakika
    const maxRequests = 100;

    if (!rateLimitMap.has(ip)) {
        rateLimitMap.set(ip, []);
    }

    const requests = rateLimitMap.get(ip)!;

    // Eski istekleri temizle
    const validRequests = requests.filter(time => now - time < windowMs);

    if (validRequests.length >= maxRequests) {
        return new NextResponse('Too Many Requests', { status: 429 });
    }

    validRequests.push(now);
    rateLimitMap.set(ip, validRequests);

    return NextResponse.next();
}

# Cloudflare DDoS koruması (önerilen)
# - Auto DDoS mitigation
# - Rate limiting rules
# - Bot management
# - WAF (Web Application Firewall)

Security Headers

# Next.js Security Headers
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff'
          },
          {
            key: 'X-Frame-Options',
            value: 'DENY'  // Clickjacking önleme
          },
          {
            key: 'X-XSS-Protection',
            value: '1; mode=block'
          },
          {
            key: 'Strict-Transport-Security',
            value: 'max-age=31536000; includeSubDomains'  // HTTPS zorunlu
          },
          {
            key: 'Content-Security-Policy',
            value: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
          },
          {
            key: 'Referrer-Policy',
            value: 'strict-origin-when-cross-origin'
          },
          {
            key: 'Permissions-Policy',
            value: 'geolocation=(), microphone=(), camera=()'
          }
        ]
      }
    ];
  }
};

# Flask Security Headers
from flask import Flask
from flask_talisman import Talisman

app = Flask(__name__)

# HTTPS zorunlu + security headers
Talisman(app,
    force_https=True,
    strict_transport_security=True,
    content_security_policy={
        'default-src': "'self'",
        'script-src': ["'self'", 'cdn.example.com'],
        'style-src': ["'self'", "'unsafe-inline'"]
    }
)

Penetration Testing ve Monitoring

Düzenli Güvenlik Testleri:

Automated scanning: OWASP ZAP, Burp Suite (haftalık)
Penetration testing: Profesyonel pentest (yılda 2 kez)
Vulnerability scanning: Nessus, Qualys (aylık)
Dependency check: npm audit, Snyk (her deploy)
Code review: SonarQube, CodeQL (her PR)

Security Monitoring:

SIEM: Splunk, ELK Stack - log analizi
IDS/IPS: Snort, Suricata - saldırı tespiti
Uptime monitoring: UptimeRobot, Pingdom
Error tracking: Sentry, Rollbar
Incident response: 7/24 alert sistemi

Güvenlik Maliyeti ve ROI

Security Investment

3.2M TL
Ortalama Veri İhlali Maliyeti
120 gün
İhlal Tespit Süresi (ort.)
%45
Müşteri Kaybı (ihlal sonrası)

Örnek Güvenlik Bütçesi (Orta Boy E-Ticaret):

SSL/TLS sertifika: 5K TL/yıl
WAF (Cloudflare): 30K TL/yıl
Penetration test: 40K TL (2x/yıl)
SIEM/Monitoring: 60K TL/yıl
Cyber insurance: 50K TL/yıl
Security engineer: 300K TL/yıl (maaş)
Toplam: ~485K TL/yıl
ROI: Bir veri ihlali 3.2M TL → güvenlik 6.5x daha ucuz

Marketplace Güvenliğinizi Güçlendirin

PCI-DSS, KVKK uyumluluğu, penetration testing ve 7/24 monitoring ile müşterilerinizin güvenliğini sağlayın.

Güvenlik Danışmanlığı