بیشتر تیمها نوعی از تست حملات تزریقی را انجام میدهند. با این حال، این تستها معمولاً بر روی زیرمجموعهای کوچک از آسیبپذیریهای خاص متمرکز است. تزریق SQL یکی از اهداف محبوب است، همچنین تزریق فرمان (Command Injection). برخی تیمها ممکن است تزریق در لاگ را هم بررسی کنند اگر قبلاً از این طریق آسیب دیده باشند.
اما وقتی صحبت از APIها میشود — بهویژه سیستمهای مدرن مبتنی بر JSON یا GraphQL — فضای حملات تزریقی بسیار گستردهتر، پنهانتر و اغلب کمتر آزمایششده از آن چیزی است که بسیاری از مجموعههای تست امنیتی تصور میکنند.
در ادامه به چند مسیر تزریقی میپردازیم که اکثر تیمها آزمایششان نمیکنند، در حالی که باید حتماً این کار را انجام دهند.
۱. تزریق JSON
ممکن است تصور کنید که چون مستقیماً با پرسوجوهای SQL کار نمیکنید، API شما در برابر تزریق مقاوم است. اما بسیاری از سیستمهای بکاند رشتههایی از انواع مختلف را میپذیرند، و یکی از انواع خطرناک آن JSON است. JSON میتواند دوباره تجزیه، در سیستمهای مختلف تفسیر و به روشهای گوناگون وارد فرآیند شود و با روشهای هوشمندانه میتواند آسیب زیادی ایجاد کند.
برای مثال، در نظر بگیرید که ورودی زیر ارسال شود:
در بکاند ممکن است اینگونه پردازش شود:
اگر این پرسوجو از طریق JSON.parse() یا یک سازندهٔ پویا تجزیه شود، و سرویس شما از MongoDB استفاده کند، نتیجه چنین خواهد بود:
در این حالت، دیگر تطبیق رشتهای ساده با «user» نیست — بلکه یک عملگر MongoDB است که همهٔ کاربران غیر تهی را بازمیگرداند. در نتیجه، ممکن است کل دادههای کاربران افشا شوند.
راهکارهای مقابله:
-
نسبت به فیلدهایی که شامل JSON سریالشده داخل رشتهها هستند، مشکوک باشید و در صورت امکان آنها را حذف کنید.
-
مطمئن شوید که بارها فقط یکبار تجزیه میشوند. در صورت نیاز به چند بار تجزیه، قوانین فیلترینگ و تبدیل را برای جلوگیری از تزریق اعمال کنید.
-
در صورت استفاده از
eval،JSON.parseیا ساختارهای پویا، خروجی را اعتبارسنجی کنید و از قوانین جلوگیری از نشت داده و تزریق عملگر استفاده کنید.
۲. سوءاستفاده از Resolver در GraphQL
GraphQL پیچیدگی زیادی را پشت یک نقطهٔ پایانی پنهان میکند، اما هر Resolver در این جریان میتواند نقطهٔ تزریق بالقوه باشد اگر ورودی کاربر به سیستمهای پاییندستی منتقل شود. هر چه انعطاف GraphQL بیشتر باشد، ریسک نیز بالاتر است.
برای مثال، ورودی زیر را در نظر بگیرید:
و بکاند آن را به این صورت پردازش کند:
در نتیجه:
-
عبارت
۱=۱همیشه درست است. -
تمام ردیفها بازگردانده میشوند.
-
حتی ممکن است امکان تزریق عباراتی مانند
; DROP TABLE users;نیز فراهم شود.
حتی اگر دادهها فیلتر شوند، ممکن است این پرسوجو به Elasticsearch یا Solr ارسال شود و منجر به اجرای کوئریهای بسیار سنگین شود.
راهکارهای مقابله:
-
ورودیهای دارای ساختار تو در تو را پاکسازی یا فقط از فهرست مجاز بپذیرید.
-
از تبدیل مقادیر Enum به مسیرهای کد جلوگیری کنید.
-
کنترلهایی روی نامگذاری فیلدها و aliasها اعمال کنید تا از حملات شکلدهی پرسوجو جلوگیری شود.
۳. تزریق در Header
این حمله رایج است اما اغلب در تستها نادیده گرفته میشود. APIها معمولاً از Header برای متادادههای حیاتی استفاده میکنند، و تزریق در آن میتواند آسیبزننده باشد.
بسیاری از تیمها محتوای بدنه را آزمایش میکنند اما نه هدرها را. در حالی که مهاجمان با حملات مرد میانی (MITM) میتوانند دادههای هدر را تغییر داده و از اطلاعات معتبر برای نفوذ استفاده کنند.
راهکارهای مقابله:
-
از چندهدر (مانند چند Authorization Header) جلوگیری کنید یا با محدودیت کاراکتر مانع شوید.
-
تزریق CRLF را فیلتر کنید تا ساختار هدر نشکند (
%0d%0a). -
از معماری Zero Trust استفاده کنید تا از دستکاری هدر میزبان برای حملات SSRF یا Poisoning جلوگیری شود.
۴. تزریق در قالبها (Template Injection) از طریق فیلدهای سفارشی
اگر از قالبها برای ایمیل، PDF یا رندر پویا استفاده میکنید و دادههای ورودی کاربر را درون آنها میگذارید، احتمال دارد یک بردار تزریق جدی ایجاد کنید.
برای نمونه:
اگر این مقدار بدون فیلتر به سیستم قالبی مانند Handlebars داده شود، ممکن است امکان اجرای کد دلخواه ایجاد شود.
راهکارهای مقابله:
-
ورودیها را قبل از درج در قالب کاملاً Escape یا Sanitize کنید.
-
از حالت امن قالبها استفاده کرده و دادهها را در محیط ایزوله رندر کنید.
-
محتوای فیلدهای پویا در ورودی API را محدود یا اعتبارسنجی کنید.
۵. تزریق از طریق Webhook یا URLهای Callback
APIهایی که URL برای وبهوک، بازگردانی (Redirect URI) یا دستور Fetch میپذیرند، هدف رایج حملات هستند.
مثلاً اگر فیلدی بپذیرد: //attacker.com، برخی تجزیهگرها این آدرس را معتبر فرض کرده و به آن درخواست میفرستند. در نتیجه، میتوان حملهٔ Open Redirect یا SSRF انجام داد.
راهکارهای مقابله:
-
فقط طرحهایی مانند
https://را بپذیرید و آنها را با فهرست مجاز مقایسه کنید. -
از ارسال آدرسهای داخلی (مثلاً
۱۲۷.۰.۰.۱) از سرویسهای خارجی جلوگیری کنید. -
از فهرستهای مجاز IP و زمانبندی درخواست استفاده کنید.
۶. بمبهای Deserialize
APIهایی که اشیای پیچیده را از طریق JSON، XML یا YAML میپذیرند، ممکن است در برابر حملات بمبهای Deserialize آسیبپذیر باشند. این حملات با ایجاد حلقههای بازگشتی، باعث اشغال بیش از حد CPU و حافظه و در نتیجه از کار افتادن سرویس میشوند.
برای مثال، یک ساختار JSON بازگشتی:
در ظاهر کوچک است اما هنگام تجزیه میتواند بار سنگینی ایجاد کند. چند صد درخواست از این نوع میتواند منابع سیستم را بهطور کامل مصرف کند.
راهکارهای مقابله:
-
از تجزیهٔ بازگشتی JSON جلوگیری کنید و اجازهٔ تزریق تنظیمات سفارشی ندهید.
-
استفاده از توابعی مانند
yaml.load()را کنترل و محدودیت حافظه اعمال کنید. -
از کتابخانههای امن با محدودیت عمق و اندازهٔ ورودی استفاده کنید.
جمعبندی
واقعیت این است که نمیتوانید چیزی را که نمیبینید اسکن کنید. تزریق فقط مربوط به SQL یا XML نیست — APIهای مدرن پر از مسیرهای تجزیهٔ ثانویه، تبدیل نوع پویا و جریانهای غیرمستقیم داده هستند. این همان نقاط کور مورد علاقهٔ مهاجمان است.
برای مقاومسازی API، چرخهٔ عمر داده را در نظر بگیرید نه فقط ورودی کنترلر را. همهچیز را اعتبارسنجی کنید، حتی هدرها و فیلدهای تو در تو را، و از رویکرد «اعتماد صفر» استفاده کنید.
خبر خوب این است که بیشتر این مشکلات با اعتبارسنجی بهتر ورودی، پوشش تست گستردهتر و بهروزرسانی مدل تهدید قابل حل هستند. خبر بد این است که اینها تنها بخشی از حملات تزریقی رایج هستند که احتمالاً آزمایششان نمیکنید — بنابراین باید همیشه هوشیار بمانید!
