گذار از معماریهای تکتوده به محاسبات سرورلس، نحوه ساخت برنامههای مقیاسپذیر ما را دگرگون کرده است. با سرویسهایی مانند AWS Lambda و Azure Functions، توسعهدهندگان میتوانند صرفاً بر روی کد تمرکز کنند بدون اینکه نیاز به مدیریت زیرساختهای زیرین داشته باشند. با این حال، این انتزاع یک پارادایم امنیتی منحصربهفرد را معرفی میکند. برچسب «سرورلس» اغلب منجر به احساس کاذب امنیت میشود و آسیبپذیریهای حیاتی ناشی از پیکربندیهای نادرست، مجوزهای بیش از حد و وابستگیهای ناامن را پنهان میکند.
در این راهنما، ما رایجترین بردارهای حمله که توابع سرورلس را هدف قرار میدهند را کالبدشکافی کرده و استراتژیهای عملی برای سختسازی محیط خود ارائه میدهیم. چه در AWS و چه در Microsoft Azure مستقر باشید، اصول «اعتماد صفر» و «کمترین امتیاز» همچنان حیاتی هستند.
تغییر در سطح حمله: درک ریسکهای سرورلس
امنیت برنامههای سنتی تمرکز شدیدی بر دفاع از مرز شبکه، مانند فایروالها و سیستمهای تشخیص نفوذ دارد. در معماریهای سرورلس، مرز شبکه از بین میرود. منطق برنامه در سراسر کانتینرهای زودگذری توزیع شده است که بر اساس نیاز بالا و پایین میشوند. در نتیجه، سطح حمله به خود کد، منابع رویدادی که توابع را فعال میکنند و سیاستهای مدیریت هویت و دسترسی (IAM) که آنها را حاکم میکنند، تغییر میکند.
آسیبپذیریهای رایج اغلب به OWASP Top 10 شباهت دارند، اما با چاشنی سرورلس. حملات تزریق (SQLi، تزریق دستور) زمانی که ورودی کاربر مستقیماً به سرویسهای زیرین بدون پاکسازی ارسال شود، شایع هستند. علاوه بر این، وابستگیهای ناامن یک ریسک بزرگ هستند، با توجه به استفاده بالا از کتابخانههای شخص ثالث در محیطهای سرورلس. اما متهم اصلی و پرتکرارتر همچنان پیکربندی نادرست، بهویژه نقشهای IAM با مجوزهای بیش از حد است.
سختسازی AWS Lambda: مدیریت IAM و وابستگیها
هنگام ایمنسازی AWS Lambda، تمرکز اصلی باید بر روی نقش اجرا باشد. توسعهدهندگان اغلب به توابع مجوزهای بسیار گستردهای مانند AdministratorAccess اعطا میکنند، با این فرض که توسعه را ساده میکند. این یک خطای حیاتی است. یک تابع نفوذ شده با مجوزهای گسترده میتواند منجر به سرقت دادهها یا حرکت جانبی در سراسر VPC شما شود.
همیشه به اصل «کمترین امتیاز» پایبند باشید. اگر تابع شما فقط نیاز به نوشتن در یک مخزن S3 خاص دارد، نقش باید بهطور دقیق s3:PutObject را فقط روی ARN آن مخزن خاص مجاز کند، نه بیشتر. علاوه بر این، مدیریت وابستگیها حیاتی است. توابع سرورلس اغلب شامل کتابخانههای سنگینی هستند که سطح حمله را افزایش میدهند. از ابزارهایی مانند aws-nuke یا اسکریپتهای سفارشی برای اسکن آسیبپذیریها در بستههای استقرار خود استفاده کنید.
import boto3
import json
def lambda_handler(event, context):
# مثال: اتصال مستقیم ناامن به پایگاه داده
# هرگز اعتبارنامهها را در کد تعبیه نکنید!
# بهجای آن، از متغیرهای محیطی یا Secrets Manager استفاده کنید
db_host = event['host']
user = event['user']
password = event['password']
# منطق آسیبپذیر شبیهسازی شده
query = f"SELECT * FROM users WHERE user = '{user}' AND pass = '{password}'"
return {"statusCode": 200, "body": "Query آسیبپذیر"}
ایمنسازی Azure Functions: هویت و جداسازی شبکه
Azure Functions چالشهای امنیتی مشابهی دارند اما ابزارهای بومی متفاوتی برای کاهش آنها ارائه میدهند. یکی از موثرترین اقدامات امنیتی در Azure، استفاده از هویتهای مدیریت شده (Managed Identities) است. بهجای ذخیره رشتههای اتصال یا اعتبارنامهها در کد تابع، Azure Functions میتوانند برای احراز هویت به سایر سرویسهای Azure از هویتی استفاده کنند که مستقیماً به خود برنامه تابع اختصاص داده شده است.
علاوه بر این، Azure قابلیتهای شبکهای قوی ارائه میدهد. شما باید توابع خود را طوری پیکربندی کنید که در یک شبکه مجازی (VNet) اجرا شوند یا از نقاط انتهایی خصوصی برای دسترسی به پایگاه داده استفاده کنید. این اطمینان میدهد که تابع در معرض اینترنت عمومی قرار ندارد و فقط میتواند با منابع داخلی مورد اعتماد ارتباط برقرار کند. جداسازی شبکه بهطور قابل توجهی ریسک سرقت دادهها در صورت نفوذ به تابع را کاهش میدهد.
function app: {
"Identity": {
"Type": "SystemAssigned",
"PrincipalId": "00000000-0000-0000-0000-000000000000"
},
"Network": {
"VnetName": "mySecureVNet",
"SubnetName": "appSubnet"
}
}
اعتبارسنجی و پاکسازی ورودی
چه از AWS و چه از Azure استفاده کنید، رایجترین بردار برای نفوذ، ورودیهای غیرقابل اعتماد است. توابع سرورلس رویدادمحور هستند، به این معنی که توسط وبهوکها، صفهای پیام یا API Gateways فعال میشوند. تمام دادههای ورودی باید بهطور دقیق بر اساس یک طرح (Schema) اعتبارسنجی شوند.
هرگز به دادههای سمت کلاینت اعتماد نکنید. از کتابخانههایی مانند validator.js یا اعتبارسنجهای داخلی فریمورک برای پاکسازی ورودیها قبل از رسیدن به منطق کسبوکار خود استفاده کنید. بهعنوان مثال، اگر تابع انتظار دارد یک شیء JSON با شناسه عددی دریافت کند، صرفاً ورودی را نپذیرید؛ آن را تجزیه کرده و نوع آن را تأیید کنید. این کار از حملات تزریق جلوگیری میکند که در آن مهاجم ممکن است تلاش کند تا کوئریهای پایگاه داده یا استدلالهای خط فرمان را دستکاری کند.
نتیجهگیری
ایمنسازی توابع سرورلس نیازمند تغییر ذهنیت از دفاع مرزی به امنیت مبتنی بر هویت و کد است. با اعمال سختگیرانه اصل کمترین امتیاز، استفاده از هویتهای مدیریت شده، اعمال جداسازی شبکه دقیق و اعتبارسنجی تمام ورودیها، توسعهدهندگان میتوانند برنامههای سرورلس قوی و مقاوم بسازند. بهیاد داشته باشید که امنیت یک پیکربندی یکباره نیست، بلکه یک فرآیند مستمر است. نقشهای IAM خود را بهطور منظم بازبینی کنید، وابستگیهای خود را اسکن کنید و در مورد آخرین توصیههای امنیتی ارائهدهندگان ابری بهروز بمانید.
با توجه به رشد ادامهدار پذیرش سرورلس، شکاف بین بهترین روشهای امنیتی و پیادهسازیهای واقعی باید پر شود. با بازبینی توابع فعلی خود امروز شروع کنید. یک معماری سرورلس امن، پایهای برای یک برنامه بومی ابری قابل اعتماد است.