خلاصه کلیدی
یک پارامتر URL در یک قابلیت پیشنمایش لینک، اگر فیلتر خروجی درست تنظیم نشده باشد، میتواند به کنترل کامل حساب ابری ختم شود. زنجیره کوتاه است و دفاع مؤثر هم شناختهشده.
در مقالهای که سال گذشته منتشر کردیم، درباره زنجیرههای SSRF نوشتیم و تمرکز روی ریشه بود. اینجا میخواهیم درباره یک الگوی خاص صحبت کنیم که در عمل، پرتکرارترین پیامد واقعی SSRF است: دسترسی به سرویس متادیتای ابری و از آنجا تا کنترل حساب.
زنجیره، مرحله به مرحله
- 1یک قابلیت بیخطر به نظر میرسد — پیشنمایش لینک، واکشی متادیتای فایل، تولید تصویر از URL — که آدرس را در اختیار سرور قرار میدهد.
- 2سرور به آدرس دادهشده درخواست میزند، بدون فیلتر کافی برای محدودههای غیرقابلمسیریابی.
- 3سرویس متادیتای ابری نسخه ۱ با یک درخواست ساده پاسخ میدهد و اطلاعات نقش اجرایی جاری را برمیگرداند.
- 4توکن دریافتی با همان دسترسیهای نقش اصلی قابل استفاده است.
- 5پیکربندی اشتباه نقش، دسترسی را به ساخت کلید جدید یا تغییر سیاست میرساند.
GET /v1/credentials/role-name HTTP/1.1
Host: 169.254.169.254
X-Forwarded-For: 127.0.0.1
# response (abridged)
{
"AccessKeyId": "ASIA...",
"SecretAccessKey": "...",
"Token": "...",
"Expiration": "2026-10-08T19:45:00Z"
}کجا چیزی در این زنجیره اشتباه است
نکتهای که در جلسات بازبینی زیاد تکرار میشود: هر حلقه از این زنجیره جداگانه معقول به نظر میرسد. قابلیت پیشنمایش لینک لازم است. دسترسی سرویس به اینترنت لازم است. نقش اجرایی هم دسترسیهای محدودی دارد. هیچیک از این تصمیمها بهتنهایی غلط نیستند.
ایمنی در یک نقطه شکست میخورد: جایی که «محدودههای غیرقابلمسیریابی» مسدود میشوند و در عین حال دسترسی به متادیتا الزامی است. اگر این فیلتر وجود نداشته باشد، هیچکدام از لایههای دیگر اهمیتی ندارد.
دفاع: چهار لایه، بهترتیب اهمیت
- 1غیرفعال کردن IMDSv1 و اجبار IMDSv2 با `HttpPutResponseHopLimit = 1` و `HttpTokens = required`.
- 2فیلتر خروجی روی لایه شبکه — deny به کل بازههای link-local، حتی اگر مسیرهای دیگر امن باشند.
- 3سرویسهای دریافتکننده آدرس کاربر نباید بتوانند به شبکه داخلی دسترسی داشته باشند؛ آنها باید در یک زیرشبکه بدون مسیر خروجی اجرا شوند.
- 4کمترین سطح دسترسی برای نقش اجرایی، و الزام چرخش دورهای کلیدها.
# IMDSv2 handshake (required)
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 300")
# fetch the role using the token
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
# IMDSv1 must fail — a 401 here is the correct outcome
curl -s -o /dev/null -w "%{http_code}\n" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/چرا این یافته را زودتر از انتظار پیدا میکنیم
جالب اینجاست که این زنجیره معمولاً در روزهای اول پروژه پیدا میشود، نه روزهای آخر. دلیلش ساده است: ما مرحله نقشهبرداری سطح حمله را با خزش کامل سایت شروع میکنیم، و پارامترهای URL در آن خزش بهسرعت خودش را نشان میدهند. اگر یک endpoint، هر مقدار دلخواهی را در پارامتر `url` قبول کند، در گزارش نقشهبرداری بهعنوان یک نقطه ورود پرریسک علامت میخورد — و تست همانجا شروع میشود.
SSRF یک یافته نیست؛ یک سؤال است. سؤال اینکه سرور شما به چه چیزهایی میتواند دست بزند که شما نمیدانید.