وقتی درخواستها معتبرند، اما نتیجه اشتباه است!
تهیهشده توسط صفر و یک سایبر | آموزش تخصصی امنیت سایبری و هک قانونمند
مقدمه: همه آسیبپذیریها باگ فنی نیستند!
تصور کن یک فروشگاه اینترنتی داری. کاربر وارد حسابش میشود، محصولی انتخاب میکند و سفارش ثبت میکند. تمام درخواستها از نظر ساختار HTTP معتبرند؛ احراز هویت هم درست کار میکند و هیچ خطای متداولی مثل SQL Injection وجود ندارد.
اما یک مشکل وجود دارد: سامانه اجازه میدهد کاربر از یک کد تخفیف چند بار استفاده کند، مرحلهای از فرایند خرید را دور بزند یا موجودی یک محصول را بیش از مقدار واقعی مصرف کند.
اینجا ممکن است با یک Business Logic Vulnerability روبهرو باشیم؛ آسیبپذیریای که از ضعف در قوانین و منطق کسبوکار ناشی میشود، نه لزوماً از یک خطای نحوی در کد.
در این قسمت یاد میگیریم چطور چنین ضعفهایی را در یک محیط آزمایشگاهی و با رویکرد یک متخصص تست نفوذ شناسایی کنیم.
بخش اول: آسیبپذیری منطق کسبوکار چیست؟
Business Logic Vulnerability زمانی رخ میدهد که برنامه قوانین مورد انتظار خود را بهدرستی اعمال نکند.
برای مثال، سامانه باید این قوانین را رعایت کند:
- هر کد تخفیف فقط یک بار برای هر حساب قابل استفاده باشد.
- کاربر نتواند سفارشی را که هنوز پرداخت نشده، تحویلشده اعلام کند.
- قیمت نهایی محصول در سمت سرور محاسبه شود.
- موجودی محصول هرگز بهصورت غیرمجاز منفی نشود.
- کاربر فقط مجاز به تغییر منابع متعلق به خودش باشد.
اگر بتوان با ترکیب درخواستهای معتبر، ترتیب غیرمنتظره عملیات یا تغییر پارامترها این قوانین را نقض کرد، ممکن است یک ضعف منطقی وجود داشته باشد.
نکته تخصصی: معتبر بودن یک درخواست HTTP به معنی مجاز بودن نتیجه تجاری آن نیست.
بخش دوم: انواع رایج ضعفهای Business Logic
۱. دور زدن ترتیب مراحل
فرض کن یک سامانه این گردش کار را دارد:
ثبت سفارش ← پرداخت ← تأیید سفارش ← ارسال
اگر سرور فقط به رابط کاربری اعتماد کند و بررسی نکند که پرداخت واقعاً انجام شده است، ممکن است مرحله تأیید بدون تحقق پیششرط لازم انجام شود.
در تست نفوذ باید بررسی کنی آیا سرور خودش ترتیب مراحل و وضعیت فعلی سفارش را اعتبارسنجی میکند یا خیر.
۲. دستکاری مقادیر تجاری
فرض کن درخواست خرید شامل تعداد محصول است:
quantity = 1
سرور باید تعداد را از نظر نوع داده، محدوده مجاز، موجودی و قوانین سفارش بررسی کند. اعتبارسنجی صرفاً در مرورگر کافی نیست؛ کاربر میتواند درخواست خودش را تغییر دهد.
همین اصل برای قیمت، مبلغ، شناسه تخفیف، وضعیت سفارش و سایر دادههای حساس صدق میکند.
۳. استفاده چندباره از یک مزیت
سامانهای را در نظر بگیر که یک اعتبار آزمایشی یا کد تخفیف را فقط یک بار مجاز میداند. اگر این محدودیت صرفاً در رابط کاربری اعمال شده باشد، امکان دارد منطق سمت سرور آن را بهدرستی اجرا نکند.
هدف تستر، بررسی قانون یکبارمصرف بودن است؛ نه سوءاستفاده از اعتبار واقعی یا انجام تراکنش در سامانه دیگران.
بخش سوم: Race Condition چیست؟
<text>Race Condition</text> یا وضعیت رقابتی زمانی رخ میدهد که نتیجه عملیات به زمانبندی و ترتیب اجرای درخواستهای همزمان وابسته باشد.
برای نمونه، فرض کن در یک آزمایشگاه محلی فقط یک واحد از محصول باقی مانده است.
دو درخواست خرید تقریباً همزمان دریافت میشوند. اگر هر دو درخواست موجودی را قبل از ثبت کاهش آن بخوانند، ممکن است سامانه هر دو سفارش را موفق اعلام کند؛ درحالیکه موجودی اولیه فقط یک واحد بوده است.
<text>موجودی اولیه: ۱</text>
<text>درخواست A: بررسی موجودی ← موجودی کافی است</text>
<text>درخواست B: بررسی موجودی ← موجودی کافی است</text>
<text>نتیجه ناامن احتمالی: دو سفارش موفق برای یک واحد</text>
این مثال یک سناریوی مفهومی است؛ نتیجه واقعی به معماری برنامه، پایگاه داده و نحوه مدیریت تراکنشها بستگی دارد.
تفاوت Business Logic و Race Condition
- Business Logic: قوانین کسبوکار بهدرستی تعریف یا اجرا نشدهاند.
- Race Condition: اجرای همزمان عملیات باعث میشود وضعیت سامانه برخلاف انتظار تغییر کند.
این دو مفهوم میتوانند با هم همپوشانی داشته باشند؛ برای مثال، یک ضعف در منطق رزرو موجودی ممکن است بهواسطه درخواستهای همزمان آشکار شود.
بخش چهارم: سناریوی عملی امن در آزمایشگاه
آزمایشگاه Zero Logic Lab
هدف: بررسی رفتار یک API آزمایشی در برابر درخواستهای متوالی و همزمان.
این تمرین را فقط روی برنامه محلی خودت یا محیط آموزشیای انجام بده که مجوز تست آن را داری. از حساب، موجودی، اعتبار یا تراکنش واقعی استفاده نکن.
مرحله اول: تعریف قوانین مورد انتظار
یک API آزمایشی فروشگاه در نظر بگیر که از دادههای ساختگی استفاده میکند.
قوانین آزمایشگاه:
- موجودی اولیه محصول برابر یک واحد است.
- موجودی نباید منفی شود.
- هر سفارش باید پیششرطهای لازم را داشته باشد.
- قیمت نهایی باید توسط سرور تعیین شود.
- یک عملیات تکراری نباید باعث ثبت ناخواسته سفارش دوم شود.
این قوانین را قبل از شروع آزمایش یادداشت کن؛ بدون تعریف رفتار مورد انتظار، تشخیص آسیبپذیری دشوار است.
مرحله دوم: بررسی درخواست عادی با Burp Suite
۱. برنامه محلی را اجرا کن.
۲. یک سفارش آزمایشی با دادههای ساختگی ایجاد کن.
۳. در Burp Suite به بخش HTTP History برو.
۴. درخواست مربوط به ایجاد سفارش را پیدا کن و موارد زیر را بررسی کن:
- مسیر و متد درخواست
- پارامترهای تعداد و شناسه محصول
- اطلاعات احراز هویت
- پاسخ سرور و کد وضعیت HTTP
- شناسه سفارش و تغییر وضعیت موجودی
۵. درخواست و پاسخ را در گزارش آزمایشگاه ثبت کن.
مرحله سوم: تست قوانین تجاری
در محیط آزمایشی، با مقادیر بیخطر و دادههای ساختگی بررسی کن:
- آیا تعداد صفر یا مقدار منفی رد میشود؟
- آیا تغییر قیمت ارسالی از سمت کاربر روی قیمت نهایی اثر میگذارد؟
- آیا سفارش بدون پیششرط لازم تأیید میشود؟
- آیا تکرار یک درخواست باعث ایجاد عملیات تکراری میشود؟
پاسخ منفی به یکی از این پرسشها بهتنهایی اثبات آسیبپذیری نیست؛ باید رفتار مورد انتظار سامانه و پاسخ واقعی آن را مقایسه کنی.
مرحله چهارم: بررسی Race Condition
برای بررسی همزمانی، از یک endpoint آزمایشگاهی که خودت کنترل میکنی استفاده کن.
۱. موجودی را به یک واحد بازگردان.
۲. وضعیت اولیه پایگاه داده و تعداد سفارشها را ثبت کن.
۳. در محیط محلی، دو درخواست آزمایشی را با فاصله زمانی بسیار کم اجرا کن.
۴. نتیجه هر درخواست، تعداد سفارشهای ثبتشده و موجودی نهایی را بررسی کن.
۵. آزمایش را با دادههای تازه تکرار کن تا نتیجه تصادفی با یک نقص قابل بازتولید اشتباه گرفته نشود.
محدودیت ایمنی: این آزمایش را با دو درخواست کنترلشده و در محیط خودت انجام بده؛ نیازی به بار زیاد، تست انکار سرویس یا ارسال درخواست به سامانه عمومی نیست.
اگر آزمایشگاه اختصاصی نداری، همین سناریو را ابتدا بهصورت یک مدل مفهومی روی کاغذ طراحی کن؛ هیچ درخواست واقعی لازم نیست.
بخش پنجم: چطور یافته را گزارش کنیم؟
یک گزارش تست نفوذ حرفهای باید از حدس و گمان فراتر برود.
| بخش گزارش | اطلاعات لازم |
|---|---|
| عنوان | احتمال ثبت سفارش تکراری در عملیات همزمان |
| پیششرط | یک واحد موجودی در محیط آزمایشگاهی |
| دارایی آزمایشی | شناسه محصول ساختگی |
| روش بررسی | دو درخواست کنترلشده |
| نتیجه مورد انتظار | حداکثر یک سفارش موفق |
| نتیجه مشاهدهشده | تعداد سفارش و موجودی واقعی پس از آزمایش |
| شواهد | درخواستها، پاسخها و وضعیت پایگاه داده |
| اثر احتمالی | ناسازگاری موجودی یا ثبت سفارش تکراری |
| پیشنهاد اصلاح | کنترل اتمیک موجودی و تراکنش پایگاه داده |
شدت آسیبپذیری را بر اساس شواهد، قابلیت تکرار، اثر واقعی و محدودیتهای سامانه تعیین کن؛ صرف مشاهده یک پاسخ غیرعادی برای اعلام شدت بحرانی کافی نیست.
بخش ششم: راهکارهای دفاعی
برای Business Logic
- قوانین حساس را در سمت سرور اعتبارسنجی کن.
- هر مرحله را فقط در صورت تحقق پیششرطهای معتبر اجرا کن.
- قیمت و تخفیف را در سمت سرور محاسبه کن.
- مالکیت منابع و مجوز هر عملیات را مستقل بررسی کن.
- برای عملیات حساس، وضعیت مجاز قبلی و بعدی را مشخص کن.
برای Race Condition
- عملیات خواندن و تغییر موجودی را در تراکنش امن انجام بده.
- از قفلگذاری مناسب یا بهروزرسانی اتمیک استفاده کن.
- در پایگاه داده محدودیتهایی تعریف کن که وضعیت نامعتبر را رد کنند.
- برای عملیات تکرارپذیر از سازوکارهای Idempotency استفاده کن.
- نتیجه نهایی را با وضعیت پایگاه داده تطبیق بده؛ فقط به پاسخ موفق یک درخواست تکیه نکن.
نکته کلیدی: کنترل همزمانی باید در لایهای اجرا شود که بتواند تغییرات واقعی داده را تضمین کند؛ غیرفعال کردن یک دکمه در رابط کاربری، راهکار امنیتی کافی نیست.
چالش قسمت پانزدهم
برای یک فروشگاه آزمایشی، سه قانون امنیتی بنویس و برای هرکدام این موارد را مشخص کن:
۱. رفتار مورد انتظار چیست؟
۲. چه ورودی یا ترتیبی ممکن است قانون را نقض کند؟
۳. چه شواهدی برای اثبات مشکل نیاز داری؟
۴. اصلاح باید در کدام بخش سامانه انجام شود؟
در پایان، یک گزارش کوتاه با عنوان «بررسی منطق کسبوکار و همزمانی در Zero Logic Lab» تهیه کن.
جمعبندی
در تست نفوذ حرفهای، فقط دنبال ورودی مخرب یا خطای فنی نیستیم؛ باید بررسی کنیم آیا سامانه در تمام شرایط، قوانین واقعی خودش را رعایت میکند یا نه.
گاهی خطرناکترین باگ، همان درخواستی است که از نظر فنی کاملاً عادی به نظر میرسد، اما نتیجهای ایجاد میکند که نباید امکانپذیر باشد.
صفر و یک سایبر | فراتر از پیدا کردن باگ؛ درک منطق پشت سامانه.

دیدگاه شما