למד מהי התייחסות ישירה לאובייקט לא מאובטח (IDOR), כיצד תוקפים מנצלים אותה וכיצד מפתחים יכולים למנוע פגיעויות IDOR באמצעות שיטות קידוד מאובטחות, דפוסי בקרת גישה ופלטפורמות בדיקה אוטומטיות.
מהו IDOR?
הפניה לא בטוחה לאובייקט ישיר (IDOR) היא פגיעות אבטחה שבה יישום חושף מזהים פנימיים של אובייקטים — כגון מזהי משתמש, מספרי הזמנות או שמות קבצים — מבלי לאמת אם למבקש יש הרשאה לגשת לאובייקט זה. על ידי שינוי פרמטר ב-URL או בקריאת API, תוקף יכול להציג, לשנות או למחוק נתונים שאליהם אין לו גישה.
הבנת IDOR: מדוע פגיעות זו עדיין חשובה
IDOR שייך לקטגוריה הרחבה של בקרת גישה שבורה, אשר OWASP דירג כסיכון האבטחה הקריטי ביותר ברשת מזה שנים. הסכנה הטמונה ב-IDOR טמונה בפשטותו: התוקף אינו זקוק לטכניקות ניצול מתקדמות, קידוד מטען או העלאת הרשאות. פרמטר אחד ששונה – לרוב רק מספר – יכול לחשוף מידע פרטי.
דפוס פגיע טיפוסי נראה כך:
לנזוף
/api/user/profile?id=1002
אם היישום אינו מאמת בעלות או הרשאה, שינוי המזהה ל- 1003 עלול לחשוף את נתוניו של משתמש אחר.
יישומים מודרניים — במיוחד אלה הכרוכים ב-API, מיקרו-שירותים או לקוחות ניידים — מסתמכים לעתים קרובות במידה רבה על גישה לאובייקטים פרמטריים. ארכיטקטורה זו, אף שהיא מהירה וגמישה, עלולה להוביל בקלות ל-IDOR כאשר בדיקות האישור אינן עקביות או חסרות.

CVE-2025-13526: מקרה IDOR אמיתי בעולם האמיתי
אחת הדוגמאות הבולטות ביותר לניצול IDOR היא CVE-2025-13526, המשפיע על התוסף הפופולרי של WordPress OneClick Chat to Order (גרסאות ≤ 1.0.8).
- הפגיעות נמצאת בתוסף
wa_order_thank_you_overrideפונקציה. התוסף סומך עלמספר הזמנהפרמטר ממחרוזת השאילתה של כתובת ה-URL — מבלי לבדוק שהבקשה מגיעה מהבעלים החוקי של ההזמנה. - תוקפים (אפילו כאלה שלא עברו אימות) יכולים פשוט לתפעל את ה-
מספר הזמנהערך בכתובת ה-URL של דף התודה (לדוגמה, שינוימספר הזמנה=123456אלמספר הזמנה=123455) ולחשוף את פרטי ההזמנות של לקוחות אחרים. הנתונים שנחשפו כללו שמות, כתובות דוא"ל, מספרי טלפון, כתובות חיוב/משלוח, פריטי הזמנה ומחירים, מטא-נתונים על אמצעי תשלום. wiz.io+2Gowri Infosec+2 - מכיוון שמספרי הזמנות היו רציפים וניתנים לחיזוי, ספירתם ההמונית הפכה למשימה פשוטה — כלומר, תוקף או סקריפט אוטומטי יכלו לאסוף אלפי הזמנות בתוך דקות. בינוני+1
- לפגיעות הוקצה ציון בסיס CVSS v3.1 של 7.5 (גבוה), המשקף את קלות הניצול (אין צורך באישור) ואת חומרת חשיפת הנתונים.
- המפתח תיקן את הבעיה בגרסה 1.0.9, על ידי יישום בדיקות אישור נאותות כדי להבטיח שרק בעלי הזכויות (או משתמשים מורשים) יוכלו לצפות בנתוני ההזמנות. בעלי האתרים התבקשו לשדרג את האתרים שלהם באופן מיידי. Gowri Infosec+1
פרצה זו בעולם האמיתי מראה כי IDOR אינו באג תיאורטי או מיושן — הוא עדיין קיים, ניתן לניצול, ועשוי לגרום להשלכות חמורות על הפרטיות והציות לתקנות.

