38980-vm/app-9w9pd00g5j41/TRIP_CREATE_SECURITY_TESTS.md
2026-03-04 18:25:09 +00:00

337 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Trip Create Security Tests
## Güvenlik Özellikleri
### 1. ✅ Zorunlu Kimlik Doğrulama (Auth Mandatory)
**Özellik**: Anonim kullanıcılar seyahat oluşturamaz.
**Test Senaryoları**:
```typescript
// ❌ BAŞARISIZ: Giriş yapmadan seyahat oluşturma
await supabase.auth.signOut();
const result = await tripsApiSafe.create({
title: "Test Seyahati"
});
// Beklenen: Error: "Seyahat oluşturmak için giriş yapmalısınız."
// ✅ BAŞARILI: Giriş yaparak seyahat oluşturma
await supabase.auth.signInWithPassword({
email: "test@example.com",
password: "password123"
});
const result = await tripsApiSafe.create({
title: "Test Seyahati"
});
// Beklenen: Trip objesi döner
```
---
### 2. ✅ Rate Limiting (5 trip/saat)
**Özellik**: Kullanıcı saatte en fazla 5 seyahat oluşturabilir.
**Test Senaryoları**:
```typescript
// ✅ İlk 5 seyahat başarılı
for (let i = 1; i <= 5; i++) {
const result = await tripsApiSafe.create({
title: `Seyahat ${i}`
});
console.log(`✅ Seyahat ${i} oluşturuldu`);
}
// ❌ 6. seyahat başarısız
try {
await tripsApiSafe.create({
title: "Seyahat 6"
});
} catch (error) {
console.log(error.message);
// Beklenen: "Saatlik limit aşıldı. X dakika sonra tekrar deneyin."
}
// ⏰ 1 saat sonra tekrar dene
setTimeout(async () => {
const result = await tripsApiSafe.create({
title: "Yeni Seyahat"
});
console.log("✅ Limit sıfırlandı, yeni seyahat oluşturuldu");
}, 3600000);
```
---
### 3. ✅ Input Validation
**Özellik**: Tüm girişler doğrulanır ve sanitize edilir.
#### 3.1 Başlık Validasyonu
```typescript
// ❌ Başlık çok kısa (min: 3 karakter)
await tripsApiSafe.create({ title: "AB" });
// Beklenen: Error: "Seyahat başlığı en az 3 karakter olmalıdır."
// ❌ Başlık çok uzun (max: 200 karakter)
await tripsApiSafe.create({
title: "A".repeat(201)
});
// Beklenen: Error: "Seyahat başlığı en fazla 200 karakter olabilir."
// ❌ Başlık boş
await tripsApiSafe.create({ title: "" });
// Beklenen: Error: "Seyahat başlığı alanı zorunludur."
// ✅ Geçerli başlık
await tripsApiSafe.create({
title: "İstanbul Gezisi"
});
```
#### 3.2 Açıklama Validasyonu
```typescript
// ❌ Açıklama çok uzun (max: 2000 karakter)
await tripsApiSafe.create({
title: "Test",
description: "A".repeat(2001)
});
// Beklenen: Error: "Açıklama en fazla 2000 karakter olabilir."
// ✅ Geçerli açıklama
await tripsApiSafe.create({
title: "Test",
description: "Harika bir seyahat planı"
});
```
#### 3.3 Tarih Validasyonu
```typescript
// ❌ Bitiş tarihi başlangıçtan önce
await tripsApiSafe.create({
title: "Test",
start_date: "2026-03-01",
end_date: "2026-02-01"
});
// Beklenen: Error: "Bitiş tarihi başlangıç tarihinden önce olamaz."
// ❌ Geçersiz tarih formatı
await tripsApiSafe.create({
title: "Test",
start_date: "invalid-date"
});
// Beklenen: Error: "Başlangıç tarihi geçersiz."
// ❌ Çok uzun seyahat (max: 365 gün)
await tripsApiSafe.create({
title: "Test",
start_date: "2026-01-01",
end_date: "2027-02-01"
});
// Beklenen: Error: "Seyahat süresi en fazla 365 gün olabilir."
// ✅ Geçerli tarihler
await tripsApiSafe.create({
title: "Test",
start_date: "2026-03-01",
end_date: "2026-03-10"
});
```
#### 3.4 Konum Validasyonu
```typescript
// ❌ Geçersiz enlem (lat: -90 ile 90 arası)
await tripsApiSafe.create({
title: "Test",
start_lat: 100,
start_lng: 30
});
// Beklenen: Error: "Enlem değeri -90 ile 90 arasında olmalıdır."
// ❌ Geçersiz boylam (lng: -180 ile 180 arası)
await tripsApiSafe.create({
title: "Test",
start_lat: 40,
start_lng: 200
});
// Beklenen: Error: "Boylam değeri -180 ile 180 arasında olmalıdır."
// ❌ Konum tipi sayı değil
await tripsApiSafe.create({
title: "Test",
start_lat: "invalid",
start_lng: 30
});
// Beklenen: Error: "Konum bilgileri geçersiz."
// ✅ Geçerli konum
await tripsApiSafe.create({
title: "Test",
start_lat: 41.0082,
start_lng: 28.9784
});
```
#### 3.5 İlgi Alanları Validasyonu
```typescript
// ❌ Çok fazla ilgi alanı (max: 20)
await tripsApiSafe.create({
title: "Test",
interests: Array(21).fill("test")
});
// Beklenen: Error: "En fazla 20 ilgi alanı seçebilirsiniz."
// ❌ Geçersiz ilgi alanı formatı
await tripsApiSafe.create({
title: "Test",
interests: ["A".repeat(51)]
});
// Beklenen: Error: "İlgi alanı formatı geçersiz."
// ✅ Geçerli ilgi alanları
await tripsApiSafe.create({
title: "Test",
interests: ["history", "culture", "food"]
});
```
---
### 4. ✅ Meaningful Error Messages
**Özellik**: Kullanıcıya anlamlı hata mesajları gösterilir.
**Hata Mesajları**:
- ✅ "Seyahat oluşturmak için giriş yapmalısınız." (Auth hatası)
- ✅ "Saatlik limit aşıldı. X dakika sonra tekrar deneyin." (Rate limit)
- ✅ "Seyahat başlığı en az 3 karakter olmalıdır." (Validation)
- ✅ "Bitiş tarihi başlangıç tarihinden önce olamaz." (Validation)
- ✅ "Seyahat oluşturulurken bir hata oluştu. Lütfen tekrar deneyin." (DB hatası)
---
### 5. ✅ Security Audit Logging
**Özellik**: Tüm güvenlik olayları loglanır.
**Log Formatı**:
```
[SECURITY AUDIT] 2026-02-08T10:30:00.000Z | Event: TRIP_CREATE_SUCCESS | User: user-uuid | Details: { tripId, title, destination }
```
**Log Olayları**:
1. `TRIP_CREATE_FAILED` - Yetkisiz erişim denemesi
2. `TRIP_CREATE_RATE_LIMITED` - Rate limit aşımı
3. `TRIP_CREATE_VALIDATION_FAILED` - Geçersiz input
4. `TRIP_CREATE_DB_ERROR` - Veritabanı hatası
5. `TRIP_CREATE_SUCCESS` - Başarılı oluşturma
**Test**:
```typescript
// Console'u izle
console.log = jest.fn();
// Başarısız deneme
try {
await supabase.auth.signOut();
await tripsApiSafe.create({ title: "Test" });
} catch (error) {
// Log kontrolü
expect(console.log).toHaveBeenCalledWith(
expect.stringContaining('[SECURITY AUDIT]'),
expect.stringContaining('TRIP_CREATE_FAILED'),
expect.stringContaining('Unauthorized')
);
}
```
---
## Kullanım Örnekleri
### Frontend'de Güvenli Kullanım
```typescript
import { tripsApiSafe } from '@/db/api';
import { toast } from 'sonner';
// ✅ DOĞRU: tripsApiSafe kullan
const handleCreateTrip = async (formData) => {
try {
const trip = await tripsApiSafe.create({
title: formData.title,
description: formData.description,
start_date: formData.startDate,
end_date: formData.endDate,
destination: formData.destination,
interests: formData.interests
});
toast.success('Seyahat başarıyla oluşturuldu!');
return trip;
} catch (error) {
// Kullanıcıya anlamlı hata mesajı göster
toast.error(error.message);
console.error('Trip creation error:', error);
}
};
// ❌ YANLIŞ: tripsApi kullanma (güvensiz)
const handleCreateTripUnsafe = async (formData) => {
const trip = await tripsApi.create(formData); // Validation yok!
};
```
---
## Performans Notları
### Rate Limiter Memory Management
Rate limiter in-memory Map kullanır. Production'da Redis kullanılması önerilir:
```typescript
// Gelecek iyileştirme: Redis ile rate limiting
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: process.env.REDIS_URL,
token: process.env.REDIS_TOKEN
});
const checkRateLimitRedis = async (userId: string) => {
const key = `rate_limit:trip_create:${userId}`;
const count = await redis.incr(key);
if (count === 1) {
await redis.expire(key, 3600); // 1 saat
}
if (count > 5) {
const ttl = await redis.ttl(key);
throw new Error(`Saatlik limit aşıldı. ${Math.ceil(ttl / 60)} dakika sonra tekrar deneyin.`);
}
};
```
---
## Güvenlik Checklist
- [x] ✅ Auth mandatory - Anonim kullanıcılar seyahat oluşturamaz
- [x] ✅ Rate limiting - 5 trip/saat per user
- [x] ✅ Input validation - Tüm alanlar doğrulanır
- [x] ✅ Meaningful errors - Kullanıcıya anlamlı mesajlar
- [x] ✅ Security logging - Tüm olaylar loglanır
- [x] ✅ SQL injection koruması - Input sanitization
- [x] ✅ XSS koruması - String validation
- [x] ✅ Data integrity - Tarih ve konum validasyonu
---
## Sonuç
`tripsApiSafe.create()` fonksiyonu artık production-ready ve güvenli:
1. **Auth Mandatory**: Sadece giriş yapmış kullanıcılar seyahat oluşturabilir
2. **Rate Limiting**: Spam ve abuse koruması
3. **Input Validation**: Tüm girişler doğrulanır ve sanitize edilir
4. **Error Handling**: Kullanıcıya anlamlı mesajlar
5. **Audit Trail**: Güvenlik olayları loglanır
**Kullanım**: Frontend'de her zaman `tripsApiSafe.create()` kullanın, `tripsApi.create()` kullanmayın!