OWASP API Security Top 10: 0xa4 unrestricted resource consumption

# API4:2023 استفاده نامحدود از منابع

| ضعف امنیتی | عوامل تهدید / مسیر حمله | پیامد |
|---------|--------------------|------------|
| خاص API / قابلیت بهره‌برداری: متوسط |  میزان شیوع: گسترده/ قابلیت تشخیص: آسان              | پیامد فنی: شدید / خاص کسب و کار     |
|بهره برداری از این آسیب‌پذیری نیاز به ارسال درخواست‌های ساده‌ای به سوی API دارد. کافی است تعدادی درخواست هم‌زمان از یک ماشین و یا با استفاده از منابع رایانش ابری به سوی API ارسال گردد تا بتوان از این آسیب‌پذیری بهره برد. اکثر ابزارهای خودکاری که موجود هستند، به منظور ایجاد حمله DoS از طریق بارگذاری حجم زیادی از ترافیک طراحی شده‌اند که این کار می‌تواند به سرویس‌دهی APIها آسیب رسانده و سرعت آن‌ها را کاهش دهد.|یافتن APIهایی که محدودسازی نرخ ارسال را بکار نگرفته یا محدودیت‌های اعمال شده آنها ناکافی است، کار دشواری نیست.  برای شناسایی این مشکل، مهاجمان می‌توانند درخواست‌های API را با پارامترهای خاصی طراحی کنند که تعداد منابعی را که API باز می‌گرداند، تغییر دهند. سپس با تجزیه و تحلیل وضعیت، زمان، و طول پاسخ‌های دریافتی، مشکل را شناسایی کنند. این موضوع برای عملیات‌های دسته‌ای هم صدق می‌کند. مهاجمان می‌توانند درخواست‌های دسته‌ای را با تغییر تعداد منابعی که در هر درخواست بازگشت داده می‌شوند، ارسال کرده و با ایجاد بارگذاری نامتعادل، اثرات منفی بر روی سرویس API ایجاد کنند. ممکن است مهاجمان اطلاعی از هزینه‌های اقتصادی حملات خود برای ارائه‌دهندگان خدمات نداشته باشند، اما می‌توانند با تحلیل مدل تجاری و قیمت‌گذاری خدمات، اثرات مالی این حملات را تخمین بزنند. |بهره برداری از این آسیب‌پذیری می‌تواند منجر به بروز DoS شده، در نتیجه API را از پاسخ به درخواست‌ها باز دارد و یا حتی آن را از دسترس خارج نماید. استفاده از این آسیب‌پذیری می‌تواند به دو شکل تأثیر منفی داشته باشد. اولاً، می‌تواند منجر به حمله DoS شده و منابع سیستم را اشغال کند. دوماً، به دلیل افزایش تقاضا بر روی واحدهای پردازشی، افزایش نیاز به فضای ذخیره‌سازی ابری و موارد مشابه می‌تواند منجر به افزایش هزینه‌های عملیاتی مرتبط با زیرساخت شود.|

### آیا API از نظر مصرف بدون محدودیت منابع ‌‌آسیب‌پذیر است؟

درخواست‌‌های ارسال شده به سوی API منابعی از قبیل پهنای باند شبکه، پردازنده، حافظه و فضای ذخیره‌سازی را مصرف می‌کنند. برخی از منابع مورد نیاز برای اجرای درخواست‌های API از طریق دیگر ارائه‌دهندگان خدمات API فراهم می‌شوند. این منابع ممکن است شامل ارسال ایمیل، پیام متنی، تماس تلفنی یا اعتبارسنجی بیومتریک و موارد مشابه باشند.
اگر دست‌کم یکی از محدودیت‌‌های زیر در سمت API به کلی اعمال نشده یا بطور نادرست (مثلا بیش از حد زیاد یا بیش از حد کم) ‌‌‌‌پیاده‌سازی شده باشد آنگاه API از منظر محدودیت یا کمبود نرخ ارسال، ‌‌آسیب‌پذیر خواهد بود:
-	Time Out اجرا 
-	حداکثر میزان حافظه قابل تخصیص
-	حداکثر تعداد توصیف‌گر  فایل‌‌ها
-	حداکثر تعداد پردازه‌‌ها
-	حداکثر سایز بارگزاری فایل
-	تعداد فراخوانی‌هایی که یک کلاینت می‌تواند در یک درخواست واحد انجام دهد (مانند GraphQL batching)
-	تعداد رکوردهای بازگردانده شده در هر صفحه
-	حداکثر هزینه‌ای که ارائه‌دهندگان خدمات شخص ثالث می‌توانند از مشتریان دریافت کنند 

## مثال‌‌هایی از سناریوهای حمله

### سناریو #1

یک شبکه اجتماعی بخش "فراموشی رمز عبور" را با استفاده از روش تأییدیه پیامکی پیاده‌سازی کرده است. کاربر پس از دریافت یک توکن یک‌بار مصرف از طریق پیامک، می‌تواند رمز عبور خود را بازنشانی کند. با کلیک بر روی گزینه "فراموشی رمز عبور"، API مرتبط از مرورگر کاربر به API Back-End ارسال می‌شود:

```
POST /initiate_forgot_password

{
  "step": 1,
  "user_number": "[PII_REDACTED]"
}
```

در پس‌زمینه، یک تماس API از سمت سرور به یک API از شخص ثالثی که وظیفه تحویل پیامک را دارد، ارسال می‌شود:

```
POST /sms/send_reset_pass_code

Host: willyo.net

{
  "phone_number": "[PII_REDACTED]"
}
```
سرویس دهنده طرف ثالث با نام willyo ، برای هر تماس از این نوع، مبلغ ۰.۰۵ دلار هزینه می‌کند. مهاجم اسکریپتی می‌نویسد که اولین تماس API را ده‌ها هزار بار ارسال می‌کند. سپس بخش پشتیبانی از طریق درخواست از willyo می‌خواهد تا ده‌ها هزار پیام متنی ارسال کند که سبب می‌شود تا در عرض چند دقیقه هزاران دلار را از دست بدهد.

### سناریو #2

کاربر از طریق GraphQL API می‌تواند تصویر پروفایل خود را بارگذاری کند

```
POST /graphql

{
  "query": "mutation {
    uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {
      url
    }
  }"
}
```
بعد از اتمام عملیات بارگذاری تصویر توسط کاربر، API چندین تصویر کوچک با اندازه‌های مختلف از روی تصویر اصلی ایجاد می‌کند. این عملیات گرافیکی نیاز به حافظه زیادی از سرور دارد. API مذکور، از مکانیزم محدودیت نرخ سنتی استفاده می‌کند، به این معنا که یک کاربر نمی‌تواند در یک دوره زمانی کوتاه تعداد زیادی درخواست به تابع انتهایی GraphQL ارسال کند. همچنین، قبل از ایجاد تصاویر کوچک از تصویر بارگذاری شده، اندازه تصویر بارگذاری شده را بررسی می‌کند تا از پردازش تصاویری که بسیار بزرگ هستند جلوگیری کند. مهاجم می‌تواند با ارسال درخواست‌های مختلف و با حجم زیاد، از این مکانیزم‌ها عبور کرده و به تابع انتهایی GraphQL دسترسی پیدا کند:

```
POST /graphql

[
  {"query": "mutation {uploadPic(name: \"pic1\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
  {"query": "mutation {uploadPic(name: \"pic2\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
  ...
  {"query": "mutation {uploadPic(name: \"pic999\", base64_pic: \"R0FOIEFOR0xJVA…\") {url}}"},
}
```
به علت عدم محدودیت در تعداد دفعات انجام عملیات uploadPic، این تماس منجر به اشغال حافظه سرور و وقوع DoD خواهد شد.

### سناریو #3

یک سرویس دهنده، به مشتریان اجازه می‌دهد که با استفاده از API آنها، فایل‌هایی با حجم دلخواه دانلود کنند. این فایل‌ها در فضای ابری ذخیره شده و اغلب تغییری نمی‌کنند. این سرویس دهنده برای بهبود نرخ ارائه خدمات و کاهش مصرف پهنای باند به یک سرویس حافظه‌پنهان مورد اعتماد نیاز دارد. این سرویس فقط فایل‌هایی را ذخیره می‌کند که حداکثر ۱۵ گیگابایت حجم دارند. اگر یکی از فایل‌ها بروزرسانی شده و اندازه آن به ۱۸ گیگابایت افزایش ‌یابد، همه مشتریان سرویس فورا نسخه جدید را دریافت می‌کنند. از آنجا که هیچ هشداری در مورد هزینه مصرفی وجود نداشته و مقدار حداکثری برای هزینه سرویس ابری تعیین نشده بود، صورت‌حساب ماهیانه بعدی از ۱۳ دلار به طور میانگین به ۸ هزار دلار افزایش می‌یابد.

## چگونه از ‌‌آسیب‌پذیری مصرف بدون محدودیت منابع پیشگیری کنیم؟

- محدودسازی [حافظه][1]، [پردازنده][2]، [تعداد دفعات راه اندازی مجدد][3]، [توصیف‌گرهای فایل][4] و پردازه‌‌ها با استفاده از کانتینرها یا کد بدون سرور (مانند Lambdas).
- تعریف و اِعمال بیشینه اندازه داده (نظیر بیشینه طول برای رشته‌‌ها یا بیشینه تعداد عناصر در آرایه‌‌ها) در درخواست‌‌ها و محموله‌‌های ورودی.
- اعمال محدودیت بر تعداد دفعات تعامل با API در یک دوره زمانی مشخص (محدودیت نرخ).
- محدودیت نرخ باید بر اساس نیازهای کسب و کار بهبود یابد.
- محدود کردن تعداد دفعات اجرای عملیات مربوط به یک API توسط یک مشتری/کاربر در زمان مشخص.
- اجرای یک فرآیند اعتبارسنجی دقیق در طرف سرور برای پارامترهایی که به صورت متغیر در رشته‌های پرس‌وجو وجود دارند.
- پیکربندی محدودیت‌ مقدار مصرف برای تمام سرویس دهندگان API. اگر تنظیم محدودیت‌ مقدار مصرف امکان‌پذیر نیست، به جای آن باید هشدارهای مالی پیکربندی شوند.

## مراجع

- [Web Service Security Cheat Sheet - OWASP][5]
- [DoS Prevention - GraphQL Cheat Sheet][6]
- [Mitigating Batching Attacks - GraphQL Cheat Sheet][7]

### خارجی

- [CWE-770: Allocation of Resources Without Limits or Throttling][8]
- [CWE-400: Uncontrolled Resource Consumption][9]
- [CWE-799: Improper Control of Interaction Frequency][10]
-	“Rate Limiting (Throttling)” - [Security Strategies for Microservices-based App