תרחישים נפוצים בעולם האמיתי שבהם מתרחשת תופעת IDOR
IDOR יכול להופיע בכל מערכת המתייחסת לאובייקטים פנימיים באמצעות קלט הנשלט על ידי המשתמש. להלן הקשרים נפוצים:
| סוג היישום | דוגמה לאובייקט | מדוע מתרחשת תופעת IDOR |
|---|---|---|
| מערכות חשבונות | userId | חשיפה ישירה של מזהי משתמשים |
| אפליקציות מסחר אלקטרוני | מספר הזמנה | אימות לא תקין של בעלות |
| ניהול קבצים | מזהה קובץ | חוסר בקרת גישה לקבצים |
| פלטפורמות מכירת כרטיסים | מזהה כרטיס | משתמשים ניגשים לכרטיסים של משתמשים אחרים |
| אפליקציות SaaS מרובות משתמשים | tenantId | דליפות נתונים בין דיירים |
התוקפים לעתים קרובות מונים מזהים צפויים, מנסים מזהים רציפים או משחזרים בקשות מאומתות עם פרמטרים ששונו.
כיצד תוקפים מנצלים IDOR (דוגמאות בטוחות ומבוקרות)
להלן דוגמאות לאיורים בטוחים המציגים דפוסים פגיעים טיפוסיים ואת המקבילים הבטוחים שלהם. אלה אינם ניצולים מזיקים; הם מדגמים טעויות נפוצות כדי לעזור למפתחים לזהות דפוסים לא בטוחים.
דוגמה 1: IDOR ב-Node.js / Express
javascript
// ❌ דוגמה לפגיעות: אמון בזהות שסופקה על ידי המשתמש
app.get('/api/user/profile', (req, res) => {
const userId = req.query.id;
db.users.findById(userId).then(user => {
res.json(user);
});
});
// ✅ דוגמה מאובטחת: אכיפת אישור
app.get('/api/user/profile', (req, res) => {
const authenticatedId = req.user.id;
db.users.findById(authenticatedId).then(user => {
if (!user) return res.status(404).json({ error: "המשתמש לא נמצא" });
res.json({ id: user.id, email: user.email, role: user.role });
});
});
דוגמה 2: תבנית נפוצה ב-Python / Flask
פייתון
#❌ לא מאובטח: אין אימות בעלות
@app.get("/invoice")
def get_invoice():
חשבונית_id = request.args.get("id")
החזר get_invoice_by_id(invoice_id)
#✅ מאובטח: נוספה בדיקת הרשאות
@app.get("/invoice")
def get_invoice_secure():
חשבונית_id = request.args.get("id")
user_id = session["user_id"]
חשבונית = get_invoice_by_id(invoice_id)
אם invoice.owner_id != user_id:
return {"error": "Unauthorized"}, 403
חשבונית החזרה
דוגמה 3: הגנה משולבת של ה-Back-End וה-Front-End (Java + React)
Java (Spring Boot)
ג'אווה
// ❌ בדיקת אישור חסרה
@GetMapping("/orders")
public Order getOrder(@RequestParam String orderId) {
החזר orderRepository.findById(orderId);
}
// ✅ יישום מאובטח
@GetMapping("/orders")
public ResponseEntity getOrder(
@RequestParam מחרוזת orderId,
מנהל בית הספר) {
הזמנה order = orderRepository.findById(orderId);
if (!order.getUser().equals(principal.getName())) {
החזר ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(Collections.singletonMap("error", "Access denied"));
}
החזר ResponseEntity.ok(הזמנה);
}
בקשה מאובטחת בצד React
javascript
פונקציה אסינכרונית fetchOrder(orderId) {
const res = await fetch(/orders?orderId=${orderId}, {
כותרות: { "אישור": Bearer ${localStorage.getItem("token")} }
});
if (!res.ok) throw new Error("לא מורשה או לא נמצא");
החזר res.json();
}
איתור פגיעויות IDOR: גישות מעשיות למפתחים
לעתים קרובות, איתור IDOR קשה יותר מניצולו. בניגוד לפגיעויות הזרקה, IDOR לא תמיד מייצר שגיאות טכניות ברורות — הסימפטומים שלו הם לוגיים והתנהגותיים.
טכניקות זיהוי נפוצות כוללות:
- פוזינג דיפרנציאלי (בדיקת מספר מזהים)
- בדיקת השמעה חוזרת (לכידה → שינוי → השמעה חוזרת)
- החלפת תפקידים בין משתמשים מרובים
- אפיון פרמטרים
קוד פסאודו בטוח:
פייתון
דוגמה פשוטה ובטוחה לפוזינג
ids = ["1001", "1002", "1003"]
עבור i ב-ids:
res = client.get(f"/api/user/profile?id={i}")
הדפס(i, res.status_code, len(res.text))
מניעת IDOR: שיטות עבודה מומלצות שעל מפתחים לנקוט
מניעת IDOR אינה עוסקת בהסתרה — היא עוסקת ב הרשאה, מבוצע באופן עקבי ברמת השרת.
לעולם אל תסמוך על מזהי אובייקטים מהלקוח
כל פרמטר ניתן לשינוי. אפילו מזהים מוצפנים ניתנים לזיוף.
אכוף אימות בצד השרת על כל בקשה
השתמש במודלים מוכרים לבקרת גישה:
- RBAC (בקרת גישה מבוססת תפקידים)
- ABAC (בקרת גישה מבוססת תכונות)
- ACLs (רשימות בקרת גישה)
- מדיניות כקוד מערכות כמו OPA
משאבי סמכות:
- OWASP: https://owasp.org
אקדמיית אבטחת האינטרנט של PortSwigger: https://portswigger.net/web-security/access-control
העדף מזהים שאינם ניתנים לספירה
UUIDs מפחיתים את הסיכון ל-IDOR, אך אינם מבטלים אותו לחלוטין.
אמת את גבולות הדיירים בסביבות מרובות דיירים
IDOR חוצה דיירים הוא אחד הסוגים החמורים והיקרים ביותר.
השתמש בשכבת Backend-for-Frontend (BFF)
BFF יכול לרכז את לוגיקת ההרשאה, ובכך להפחית את חוסר העקביות בין לקוחות.
דוגמאות מתקדמות נוספות
דוגמה 4: ממשק API של Go עם אישור חסר
לך
// ❌ מטפל פגיע
func GetDocument(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
doc := db.FindDocument(id)
json.NewEncoder(w).Encode(doc)
}
// ✅ עם אימות בעלות
func GetDocumentSecure(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
user := r.Context().Value("user").(string)
doc := db.FindDocument(id)
אם doc.Owner != user {
http.Error(w, "Unauthorized", http.StatusForbidden)
חזרה
}
json.NewEncoder(w).Encode(doc)
}
דוגמה 5: נקודות קצה GraphQL ואישור אובייקטים
javascript
// ❌ רזולבר פגיע
const resolvers = {
שאילתה: {
הזמנה: (_, { id }) => db.getOrder(id),
}
};
// ✅ פתרון מאובטח עם בדיקת בעלות
const resolversSecure = {
שאילתה: {
הזמנה: (_, { id }, context) => {
const order = db.getOrder(id);
if (order.owner !== context.user.id) {
זרוק שגיאה חדשה ("גישה נדחתה");
}
החזרת הזמנה;
}
}
};
דוגמה 6: גישה מאובטחת ב-Rust (Actix Web)
חלודה
// ❌ פגיע
async fn get_ticket(path: web::Path) -> impl Responder {
let id = path.into_inner();
let ticket = db::find_ticket(&id);
web::Json(כרטיס)
}
// ✅ גרסה מאובטחת
async fn get_ticket_secure(
נתיב: web::Path,
משתמש: LoggedInUser
) -> impl Responder {
let id = path.into_inner();
let ticket = db::find_ticket(&id);
אם ticket.owner != user.id {
החזר HttpResponse::Forbidden().json("גישה נדחתה");
}
HttpResponse::Ok().json(כרטיס)
}
אוטומציה של זיהוי IDOR: מדוע כלים מסורתיים מתקשים בכך
רוב סורקי הפגיעות המסורתיים אינם מסוגלים לזהות IDOR באופן מהימן, מכיוון ש-IDOR דורש שני דברים שסורקים מסורתיים אינם מסוגלים לבצע:
- מודעות ללוגיקה עסקית
- בדיקות רב-משתמשים בהקשר
כלי סריקה המסתמכים אך ורק על זיהוי מבוסס חתימה או בקשות של משתמש בודד בדרך כלל מפספסים את IDOR לחלוטין, במיוחד ב-API.
כיצד Penligent מסייע בזיהוי IDOR באופן אוטומטי
זה המקום שבו Penligent, פלטפורמת בדיקות חדירה מבוססת בינה מלאכותית, מספקת יתרון ייחודי. בניגוד לסורקים קונבנציונליים, Penligent מבצעת:
- סימולציה אוטומטית למשתמשים מרובים
- הסקת פרמטרים בין-אובייקטים
- זיהוי תבניות זיהוי חכם
- ניתוח דיפרנציאלי התנהגותי
- Fuzzing מבוסס AI המסתגל בהתאם לתגובות שנצפו
דוגמה לתוצאת זיהוי בטוחה ואנונימית של Penligent:
vbnet
`זוהתה אפשרות ל-IDOR: נקודת קצה: /orders?id=1002 התנהגות שנצפתה:
- משתמש A קיבל את ההזמנה #1003 (בבעלות משתמש B) סיכון: גישה לא מורשית לנתוני משתמש אחר.
תובנה מסוג זה קשה להשיג באמצעות כלים סטטיים או בדיקה ידנית בלבד.
הפחתת סיכוני IDOR ב-CI/CD באמצעות Penligent
Penligent משתלב באופן טבעי בצינורות CI/CD ומספק כיסוי רציף:
- API וזיהוי אוטומטי של מסלולים
- הסקת מטריצת הרשאות בזמן אמת
- סריקה של סביבות בימוי והפקה
- יצירה אוטומטית של רצפים PoC בטוחים וניתנים לשחזור
זה מפחית:
- נקודות עיוורות בהיגיון העסקי
- חשיפה לדיירים מרובים
- סיכונים רגולטוריים (GDPR, HIPAA, SOC2)
מסקנה: IDOR הוא פשוט אך הרסני — וניתן למניעה
IDOR נותרה אחת מצורות הפגיעות הנפוצות והמזיקות ביותר בתחום בקרת הגישה. מכיוון שהיא מסתתרת בתוך הלוגיקה העסקית, היא לעתים קרובות חומקת מעבר לכלים המסורתיים. על ידי אכיפת בדיקות אישור עקביות, שימוש במזהים בלתי צפויים, אימות גבולות הדיירים ואימוץ פלטפורמות בדיקה אוטומטיות כמו Penligent, ארגונים יכולים להפחית באופן דרמטי את הסיכון לחשיפת נתונים בקנה מידה גדול.
לא ניתן לחסל את IDOR לחלוטין באמצעות מזל או כוונות טובות — נדרשים בקרת גישה מובנית, עקרונות הנדסיים עקביים ובדיקות מתמשכות.

