چک‌لیست امنیتی API

داستان ترجمه

به طور خیلی اتفاقی به یه مخزن Github رسیدم که استار خیلی زیادی داشت و داخلش چک‌لیستی از موارد امنیتی مهمی رو که باید در حین طراحی، پیاده‌سازی و دپلوی APIها رعایت کرد، قرار داده بود.

چون کوتاه بود و با خوندنش حس کردم خیلی مفیده، تصمیم گرفتم ترجمش کنم. بعد از این که ترجمه کردم و چند بار مرور و ویرایش کردم، مشکل راست‌به‌چپ کردن فایل مارک‌داون رو حل کردم و بعد دیدم که متاسفانه وقتی با ترفندی که توی استک اورفلو پیدا کرده بودم، فایل مارک‌داون رو راست‌به‌چپ میکنم، checkboxها میافته روی متن! واقعا از دست Github عصبانی بودم و در نهایت با کلی آزمون و خطا و با کمک ;nbsp& مشکل رو حل کردم :)
توی pull requestهای مخزن دیدم که دوتا پول‌رکوئست فعال برای ترجمه‌ی فارسی وجود داره! یکی از پول‌رکوئست‌ها که جدیدتر هم بود ترجمه‌ی خوبی نداشت و مترجم، فایل مارک‌داونش رو راست‌به‌چپ نکرده بود! پول‌رکوئست دومی ترجمه‌ی خوبی داشت (و از بخش‌هایی از ترجمش برای بهتر کردن ترجمه‌ی خودم هم استفاده کردم) و فایل مارک‌داونش هم راست‌به‌چپ بود ولی مشکل روهم‌افتادن checkboxها رو حل نکرده بود. پس خودم یه پول‌رکوئست جدید درست کردم و موارد بالارو داخلش توضیح دادم‌.


لینک مخزن گیت‌هاب چک‌لیست. نگاه کنید و اگه خوشتون اومد استار کنید.

در ادامه‌ی نوشته ترجمه‌ی خود چک‌لیست رو هم قرار میدم چون ویرگول نوشته رو حذف کرد به دلیل تبلیغات و لینک‌سازی! اما توجه داشته باشید که چک‌لیست در واقع یه چیز پویاست که میتونه تغییر کنه و موارد مختلفی به اون اضافه یا کم بشه و اگه واقعا می‌خواین نسخه‌ی بروزش رو ببینید باید از گیتهاب اینکارو بکنید.

https://github.com/mahdavipanah/API-Security-Checklist/blob/add-persian/README-fa.md

چک‌لیست امنیتی API

چک‌لیستی از مهم‌ترین کارهای لازم برای حفظ امنیت در زمان طراحی، تست و انتشار API.

احراز هویت

  • از Basic Auth یا همان اصالت‌سنجی برای دسترسی‌های اولیه استفاده نکن. به جای آن از روش‌های استاندارد احراز هویت استفاده کن (مثلا JWT یا OAuth).
  • برای کارهایی مثل احراز هویت، تولید توکن و ذخیره پسوورد چرخ را دوباره اختراع نکن. از استانداردها استفاده کن.
  • برای لاگین محدودیت‌های تعداد ماکسیمم تلاش مجدد و تعداد دفعات ورود را قرار بده.
  • همه‌ی داده‌های حساس را رمزگذاری کن.

JWT (JSON Web Token)

  • از یک کلید پیچیده‌ی تصادفی برای JWT Secret استفاده کن تا حمله‌ی بروت‌فورس به توکن بسیار سخت باشد.
  • الگوریتم را از هدر استخراج نکن. در بک‌اند الگوریتم را تحمیل کن (HS256 یا RS256).
  • انقضای توکن (TTL یا RTTL) را تا حد ممکن کوتاه کن.
  • اطلاعات حساس را در پی‌لود JWT ذخیره نکن چون به راحتی قابل رمزگشایی است.

OAuth

  • همیشه redirect_uri را در سمت سرور اعتبارسنجی کن تا تنها به URLهای مجاز اجازه داده شود.
  • همیشه تلاش کن تا code را به جای token تبادل کنی (اجازه response_type=token را نده).
  • از پارامتر state با یک هش تصادفی استفاده کن تا از CSRF روی پروسه‌ی احراز هویت OAuth جلوگیری کنی.
  • مقدار scope پیش‌فرض را تعریف کن و پارامترهای scope را برای هر اپلیکیشن اعتبارسنجی کن.

دسترسی

  • رکوئست‌ها را محدود کن (Throttling) تا از حملات DDos یا بروت‌فورس جلوگیری شود.
  • در سمت سرور از HTTPS استفاده کن تا از حملات مرد میانی جلوگیری شود.
  • از هدر HSTS استفاده کن تا از حمله‌ی SSL Strip جلوگیری شود.

