Broken Access Control و IDOR چیست؟ آموزش تست دسترسی غیرمجاز در آزمایشگاه Kali Linux و DVWA

What is Broken Access Control and IDOR
0 دیدگاه
۱۴۰۵-۰۶-۱۶ ۱۹:۲۵:۵۰

☠️ یک عدد ساده می‌تواند درِ حساب کاربر دیگری را باز کند!

تصور کن وارد حساب کاربری خودت شده‌ای.

در 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 خودش تصمیم بگیرد چه کسی به چه چیزی دسترسی دارد؛ نه اینکه به مرورگر اعتماد کند.

دسته بندی‌ها:

آنچه در این مقاله میخوانید

دیدگاه شما

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *