در نگاه اول، محدودسازی نرخ تقریباً میتواند غیرمنطقی به نظر برسد. ما تمام این زمان را صرف باز کردن محصول یا سرویس خود از طریق یک API میکنیم، فقط برای اینکه وقتی کاربران درخواستهای بیش از حد ارسال میکنند، یک «آه آه آه» و انگشت تکاندهنده — به سبک دنیس ندری در پارک ژوراسیک — اجرا کنیم.
اگر مشخص نکنیم «بیش از حد» یعنی چه، خطر ناامید کردن کاربران را داریم. اما وقتی آن را شفاف اعلام میکنیم، خطر باز گذاشتن APIهایمان برای بازیگران بد را داریم. این فقط یکی از بخشهای چیزی است که تیم Zuplo، یک پلتفرم دروازه و مدیریت API، آن را «هنر ظریف محدودسازی نرخ» نامیدهاند. در واقع، آنها حفاظتی که محدودسازی نرخ میتواند ارائه دهد را یکی از سه ستون برنامه API خود میدانند.
نیت توتن از Zuplo در اجلاس API آستین ما در سال ۲۰۲۴ به ما پیوست و در آنجا بهطور گسترده درباره تعادل بین تجربه مصرفکننده و عملکرد صحبت کرد. در ادامه، نکات کلیدی صحبت او را همراه با برخی اشتباهات بزرگ در زمینه محدودسازی نرخ پوشش میدهیم…
چرا به محدودسازی نرخ نیاز داریم؟
از مفاهیم اولیه محدودسازی نرخ API گرفته تا بررسی عمیق الگوریتمهای مختلف برای پیادهسازی محدودسازی نرخ. اگر به ندرت از محدودسازی نرخ استفاده نمیکنید، حتماً آنها را بررسی کنید.
توتن در ابتدای سخنرانیاش بهصورت بلاغی میپرسد: «آیا واقعاً مورد حمله قرار میگیرم؟» پاسخ او این است: «بله، اما نه توسط کسی که فکر میکنید.» یک حلقه for ناشیانه، پیشنهاد میدهد توتن، یا خطای دیگری از طرف شما میتواند باعث شود خودتان API خود را بمباران کنید… و صورتحسابهای سنگینی دریافت کنید.
محدودسازی نرخ برای محافظت از مصرف منابع عالی است. اما با همه این حرفها، بازیگران بدی هم هستند که به دنبال سوءاستفاده از APIهایی هستند که فاقد محدودسازی نرخاند. متأسفانه به نظر میرسد برخی شرکتها این یادداشت را دریافت نکردهاند.
نمونهای از نقض امنیتی مرتبط با محدودسازی نرخ
در ابتدای سال ۲۰۲۴، نقض امنیتی ترلو منجر به نشت بیش از ۲۱ گیگابایت داده شد، از جمله بیش از ۱۵ میلیون آدرس ایمیل کاربران. هکری به نام «emo» به BleepingComputer گفت که این اطلاعات با استفاده از یک API REST بدون امنیت به دست آمده است.
بهطور خاص، emo فهرستی شامل ۵۰۰ میلیون آدرس ایمیل را به API (که توسط توسعهدهندگان برای پرسوجو درباره اطلاعات عمومی پروفایلهای ترلو استفاده میشود) تزریق کرد تا بررسی کند آیا به حساب ترلو متصل هستند یا نه. با استفاده از اطلاعات حساب برگشتی، توانستند پروفایلهایی برای ۱۵ میلیون کاربر ایجاد کنند.
ترلو از آن زمان محدودیتهای نرخ را در اطراف APIهای خود سختتر کرده است. با این حال، این واقعیت که کسی توانسته بود ۵۰۰ میلیون آدرس ایمیل را فراخوانی کند — عددی بسیار بزرگتر از چیزی که هر کسی که درخواست قانونی میدهد واقعاً نیاز داشته باشد — باعث تعجب خیلیها شده است.
۱. محدودسازی نرخ را شفاف و قابل مشاهده کنید
پاسخهای استاندارد (Canonical) کاملاً ساده هستند. برای مثال:
- Status – ۴۲۹
- Status Text – Too Many Requests
- Header – Retry-After: 3600
- Body – Use Problem Details format (IETF RFC 7807)
با این حال، توتن اذعان میکند که افشای محدودیتها (مانند ۳۶۰۰ که در هدر بالا نشان داده شده) کار را برای کاربران مخرب آسانتر میکند تا مصرف منابع را بدون برخورد با محدودیت به حداکثر برسانند. از طرف دیگر، عدم افشای آنها باعث میشود مصرفکنندگان قانونی به سختی بتوانند از آن اجتناب کنند.
او پیشنهاد میکند که رسمی بودن رابطه شما با کاربران میتواند میزان اطلاعاتی که با آنها به اشتراک میگذارید را تعیین کند. برای مثال، اطلاعات محدودسازی نرخ را برای سطوح رایگان افشا نکنید. در عوض، فقط برای شرکای قراردادی افشا کنید. با این حال، او تأکید میکند که بازیگران بد احتمالاً به هر حال میتوانند این اطلاعات را کشف کنند.
توتن میگوید دیدهپذیری یک عامل کلیدی است که باید در کل فرآیند محدودسازی نرخ در نظر گرفته شود: «وقتی محدودسازی نرخ را به API خود اضافه کنید، درخواستهای پشتیبانی زیادی دریافت خواهید کرد… بهخصوص اگر آن را در جایی اضافه کنید که قبلاً وجود نداشته است.» او ادامه میدهد: «در دنیای ایدهآل، هم شما بهعنوان توسعهدهنده و هم مشتریانتان باید دیدی نسبت به آنچه در سیستم در جریان است داشته باشید.»
در این زمینه، دیدهپذیری یعنی بررسی مواردی مانند درخواست در ثانیه (RPS)، تفکیک درخواستها بر اساس باکت (مانند IP یا کاربر)، و پاسخهای محدود شده. میتوانید این اطلاعات را با کاربرانی که به آنها اعتماد دارید به اشتراک بگذارید، همانطور که ممکن است آپتایم یا وضعیت سرور را به اشتراک بگذارید. هرچه شفافیت بیشتری درباره نحوه استفاده از API به آنها بدهید، درخواستهای پشتیبانی مربوط به محدودسازی نرخ (و مسائل دیگر) کمتر خواهد شد.
۲. تعادل بین بهینهسازی و تأخیر (Latency)
چه بهعنوان توسعهدهنده و چه مصرفکننده، همه ما میخواهیم APIها ویژگیهای خاصی داشته باشند: سرعت، قابلیت اطمینان (آپتایم بالا)، کاربری خوب و امنیت. اما گاهی بهبود یکی از این ویژگیها میتواند به دیگری آسیب بزند.
برای مثال، محدودسازی نرخ بر اساس IP خطر تنبیه کسانی را دارد که آدرس مشترک دارند (مانند سرویسهایی که از یک دیتاسنتر یا حتی یک فضای WeWork کار میکنند). محدودسازی بر اساس کاربر یا اپلیکیشن ممکن است برای توسعهدهنده سنگینتر باشد، اما تجربه کاربری کلی را بهبود میبخشد.
به همین ترتیب، توتن اشاره میکند که انجام بررسی محدودسازی نرخ قبل از اجازه دادن به درخواست، باعث میشود API برای همه کندتر شود زیرا تأخیر را به هر درخواست تحمیل میکند. او رویکرد ملایمتری پیشنهاد میکند: اجرای بررسیها بهصورت ناهمزمان و کش کردن کاربران مسدود شده:
- مصرفکنندگان شناختهشده (و زمان تلاش مجدد) را در کش محلی ذخیره کنید.
- بررسی محدودسازی نرخ را موازی با انجام درخواست اصلی انجام دهید.
- اگر بررسی محدودسازی نرخ برگشت و مسدود بود، کش را بهروزرسانی کنید و (اگر درخواست اصلی هنوز کامل نشده) پاسخ را نادستورالعمل کنید.
- در غیر این صورت، درخواست بعدی به هر حال مسدود خواهد شد.
عیب؟ توتن اذعان میکند که «مقدار معینی از درخواستها از سقف مجاز عبور خواهند کرد.» اما او استدلال میکند که این معامله معمولاً ارزشش را دارد. او میگوید: «به جای اینکه هر درخواست تکتک این جریمه را بپردازد، میتوانیم عملکرد را افزایش دهیم و تأخیر را کاهش دهیم.»
۳. محدودسازی نرخ همه چیز نیست
در جولای ۲۰۲۴، گروه هکری NullBulge بیش از ۱.۱ ترابایت داده Slack دیزنی را منتشر کرد (که ادعا میشود شامل پروژههای منتشرنشده، تصاویر خام و کد، و لینکهایی به APIها/صفحات وب داخلی است). در واقع، به نظر میرسد بیشتر اطلاعات منتشرشده نسبتاً بیخطر باشند — یک ترابایت عکس سگهای تصادفی، میم و اسکرینشات، طبق نظر برخی کامنتگذاران.
هرچند دیزنی از آن زمان انگشت اتهام را به سمت یک فرد داخلی نشانه رفته، اما نظریه اولیهای که در زمان نگارش این مقاله در گردش بود پیشنهاد میکرد — مانند مورد ترلو — نشت ممکن است به دلیل یک نقطه انتهایی API Slack بدون امنیت بوده باشد.
در واقع، Slack از قبل محدودسازی نرخ را روی APIهای خود اعمال کرده و ویژگیهای DLP برای جلوگیری از نشت داده ارائه میدهد. با این حال، بدیهی است که ما از میزان استفاده دیزنی از این ویژگیها یا پشته امنیتی گستردهتر آنها اطلاع نداریم.
با این وجود، جالب است که یک هکر همچنان توانسته هزاران فراخوانی در ساعت در چارچوب محدودسازی نرخ Slack انجام دهد. در واقع، آنها میتوانستند تمام ۱۶۷۳۵ فایل موجود در تورنت بالا را در کمتر از سه ساعت جمعآوری کنند. یادآوری خوبی که محدودسازی نرخ به تنهایی یک راهحل جادویی نیست.
هرچند محدودسازی نرخ میتواند بسیار مفید باشد، اما باید فقط بهعنوان یکی از جنبههای رویکرد شما به امنیت API در نظر گرفته شود. برای یک API واقعاً امن، باید بهترین شیوههای دیگر را نیز دنبال کنید، مانند استفاده از دروازه، OAuth، انجام ممیزی و تستهای منظم و غیره.