ورودی

  • از متد HTTP مناسب با توجه به نوع عملیات استفاده کن: GET برای خواندن، POST برای ایجاد کردن، PUT/PATCH برای جایگزین یا بروزرسانی و DELETE برای حذف یک رکورد، و در صورتیکه متد درخواستی برای منبع درخواست‌شده مناسب نیست با 405 Method Not Allowed پاسخ بده.
  • مقدار content-type را در هدر Accept رکوئست (مذاکره محتوا یا Content Negotiation) اعتبارسنجی کن تا فقط به فرمت‌های مورد پشتیبانی اجازه داده شود (مثلا application/xml، application/json و ...).
  • مقدار content-type در داده‌ی پست‌شده را اعتبارسنجی کن (مثلا application/x-www-form-urlencoded، multipart/form-data، application/json و ...).
  • ورودی کاربر را اعتبارسنجی کن تا از آسیب‌پذیری‌های معمول جلوگیری شود (مثلا XSS، SQL-Injection و Remote Code Execution).
  • هیچ داده‌ی حساسی مثل (داده‌های اعتبارسنجی، پسوورد‌ها، توکن‌های امنیتی یا کلید‌های API) را داخل URL قرار نده و از هدر Authorization استاندارد استفاده کن.
  • از یک سرویس API Gateway استفاده کن تا کش‌کردن و سیاست‌های Rate Limit (مثلا Quota، Spike Arrest یا Concurrent Rate Limit) فعال شوند و منابع APIها را به صورت داینامیک دپلوی کن.

پردازش

  • چک کن که تمامی endpointها توسط احراز هویت محافظت شوند تا از شکستن پروسه‌ی احراز هویت جلوگیری شود.
  • از استفاده از ID ریسورس خود کاربر اجتناب کن. به جای user/654321/orders از /me/orders استفاده کن.
  • از IDهای auto-increment استفاده نکن. به جای آن از UUID استفاده کن.
  • اگر فایل‌های XML را parse میکنی مطمئن شو تا entity parsing غیرفعال باشد تا از XXE (XML External entity attack) جلوگیری شود.
  • اگر فایل‌های XML را parse میکنی، مطمئن شو تا entity expansion غیرفعال باشد تا از Billion Laughs/XML bomb توسط exponential entity expansion attack جلوگیری شود.
  • از یک CDN برای آپلودهای فایل استفاده کن.
  • اگر با مقادیر بسیار حجیمی از داده باید کار کنی، از Workerها و Queueها استفاده کن تا حداکثر پردازش در بک‌گراند انجام شود و سریع پاسخ را برگردان تا از HTTP Blocking جلوگیری شود.
  • خاموش کردن حالت DEBUG را فراموش نکن.

خروجی

  • هدر X-Content-Type-Options: nosniff را ارسال کن.
  • هدر X-Frame-Options: deny را ارسال کن.
  • هدر 'Content-Security-Policy: default-src 'none را ارسال کن.
  • هدرهایی که به نوعی اثرانگشت برجای میگذارند را حذف کن، مثلا X-Powered-By، Server و ‍X-AspNet-Version.
  • مقدار content-type را برای جواب اجباری کن. اگر application/json برمیگردانی، پس content-type پاسخ application/json است.
  • اطلاعات حساس مثل داده‌های اعتبارسنجی، پسوورد‌ها و توکن‌های امنیتی را برنگردان.
  • با توجه به عملیات انجام‌شده، status code مناسب را برگردان. مثلا 200 OK، 400 Bad Request، 401 Unauthorized و 405 Method Not Allowed.

CI & CD

  • طراحی و پیاده سازی خودت را با پوشش تست‌های unit/integration بازرسی کن.
  • از یک پروسه‌ی مرور کد استفاده کن و خود-تاییدی را نادیده بگیر.
  • مطمئن شو تا تمامی اجزای سرویس‌هایت، شامل کتابخانه‌های استفاده‌شده و دیگر وابستگی‌ها، قبل از انتشار در حالت production، به طور ایستا توسط نرم‌افزارهای آنتی‌ویروس اسکن شده‌اند.
  • برای دپلوی، یک راه‌حل با قابلیت عقبگرد (rollback) طراحی کن.

نگاهی بیانداز به:

مشارکت

برای همکاری و کمک می‌توانی به راحتی این مخزن را fork کنی، تغییرات مورد نظرت را اعمال کنی و یک pull request ثب کنی. اگر سوالی داشتی به آدرس team@shieldfy.io ایمیل بزن.