وقتی کوئری را با چسباندن رشته میسازید، مقدار کاربر و دستور شما در یک متن قرار میگیرند و پایگاه داده هیچ راهی برای تشخیصشان ندارد. یک نقلقول در ورودی، رشته را میبندد و هرچه پس از آن بیاید بخشی از خود کوئری است.
با پارامتر، همین ورودی هیچ اثری ندارد. دلیلش این نیست که نویسهها فرار داده شدهاند؛ دلیلش این است که متن کوئری و مقدارها جدا فرستاده میشوند. پایگاه داده اول ساختار کوئری را میسازد و بعد مقدارها را در جای خالی میگذارد، پس مقدار هیچوقت این امکان را ندارد که دستور شود.
این تفاوت اساسی است و نه یک درجه امنیت بیشتر. فرار دادن دستی یک لایه محافظت است که میشود دورش زد؛ پارامتر یک تغییر ساختاری است که این کلاس حمله را غیرممکن میکند.
جاهایی که پارامتر کار نمیکند
پارامتر فقط برای مقدارهاست. نام جدول، نام ستون، و جهت مرتبسازی نمیتوانند پارامتر باشند، چون بخشی از ساختار کوئریاند. و دقیقا همان جاست که تزریق در پروژههای واقعی پیدا میشود: یک صفحه فهرست که ستون مرتبسازی را از نشانی میگیرد.
راه درست برای این حالت فهرست سفید است: مقدار ورودی را با فهرستی از نامهای مجاز مقایسه کنید و اگر نبود، پیشفرض را بردارید. هیچوقت مقدار ورودی را حتی پس از پاکسازی مستقیم در متن کوئری نگذارید.
لایههای بعدی، که جای پارامتر را نمیگیرند
کاربر پایگاه داده برنامه نباید مجوز حذف جدول یا خواندن جدولهای سیستمی داشته باشد؛ این کاری نمیکند که تزریق رخ ندهد، ولی محدود میکند که با آن چه میشود کرد. و پیام خطای پایگاه داده هرگز نباید به کاربر نشان داده شود، چون همان پیامها هستند که به مهاجم میگویند ساختار جدول چیست.
لایهبندی ابزار نگاشت شی به رابطه هم بهخودیخود امن نیست: هر ابزاری راهی برای نوشتن کوئری خام دارد و همان جاست که همین مسئله برمیگردد: نگاشت سطر به شی، و چیزی که از زیرش بیرون میزند.
جایی که کار گیر میکند، کد قدیمی و جستوجوی فارسی است
بیشتر تزریقهایی که در سایتهای فارسی پیدا میشوند در کدی هستند که سالها پیش نوشته شده، معمولا در یک صفحه جستوجو یا یک فیلتر که با چسباندن رشته ساخته شده. یک نکته که مخصوص فارسی است: چون ورودی فارسی است، تیم فرض میکند مهاجم هم فارسی مینویسد و بررسیهای سادهای میگذارد که فقط نویسههای خاص لاتین را میبینند. این هیچ کمکی نمیکند، چون ورودی مهاجم لازم نیست فارسی باشد. کاری که واقعا جواب میدهد یک بار گشتن در مخزن دنبال هر جایی است که رشته کوئری با نقطه یا با علامت جمع ساخته میشود، و تبدیل همهشان به پارامتر.
ابزار، و سالی که این حرف درست است
در سال ۲۰۲۶، هر لایه دسترسی به پایگاه داده در هر زبان اصلی پارامتر را پشتیبانی میکند و رایگان است؛ جای فرار دادن دستی را گرفته که سالها روش رایج بود و هیچوقت کامل نبود. برای پیدا کردن جاهای باقیمانده، ابزارهای تحلیل ایستا هر کوئریای که از رشته ساخته شده باشد را علامت میزنند و متنباز و رایگاناند. و در پایگاه داده، ساختن یک کاربر با کمترین مجوز لازم یک دستور است.
پرسش بعدی این است که همین ایده در سمت مرورگر چه شکلی دارد و چرا آنجا دفاع سر خروجی است، که ورودی نامطمئنی که بهجای متن، کد اجرا میشود است. و خود زبان کوئری در زبانی که با پایگاه داده حرف میزند است.