☠️ یک عدد ساده میتواند درِ حساب کاربر دیگری را باز کند!
تصور کن وارد حساب کاربری خودت شدهای.
در URL صفحه، چیزی شبیه این میبینی:
/profile?id=101
همهچیز عادی به نظر میرسد.
اما یک سؤال:
اگر 101 را به 102 تغییر بدهی چه اتفاقی میافتد؟
اگر اطلاعات کاربر دیگری نمایش داده شود، با یک مشکل جدی در Access Control روبهرو هستیم.
این دقیقاً همان جایی است که مفهوم IDOR وارد داستان میشود.
1. Broken Access Control چیست؟
Broken Access Control یا کنترل دسترسی معیوب، زمانی اتفاق میافتد که برنامه نتواند بهدرستی مشخص کند:
«این کاربر دقیقاً به چه چیزی اجازه دسترسی دارد؟»
یک سیستم امن باید بین:
Authentication
و:
Authorization
تفاوت قائل شود.
Authentication
یعنی:
تو چه کسی هستی؟
Authorization
یعنی:
حالا که میدانم چه کسی هستی، اجازه انجام چه کاری را داری؟
مثلاً:
User A
↓
Authenticated
↓
Authorization Check
↓
Own Profile → ✅
Admin Panel → ❌
User B Data → ❌
مشکل زمانی ایجاد میشود که برنامه فقط بررسی کند:
"آیا کاربر Login کرده؟"
و بررسی نکند:
"آیا این کاربر اجازه دسترسی به این Resource را دارد؟"
2. IDOR چیست؟
IDOR مخفف:
Insecure Direct Object Reference
است.
این مشکل زمانی رخ میدهد که برنامه یک Object یا Resource را با یک شناسه مستقیم مشخص کند، اما هنگام درخواست، مالکیت یا مجوز دسترسی به آن Resource را بهدرستی بررسی نکند.
مثلاً:
/account?id=1001
کاربر فعلی حساب 1001 است.
اما اگر برنامه اجازه دهد:
/account?id=1002
و اطلاعات حساب کاربر دیگری را نمایش دهد، یک نمونه کلاسیک از IDOR داریم.
3. یک مثال ساده
فرض کنیم برنامه این درخواست را دریافت میکند:
GET /profile?id=1001 HTTP/1.1
Cookie: SESSION=...
سرور باید بررسی کند:
Session User = 1001
Requested User = 1001
→ Allowed
اما اگر کاربر درخواست کند:
GET /profile?id=1002 HTTP/1.1
سرور باید بگوید:
Session User = 1001
Requested User = 1002
→ Access Denied
اگر پاسخ اطلاعات کاربر 1002 را برگرداند:
Session User = 1001
Requested User = 1002
→ Access Granted ❌
مشکل وجود دارد.
4. چرا IDOR خطرناک است؟
شدت IDOR کاملاً به Resource آسیبدیده بستگی دارد.
اگر فقط یک اطلاعات عمومی نمایش داده شود، ریسک ممکن است پایین باشد.
اما اگر Resource شامل اطلاعات حساس باشد، وضعیت کاملاً متفاوت است.
مثلاً:
👤 اطلاعات پروفایل
📧 Email
📱 شماره تلفن
📄 اسناد
💳 اطلاعات مالی
📦 سفارشها
🎫 تیکتهای پشتیبانی
⚙️ تنظیمات حساب
در برخی شرایط حتی عملیاتهایی مانند:
Edit
Delete
Download
Change
Approve
نیز میتوانند تحت تأثیر قرار بگیرند.
5. انواع Broken Access Control
Broken Access Control فقط IDOR نیست.
چند نمونه مهم:
Horizontal Privilege Escalation
کاربر معمولی بتواند به اطلاعات کاربر معمولی دیگری دسترسی پیدا کند.
User A
↓
User B Data
Vertical Privilege Escalation
کاربر سطح پایین بتواند عملیات مخصوص Administrator را انجام دهد.
Normal User
↓
Admin Function
Missing Function-Level Access Control
کاربر بتواند مستقیماً یک Endpoint حساس را فراخوانی کند، در حالی که رابط کاربری نباید چنین امکانی به او بدهد.
IDOR
کاربر بتواند با تغییر Reference، به Object متعلق به کاربر دیگری دسترسی پیدا کند.
6. ساخت آزمایشگاه
برای این آموزش از همان ساختار قبلی استفاده میکنیم:
┌─────────────────────────┐
│ Kali Linux │
│ │
│ Browser + Burp Suite │
└────────────┬────────────┘
│
│ HTTP
▼
┌─────────────────────────┐
│ DVWA │
│ │
│ Access Control Testing │
└─────────────────────────┘
فرض میکنیم IP ماشین آزمایشگاهی:
192.168.56.20
این IP فقط نمونه است.
7. بررسی اتصال
ابتدا اتصال به ماشین آزمایشگاهی را بررسی کنید:
ping 192.168.56.20
سپس سرویسهای محیط آزمایشگاهی را بررسی کنید:
nmap -sV 192.168.56.20
هدف این مرحله شناسایی سرویسهای لابراتوار خودمان است.
8. مفهوم Object چیست؟
برای درک IDOR باید مفهوم Object را بفهمیم.
در یک برنامه وب، Object میتواند چیزهای مختلفی باشد:
User
Order
Invoice
Ticket
Message
File
Document
Profile
مثلاً:
/orders/1001
در اینجا:
1001
یک Reference برای یک Order است.
اگر برنامه فقط بگوید:
Order 1001 exists
کافی نیست.
باید بررسی کند:
Does current user own Order 1001?
9. اولین تست IDOR
فرض کنیم در محیط آزمایشگاهی بعد از Login با URL زیر مواجه شدیم:
http://192.168.56.20/profile.php?id=1
حالا در یک آزمایشگاه قانونی، مقدار را بررسی میکنیم:
id=1
و سپس:
id=2
هدف این نیست که اطلاعات دیگران را در دنیای واقعی امتحان کنیم.
هدف این است که ببینیم اپلیکیشن آزمایشگاهی آیا Authorization را درست اعمال میکند یا خیر.
10. تست با Burp Suite
Burp Suite را باز کنید.
یک درخواست نمونه ممکن است شبیه این باشد:
GET /profile.php?id=1 HTTP/1.1
Host: 192.168.56.20
Cookie: PHPSESSID=...
درخواست را به:
Repeater
ارسال کنید.
حالا مقدار Reference را تغییر دهید:
GET /profile.php?id=2 HTTP/1.1
سپس Response را بررسی کنید.
11. چه چیزی باید بررسی کنیم؟
فقط تغییر Status Code کافی نیست.
Response را با درخواست اصلی مقایسه کنید.
بررسی کنید:
Status Code
Response Length
Returned Object
Username
Object ID
Error Message
Redirect
مثلاً:
درخواست اول
id=1
Response:
User: TestUser
ID: 1
درخواست دوم
id=2
اگر پاسخ:
User: AnotherUser
ID: 2
باشد و کاربر فعلی اجازه مشاهده آن را نداشته باشد، یک نشانه بسیار مهم از IDOR وجود دارد.
12. تست صحیح IDOR
یک اشتباه رایج این است که فقط یک ID را تغییر دهیم و سریع نتیجه بگیریم.
تست حرفهای باید سؤالهای بیشتری داشته باشد:
آیا Resource متعلق به کاربر فعلی است؟
آیا کاربر اجازه Read دارد؟
آیا کاربر اجازه Edit دارد؟
آیا کاربر اجازه Delete دارد؟
آیا Server-side Authorization وجود دارد؟
13. Read IDOR
سادهترین حالت:
User A
↓
Request Resource A
↓
Allowed
اما:
User A
↓
Request Resource B
↓
Allowed ❌
در این حالت مشکل در دسترسی خواندن Resource وجود دارد.
14. Write IDOR
مشکل میتواند جدیتر باشد.
فرض کنید کاربر میتواند Resource خودش را ویرایش کند:
POST /profile/update
و در Request یک شناسه وجود دارد:
user_id=1
اگر تغییر این مقدار باعث شود کاربر بتواند Resource متعلق به کاربر دیگری را تغییر دهد، با یک Broken Access Control در عملیات Write روبهرو هستیم.
در محیط آزمایشگاهی باید فقط از دادههای ساختگی استفاده شود.
15. Delete IDOR
سناریوی خطرناکتر:
DELETE /document?id=1
اگر برنامه فقط بررسی کند:
User is logged in?
ولی بررسی نکند:
Does User own document 1?
ممکن است عملیات Delete روی Resource غیرمجاز انجام شود.
این نوع مشکل معمولاً شدت بیشتری نسبت به یک Read ساده دارد.
16. Horizontal Privilege Escalation
یکی از مهمترین مفاهیم این قسمت:
Horizontal Privilege Escalation
فرض کنید:
User A
User B
User C
همگی کاربر عادی هستند.
User A نباید بتواند Resource مربوط به User B را ببیند.
اما:
User A
↓
Change Object ID
↓
User B Resource
↓
Access Granted ❌
این یک نمونه از دسترسی افقی غیرمجاز است.
17. Vertical Privilege Escalation
حالا یک سناریوی دیگر:
Normal User
↓
/admin/delete-user
اگر کاربر معمولی بتواند مستقیماً Endpoint مخصوص Administrator را اجرا کند، مشکل میتواند Vertical Privilege Escalation باشد.
یعنی:
Normal User
↓
Admin Function
↓
Access Granted ❌
18. یک نکته بسیار مهم درباره UI
این تصور اشتباه است:
«اگر دکمه Admin را از صفحه کاربر حذف کنیم، امنیت برقرار است.»
❌ خیر.
مهاجم میتواند Request را مستقیماً ارسال کند.
مثلاً حتی اگر دکمه:
Delete User
برای کاربر نمایش داده نشود، ممکن است Endpoint همچنان قابل دسترسی باشد.
امنیت واقعی باید سمت Server اعمال شود.
19. Client-Side در برابر Server-Side
طراحی ناامن:
Browser
↓
Client-side Check
↓
Server
طراحی صحیح:
Browser
↓
Request
↓
Server
↓
Authentication
↓
Authorization
↓
Resource Ownership Check
↓
Response
هرگز نباید به کنترلهای سمت Client به عنوان مرز امنیتی اصلی اعتماد کرد.
20. IDOR فقط در URL نیست!
یکی از نکات مهم:
IDOR الزاماً به شکل:
?id=123
نیست.
ممکن است Reference در:
URL
/profile/123
Query Parameter
?id=123
JSON
{
"user_id": 123
}
Form Data
document_id=123
Header
یا حتی ساختارهای دیگر API قرار داشته باشد.
بنابراین هنگام تست باید Request کامل را بررسی کنیم.
21. IDOR در API
APIها نیز میتوانند تحت تأثیر Broken Access Control قرار بگیرند.
مثلاً:
GET /api/users/101/orders
کاربر فعلی:
User ID = 101
اگر بتواند:
GET /api/users/102/orders
را ارسال کند و سفارشهای User 102 را دریافت کند، باید Authorization بررسی شود.
22. چرا APIها مهم هستند؟
در برنامههای مدرن، بخش بزرگی از ارتباطات از طریق API انجام میشود.
ممکن است رابط کاربری ظاهراً امن باشد:
Frontend
↓
Everything looks normal
اما API:
/api/resource/123
کنترل دسترسی مناسبی نداشته باشد.
به همین دلیل در تست نفوذ:
فقط ظاهر سایت را بررسی نمیکنیم؛ Request و Response را نیز بررسی میکنیم.
23. Burp Suite و پیدا کردن Referenceها
در Burp Suite → HTTP history درخواستها را بررسی کنید.
دنبال الگوهایی مثل این بگردید:
id=
user_id=
account_id=
order_id=
document_id=
file_id=
ticket_id=
profile_id=
یا:
/users/123
/orders/456
/files/789
اینها لزوماً آسیبپذیری نیستند.
فقط نقاطی هستند که باید Authorization آنها بررسی شود.
24. آیا عددی بودن ID به معنی آسیبپذیری است؟
خیر.
این تصور اشتباه است:
«اگر ID عددی بود، پس سایت IDOR دارد.»
❌ نه.
ممکن است برنامه از:
id=123
استفاده کند ولی سمت سرور بهدرستی بررسی کند:
Current User = 123
Requested Resource = 123
→ Allowed
و:
Current User = 123
Requested Resource = 124
→ Forbidden
در این حالت مشکلی وجود ندارد.
اصل مسئله Authorization است، نه شکل ID.
25. IDهای تصادفی هم امنیت کامل نیستند
گاهی تصور میشود اگر ID را از:
123
به یک مقدار پیچیدهتر تغییر دهیم، مشکل حل میشود.
مثلاً:
8f91c7a2...
این کار میتواند حدس زدن Reference را سختتر کند، اما:
Random بودن ID جای Authorization را نمیگیرد.
حتی اگر Reference غیرقابل حدس باشد، سرور باید مالکیت و مجوز دسترسی را بررسی کند.
26. روش امن پیادهسازی
فرض کنیم درخواست:
GET /invoice/500
دریافت شده است.
Server باید:
1. Identify current user
2. Find invoice 500
3. Check invoice ownership
4. Check authorization
5. Return resource only if allowed
به صورت مفهومی:
Request
↓
Authentication
↓
Find Resource
↓
Ownership Check
↓
Authorization
↓
Allowed / Denied
27. مثال PHP ناامن
یک پیادهسازی فرضی ناامن ممکن است چنین منطقی داشته باشد:
$id = $_GET['id'];
$query = "SELECT * FROM invoices WHERE id = ?";
مشکل اصلی اینجا فقط SQL Injection نیست.
حتی اگر Query کاملاً امن باشد، هنوز باید بررسی شود:
آیا این Invoice متعلق به کاربر فعلی است؟
28. طراحی امنتر
منطق مناسب باید مفهومی شبیه این داشته باشد:
$user_id = $_SESSION['user_id'];
$invoice_id = $_GET['id'];
$query = "
SELECT *
FROM invoices
WHERE id = ?
AND user_id = ?
";
یعنی Resource فقط زمانی برگردانده شود که:
Invoice ID
+
Current User ID
با هم تطابق داشته باشند.
این کد فقط یک نمونه آموزشی است و پیادهسازی نهایی باید با معماری و ORM/Database layer برنامه هماهنگ شود.
29. پاسخ مناسب هنگام عدم دسترسی
اگر کاربر مجوز دسترسی ندارد، برنامه باید دسترسی را رد کند.
مثلاً:
HTTP/1.1 403 Forbidden
یا در بعضی طراحیها:
HTTP/1.1 404 Not Found
انتخاب پاسخ به معماری و نیازهای امنیتی برنامه بستگی دارد.
نکته مهم این است که:
Resource غیرمجاز نباید در Response افشا شود.
30. تفاوت 401 و 403
این دو Status Code را با هم اشتباه نگیرید.
401 Unauthorized
معمولاً یعنی درخواست نیاز به Authentication معتبر دارد.
Not Authenticated
403 Forbidden
کاربر شناسایی شده، اما اجازه انجام آن عملیات را ندارد.
Authenticated
+
Not Authorized
31. تست Access Control در چند مرحله
برای تست حرفهای، سناریوهای مختلف بسازید.
سناریو A
Anonymous User
→ Protected Resource
سناریو B
User A
→ Own Resource
سناریو C
User A
→ User B Resource
سناریو D
Normal User
→ Admin Resource
سناریو E
Expired Session
→ Protected Resource
این تستها دید بسیار بهتری از وضعیت Access Control برنامه میدهند.
32. جدول تست
| تست | انتظار |
|---|---|
| کاربر بدون Login → Resource | Denied |
| User A → Resource خودش | Allowed |
| User A → Resource User B | Denied |
| Normal User → Admin Function | Denied |
| Expired Session → Protected Resource | Denied |
| Admin → Authorized Admin Function | Allowed |
هر اختلاف بین رفتار واقعی و انتظار میتواند نیازمند بررسی بیشتر باشد.
33. سناریوی Dark Lab 🔥
فرض کنید دو حساب آزمایشگاهی داریم:
User A
User B
User A وارد حساب خودش میشود.
در Burp درخواست زیر را مشاهده میکند:
GET /profile?id=1001
حالا درخواست را به Repeater میفرستد.
مقدار را تغییر میدهد:
GET /profile?id=1002
Server پاسخ میدهد:
Profile: User B
Email: test-user-b@example.test
😶
اینجاست که باید متوقف شویم و سؤال اصلی را بپرسیم:
چرا User A اجازه دیدن Resource مربوط به User B را دارد؟
این سؤال، قلب تست Broken Access Control است.
34. از تغییر ID تا اثبات آسیبپذیری
فرآیند حرفهای:
Find Reference
↓
Understand Ownership
↓
Authenticate as User A
↓
Request User A Resource
↓
Change Reference
↓
Request User B Resource
↓
Compare Response
↓
Verify Unauthorized Access
↓
Document Evidence
این مراحل را فقط در محیطی انجام دهید که اجازه تست آن را دارید.
35. اشتباهات رایج در تست IDOR
❌ اشتباه اول
هر ID عددی را آسیبپذیری فرض کنیم.
❌ اشتباه دوم
فقط به URL نگاه کنیم.
❌ اشتباه سوم
Authorization سمت Client را کافی بدانیم.
❌ اشتباه چهارم
تغییر ID را بدون مشخص کردن مالکیت Resource انجام دهیم.
❌ اشتباه پنجم
بدون بررسی Impact، Severity بالا تعیین کنیم.
❌ اشتباه ششم
روی حسابهای واقعی یا کاربران دیگر تست انجام دهیم.
36. چطور IDOR را در گزارش ثبت کنیم؟
فرض کنید در آزمایشگاه یک IDOR واقعی پیدا کردهایم.
عنوان
Insecure Direct Object Reference (IDOR)
Severity
Medium
یا بر اساس Impact:
High
Description
The application does not properly validate whether
the authenticated user is authorized to access the
requested resource.
Affected Component
Profile / API Endpoint
Steps to Reproduce
1. Authenticate as User A.
2. Request User A's resource.
3. Capture the request in Burp Suite.
4. Modify the resource identifier.
5. Send the modified request.
6. Observe that another user's resource is returned.
37. Evidence
برای گزارش حرفهای، Evidence باید حداقل نشان دهد:
Original Request
↓
Original Resource
Modified Request
↓
Unauthorized Resource
اطلاعات حساس واقعی را در گزارش عمومی یا آموزشی منتشر نکنید.
در آزمایشگاه از دادههای ساختگی استفاده کنید.
38. Impact
Impact باید دقیق باشد.
مثلاً:
An authenticated user may access resources
belonging to another user by modifying the
resource identifier.
اگر عملیات Write نیز امکانپذیر باشد:
An authenticated user may potentially modify
resources that belong to another user.
Impact واقعی باید بر اساس چیزی که در محیط مجاز تست شده تعیین شود.
39. Remediation
راهکار اصلی:
Authorization را در سمت Server برای هر درخواست و هر Resource اعمال کنید.
همچنین:
1. Ownership Check
بررسی کنید Resource متعلق به کاربر است یا خیر.
2. Role Check
سطح دسترسی کاربر را بررسی کنید.
3. Least Privilege
هر کاربر فقط حداقل دسترسی مورد نیاز را داشته باشد.
4. Server-Side Enforcement
به کنترلهای Client اعتماد نکنید.
5. Deny by Default
دسترسی باید پیشفرض محدود باشد.
6. Centralized Authorization
منطق Authorization را تا حد امکان متمرکز و قابل تست نگه دارید.
40. Defense in Depth
برای جلوگیری از Broken Access Control بهتر است چند لایه دفاعی وجود داشته باشد:
Authentication
+
Authorization
+
Object Ownership
+
Role Validation
+
Least Privilege
+
Secure Session
+
Logging & Monitoring
هیچکدام بهتنهایی تضمینکننده امنیت کامل نیستند.
41. چکلیست تست Broken Access Control
قبل از پایان تست، این موارد را بررسی کنید:
Authentication
-
کاربر ناشناس به Resource محافظتشده دسترسی ندارد.
-
Session منقضیشده پذیرفته نمیشود.
Horizontal Access
-
User A به Resource User B دسترسی ندارد.
-
User A نمیتواند Resource User B را تغییر دهد.
-
User A نمیتواند Resource User B را حذف کند.
Vertical Access
-
User عادی به Admin Function دسترسی ندارد.
-
Endpointهای Admin سمت Server محافظت شدهاند.
API
-
Object IDها Authorization دارند.
-
Endpointها مالکیت Resource را بررسی میکنند.
-
تغییر Reference باعث افشای داده نمیشود.
42. تمرین عملی قسمت ۱۲
حالا نوبت شماست. 🔥
در یک محیط آزمایشگاهی با دو کاربر ساختگی:
User A
User B
مرحله ۱
با User A وارد شوید.
مرحله ۲
یک Resource متعلق به User A پیدا کنید.
مرحله ۳
Request را در Burp Suite مشاهده کنید.
مرحله ۴
Reference مربوط به Resource را شناسایی کنید.
مرحله ۵
Request را به Repeater بفرستید.
مرحله ۶
Reference را با یک Resource آزمایشگاهی متعلق به User B جایگزین کنید.
مرحله ۷
Response را با درخواست اصلی مقایسه کنید.
مرحله ۸
بررسی کنید آیا:
Access Denied
دریافت میکنید یا:
Unauthorized Access
مرحله ۹
در صورت وجود مشکل، Finding را مستند کنید.
مرحله ۱۰
راهکار اصلاحی را پیشنهاد دهید.
43. قالب گزارش Finding
Title:
Insecure Direct Object Reference (IDOR)
Severity:
Medium / High
Affected Endpoint:
Description:
Authentication Context:
Original Request:
Modified Request:
Evidence:
Steps to Reproduce:
Impact:
Root Cause:
Remediation:
Retest:
Status:
Open / Fixed
44. نکته مهم برای Pentesterها
در تست IDOR، مهمترین سؤال این نیست که:
«آیا میتوانم ID را تغییر دهم؟»
سؤال حرفهای این است:
«آیا تغییر ID باعث میشود یک کاربر بدون مجوز به Resource دیگری دسترسی پیدا کند؟»
این تفاوت بین یک تست سطحی و یک تست حرفهای است.
45. جمعبندی نهایی
در این قسمت با یکی از مهمترین خانوادههای آسیبپذیری وب آشنا شدیم:
Broken Access Control
یاد گرفتیم:
🔐 Authentication با Authorization متفاوت است.
👤 هر کاربر باید فقط به Resourceهایی دسترسی داشته باشد که مجاز است.
🆔 IDOR زمانی رخ میدهد که Reference یک Object مستقیماً قابل تغییر باشد اما Server مالکیت یا مجوز دسترسی را بهدرستی بررسی نکند.
🕵️ Burp Suite میتواند برای تحلیل Request و Response بسیار مفید باشد.
⚠️ عددی بودن ID بهتنهایی آسیبپذیری نیست.
🔒 Random بودن ID نیز جای Authorization را نمیگیرد.
🚫 کنترل دسترسی باید در سمت Server اعمال شود.
و مهمتر از همه:
امنیت واقعی یعنی Server خودش تصمیم بگیرد چه کسی به چه چیزی دسترسی دارد؛ نه اینکه به مرورگر اعتماد کند.

دیدگاه شما