IDOR چیست؟
IDOR مخفف Insecure Direct Object Reference است: «ارجاع مستقیم ناامن به شیء». مکانیزم آن در یک جمله خلاصه میشود — برنامه یک شناسه از ورودی کاربر میگیرد، آن را مستقیماً به لایهی داده میدهد، و هیچجا بررسی نمیکند که کاربرِ درخواستدهنده مجاز به دسترسی به آن شیء هست یا نه.
در سطح کد، تفاوت آسیبپذیر و امن معمولاً یک شرط است:
// vulnerable
invoice = db.query("SELECT * FROM invoices WHERE id = ?", id);
// safe
invoice = db.query(
"SELECT * FROM invoices WHERE id = ? AND owner_id = ?",
id, session.userId);نکتهی مهم این است که IDOR یک زیرمجموعهی کنترل دسترسی شکسته (A01:2025) است، نه یک دستهی مستقل در OWASP Top 10. در راهنمای آزمون WSTG، IDOR یکی از چهار آزمون بخش مجوزدهی (WSTG-ATHZ) است.
یک بدفهمی رایج در نامگذاری هم وجود دارد: «Direct» بهمعنای «عدد ترتیبی» نیست. هر چیزی که به یک شیء ارجاع میدهد و از سمت کاربر میآید میتواند وکتور IDOR باشد — عدد افزایشی، UUID، هش، نام فایل، شمارهی سفارش، آدرس ایمیل، یا حتی یک ادعای داخل توکن JWT که سرور بدون راستیآزمایی به آن اعتماد میکند.
انواع IDOR و آسیبپذیریهای خویشاوند
- IDOR خواندنی (افقی): دیدن دادهی کاربر دیگر — فاکتور، پیام، پروندهی پزشکی، فایل آپلودشده. رایجترین حالت و معمولاً پرحجمترین از نظر دادهی افشاشده.
- IDOR نوشتنی: تغییر یا حذف دادهی کاربر دیگر. اثر بهمراتب سنگینتر است و اغلب فراموش میشود، چون تیم توسعه فقط
GETرا محافظت کرده است. - IDOR کور (Blind): پاسخ دادهای برنمیگرداند اما عملیات انجام میشود — مثلاً
POST /api/subscriptions/9812/cancelکه با کد ۲۰۴ پاسخ میدهد. برای اثبات باید اثر جانبی را از مسیر دیگری مشاهده کرد. - IDOR در فایل و منابع ایستا: مسیرهایی مثل
/uploads/2026/03/contract-1042.pdfکه مستقیماً توسط وبسرور سرو میشوند و هرگز از لایهی مجوزدهی برنامه عبور نمیکنند.
سه خویشاوند نزدیک که در گزارش باید از IDOR تفکیک شوند:
| عنوان | ماهیت |
|---|---|
| BOLA | همان IDOR، با نامی که OWASP API Security Top 10 (نسخهی ۲۰۲۳) برایش انتخاب کرده و رتبهی یک آن فهرست است |
| BFLA | دسترسی به یک عملیات غیرمجاز، نه یک شیء — مثلاً اجرای DELETE روی منبعی که فقط GET آن مجاز بود |
| BOPLA / Mass Assignment | خواندن یا نوشتن ویژگیهایی از شیء که نباید در دسترس باشند — مثل ارسال {"role":"admin"} در بدنهی بهروزرسانی پروفایل |
سناریوی واقعی
یک سامانهی مدیریت قرارداد، فایلهای امضاشده را با آدرسی شامل UUID سرو میکند: /files/9f1c7d3a-…-b41e/download. تیم توسعه معتقد است چون شناسه غیرقابل حدس است، بررسی مالکیت لازم نیست.
در تست نفوذ، سه مسیر نشت شناسه پیدا میشود. اول، اندپوینت GET /api/projects/{id}/files فهرست فایلهای یک پروژه را با UUID کامل برمیگرداند و خودش کنترل مجوز کافی ندارد. دوم، خروجی گزارش اکسل که برای همهی اعضای سازمان قابل دانلود است، ستون شناسهی فایل را دارد. سوم، صفحهی پیشنمایش سند یک اسکریپت تحلیل ثالث بارگذاری میکند و UUID در هدر Referer به دامنهی بیرونی ارسال میشود.
نتیجه: «غیرقابل حدس بودن» شناسه اصلاً به آزمون گذاشته نشد، چون مهاجم نیازی به حدس زدن نداشت. این دقیقاً همان چیزی است که در بند بعد توضیح داده میشود.
اشتباه رایج: «از UUID استفاده میکنیم پس IDOR نداریم»
«شناسههای ما UUID هستند، پس IDOR نداریم.» شناسهی غیرقابل حدس فقط هزینهی کشف را بالا میبرد؛ هیچ بررسی مجوزی اضافه نمیکند. اگر مهاجم به هر شکلی شناسه را بهدست آورد، برنامه همچنان داده را تحویل میدهد. UUID یک کنترل دسترسی نیست، یک فضای نام است.
مسیرهایی که UUID از آنها نشت میکند، در عمل فراواناند:
- پاسخ اندپوینتهای دیگر — بهویژه اندپوینتهای فهرستکننده، جستوجو و پیشنهاد خودکار.
- خروجی گزارشها و فایلهای CSV/Excel که برای همهی اعضای سازمان قابل دسترساند.
- هدر
Refererهنگام بارگذاری منابع ثالث، و لاگهای سرور و CDN. - پروفایلهای عمومی، آدرسهای اشتراکگذاری، ایمیلهای اعلان و پیوستها.
- ساختار خود شناسه: UUID نسخهی ۱ مهر زمانی و شناسهی سختافزاری (MAC) را در خود کدگذاری میکند و بنابراین اصلاً تصادفی نیست. اگر شناسهها با v1 تولید میشوند، پیشبینیپذیری واقعی روی میز است.
نتیجهی عملی برای گزارشنویسی: در یافتهی IDOR هرگز ننویسید «بهدلیل ترتیبی بودن شناسهها». علت واقعی نبود بررسی مالکیت است و راهکار هم تغییر نوع شناسه نیست.
چگونه در تست نفوذ کشف میشود
روش استاندارد و قابل تکرار، مقایسهی دو حساب همسطح است:
- دو حساب همسطح بگیرید (کاربر A و کاربر B، هر دو با نقش یکسان). بدون حساب دوم، آزمون افقی معنا ندارد و شما فقط دارید حدس میزنید.
- با حساب A همهی جریانهای کاری را کامل اجرا کنید و با حساب B هم همین کار را انجام دهید تا تاریخچهی پروکسی برای هر دو کامل شود.
- شناسهها را استخراج کنید: شناسهی رکوردهای B را از تاریخچهی B بردارید و در درخواستهای A جایگذاری کنید. جای شناسه فقط مسیر URL نیست — پارامتر Query، بدنهی JSON، فرم چندبخشی، کوکی، هدرهای سفارشی و ادعاهای توکن را هم بررسی کنید.
- پاسخها را تفاضلی مقایسه کنید. کد وضعیت بهتنهایی کافی نیست؛ به طول پاسخ، زمان پاسخ و تفاوت محتوا نگاه کنید. پاسخ
404در برابر403خودش یک نشت اطلاعات است (وجود یا عدم وجود رکورد). - متدها را جابهجا کنید: اگر
GETمحافظت شده است،PUT،PATCH،DELETEو هدرX-HTTP-Method-Overrideرا امتحان کنید. - اندپوینتهای دستهای و GraphQL: اندپوینتهایی که آرایهای از شناسه میگیرند (
ids=[1041,1042]) یا کوئریهای تودرتوی GraphQL، اغلب بررسی مجوز را فقط روی گرهی ریشه انجام میدهند.
ابزار کمکی: افزونههای بازپخش متقاطع در Burp Suite، امکانات معادل در Caido برای مقایسهی خودکار پاسخها، و ffuf برای پیمایش دامنهی شناسهها وقتی شناسهها ترتیبی هستند. اما تصمیم نهایی همیشه دستی است — ابزار نمیداند کاربر A باید رکورد ۱۰۴۲ را ببیند یا نه. امنیت برنامهی وب در این نقطه به قضاوت انسانی وابسته است.
نمونهی فنی و ارتباط با OWASP و CWE
شکل ساده و غیرتهاجمی اثبات مفهوم در گزارش:
GET /api/orders/8841 HTTP/1.1
Host: shop.example.com
Cookie: session=<session-of-user-A>
HTTP/1.1 200 OK
{"order":8841,"customer":"user-B","phone":"09xx…"}در شواهد گزارش باید سه چیز دیده شود: نشست متعلق به کاربر A، شناسهی متعلق به کاربر B، و دادهی برگشتی که مالکیت B را ثابت میکند. اثبات باید حداقلی باشد — یک رکورد کافی است و استخراج انبوه دادهی واقعی مشتریان در یک تست مجاز، غیرحرفهای و از نظر قراردادی پرریسک است.
نگاشت به استانداردها
- OWASP Top 10:2025: زیرمجموعهی A01 — Broken Access Control.
- CWE-639: Authorization Bypass Through User-Controlled Key — نزدیکترین شناسه به IDOR، که در فهرست ۲۰۲۵ CWE Top 25 رتبهی ۲۴ را دارد. CWE-862 (نبود مجوزدهی) رتبهی چهارم همان فهرست است.
- WSTG-ATHZ: آزمون IDOR یکی از چهار آزمون بخش مجوزدهی راهنمای آزمون OWASP.
- OWASP API Security Top 10 (2023): با نام BOLA، رتبهی یک.
پرسشهای متداول
آیا استفاده از UUID جلوی IDOR را میگیرد؟
خیر. UUID فقط حدس زدن شناسه را دشوار میکند و هیچ بررسی مجوزی اضافه نمیکند. شناسهها از پاسخ سایر اندپوینتها، خروجی گزارشها، هدر Referer، لاگها و آدرسهای اشتراکی نشت میکنند. ضمناً UUID نسخهی ۱ مهر زمانی و آدرس MAC را در خود دارد و تصادفی نیست. راهحل واقعی، بررسی مالکیت در سمت سرور برای هر درخواست است.
چطور IDOR را در برنامهی خودم تست کنم؟
دو حساب همسطح بسازید، با هر دو همهی جریانهای کاری را اجرا کنید، سپس شناسههای حساب دوم را در درخواستهای حساب اول جایگذاری کنید و پاسخها را مقایسه کنید. جای شناسه فقط URL نیست؛ بدنهی JSON، کوکی، هدرهای سفارشی و اندپوینتهای دستهای را هم بررسی کنید. متدهای PUT و DELETE را جدا از GET بیازمایید.
شدت IDOR در گزارش تست نفوذ چقدر است؟
به داده و عملیات بستگی دارد. خواندن دادهی هویتی یا مالی کاربران دیگر معمولاً بالا تا بحرانی امتیاز میگیرد؛ IDOR نوشتنی که امکان تغییر یا حذف دادهی دیگران را میدهد تقریباً همیشه بحرانی است. امتیازدهی را با CVSS انجام دهید و نسخهی مورد استفاده را در گزارش ذکر کنید.
تفاوت IDOR و BOLA چیست؟
عملاً یک چیزند. BOLA (Broken Object Level Authorization) نامی است که OWASP در فهرست API Security Top 10 نسخهی ۲۰۲۳ برای همین مفهوم انتخاب کرده و رتبهی یک آن فهرست است. اگر گزارشی برای تست API مینویسید، اصطلاح BOLA دقیقتر و قابل ارجاعتر است.