חשיפת נתונים ב-API: מניעה וזיהוי
חשיפה בלתי הולמת של נתונים דרך API מהווה אחת מהפגיעויות המרכזיות במערכות מודרניות. ממשקי API המוגדרים בצורה שגויה או מוגנים באופן בלתי מספק עלולים להדליף מידע רגיש, לסכן נתוני משתמשים ולהפר תקנות פרטיות כגון LGPD ו-GDPR.
סוגי חשיפת נתונים ב-API
1. חשיפת נתונים מופרזת (API3:2023 - OWASP)
ממשקי API המחזירים יותר מידע מהנדרש:
- ה-endpoint מחזיר את האובייקט המלא כאשר נדרשים רק שדות אחדים
- הכללת שדות רגישים בתגובות (hashes של סיסמאות, tokens פנימיים)
- מטא-נתונים של המערכת הנחשפים בשגיאות
// [ERRO] Exemplo RUIM - Expondo dados demais
GET /api/users/123
{
"id": 123,
"name": "João Silva",
"email": "[email protected]",
"password_hash": "$2b$10$...", // [AVISO] Nunca expor
"ssn": "123-45-6789", // [AVISO] Dado sensível
"internal_role_id": 42, // [AVISO] Dado interno
"created_at": "2025-01-01",
"last_login_ip": "192.168.1.1" // [AVISO] Informação sensível
}
// [OK] Exemplo BOM - Apenas dados necessários
GET /api/users/123/profile
{
"id": 123,
"name": "João Silva",
"avatar_url": "https://..."
}
2. היעדר סינון משאבים (Broken Object Level Authorization)
משתמשים יכולים לגשת לנתונים של משתמשים אחרים על ידי שינוי מזהים:
// [ERRO] Vulnerável a IDOR (Insecure Direct Object Reference)
GET /api/orders/456 // Usuário A pode ver pedidos do Usuário B
// [OK] Protegido - Validar autorização
app.get('/api/orders/:id', async (req, res) => {
const order = await Order.findById(req.params.id);
// Verificar se o pedido pertence ao usuário autenticado
if (order.userId !== req.user.id) {
return res.status(403).json({ error: 'Acesso negado' });
}
res.json(order);
});
3. חשיפת מידע רגיש בכתובות URL
- Tokens של אימות ב-query strings
- נתונים אישיים בנתיבים
- מידע סודי ביומני השרת
אסטרטגיות מניעה
יישום Data Transfer Objects (DTOs)
// TypeScript - Definir claramente o que expor
interface UserPublicDTO {
id: number;
name: string;
avatar_url: string;
}
class UserService {
async getPublicProfile(userId: number): Promise<UserPublicDTO> {
const user = await db.users.findUnique({ where: { id: userId } });
// Retornar apenas campos permitidos
return {
id: user.id,
name: user.name,
avatar_url: user.avatar_url
};
}
}
החלת מסנני סריאליזציה
- שימוש בספריות כגון class-transformer (TypeScript)
- Decorators לסימון שדות רגישים (@Exclude)
- קבוצות סריאליזציה להקשרים שונים (ציבורי לעומת admin)
אימות הרשאות
// Middleware de autorização
const checkResourceOwnership = (resourceType) => {
return async (req, res, next) => {
const resource = await db[resourceType].findById(req.params.id);
if (!resource) {
return res.status(404).json({ error: 'Recurso não encontrado' });
}
if (resource.ownerId !== req.user.id && !req.user.isAdmin) {
return res.status(403).json({ error: 'Acesso não autorizado' });
}
req.resource = resource;
next();
};
};
// Uso
app.get('/api/documents/:id',
authenticate,
checkResourceOwnership('documents'),
(req, res) => {
res.json(req.resource);
}
);
טכניקות זיהוי
ניתוח Payloads
- סקירה ידנית של תגובות מ-endpoints קריטיים
- שימוש בכלים כגון Burp Suite, OWASP ZAP
- בדיקות אוטומטיות לאימות שדות חשופים
ניטור והתראות
- זיהוי דפוסי גישה חריגים (enumeration)
- התראה על גישות שנדחו בכמות מופרזת
- ניטור נפח הנתונים המועברים לכל משתמש
Code Review וניתוח סטטי
- סקירת DTOs ומודלים של סריאליזציה
- אימות יישום ההרשאות
- שימוש בכלי SAST לזיהוי חשיפות
שיטות עבודה מומלצות
- אימוץ עקרון ההרשאה המזערית עבור נתונים חשופים
- יישום rate limiting למניעת scraping
- שימוש ב-UUIDs במקום מזהים סדרתיים
- הצפנת נתונים רגישים במעבר ובמנוחה
- יישום ניהול גרסאות API לשינויים בטוחים
- ביצוע בדיקות אבטחה באופן קבוע
- תיעוד ברור של הנתונים שכל endpoint חושף
- שימוש ב-GraphQL בזהירות (עלול להקל על over-fetching)
תאימות ורגולציה
- LGPD/GDPR: מזעור נתונים, בסיס חוקי לעיבוד
- PCI-DSS: הגנה על נתוני כרטיסי אשראי
- HIPAA: הגנה על מידע בריאותי (ארה"ב)
- SOC 2: בקרות גישה וניטור
