تابلوی اشیای گمشده یک دانشگاه در زنجان، با سه تابلو در یک جدول: گمشده، پیداشده، و یک تابلوی کارکنان که کسی بیرون از دفتر نباید ببیندش. جستوجو پرسش خودش را با چسباندن رشتهها میسازد، که تقریباً هر نسخه اولی همینطور نوشته میشود:
"SELECT takhte, matn FROM elan WHERE takhte = '" + takhte + "'"- با
gomshodeصدا زده شود، یک اعلان برمیگرداند - با
gomshode' OR '1'='1صدا زده شود، هر سه تابلو را برمیگرداند، تابلوی کارکنان هم داخلش
اجراشده در سوم سپتامبر ۲۰۲۶. آن ورودی هر سه تابلو را برگرداند و هیچ چیز فرو نپاشید، هیچ چیز لاگ نشد، و صفحه عادی رسم شد. آپاستروف، رشتهای را بست که برنامهنویس باز کرده بود، و هر چیزی بعد از آن بهجای اینکه بخشی از داده پرسش باشد بخشی از دستور زبانش شد.
راهحل یک سطر است و فیلتر نیست. مقدار را بهشکل پارامتر بدهید:
db.execute("SELECT takhte, matn FROM elan WHERE takhte = ?", (takhte,))
همان ورودی از راه یک پرسش پارامتری صفر سطر برگرداند، چون پایگاه داده دنبال تابلویی گشت که اسمش عیناً gomshode' OR '1'='1 باشد و چنین تابلویی نیست. یک پارامتر داده است و هرگز نمیتواند بخشی از دستور زبان پرسش شود، هر کاراکتری که داخلش باشد. تمام چرا هرگز یک پرسش را با چسباندن نمیسازید همین است.
همان اشکال، در اتاقی دیگر
کسی اعلانی میگذارد که متنش <img src=x onerror="bardar()">شال خاکستری است. همانطور که هست داخل صفحه رسم شود، مرورگر متن نمیبیند، یک تگ میبیند، و آن تگ وقتی تصویر بار نشود اجرا میشود. سر خروجی که فرار داده شود، همان رشته یک تگ تصویر است که بهشکل کاراکتر چاپ شده و هیچ چیزی اجرا نمیشود.
هرکدام از اینها همان یک اشکالاند: دادهای که به جایی میرسد که آن را کد میخواند. یک پایگاه داده که SQL میخواندش، یک مرورگر که نشانهگذاری میخواندش، یک پوسته که فرمان میخواندش. همین که این دیده شود، دفاعها از یک فهرست حفظی به یک عادت تبدیل میشوند که در سه جا اعمال میشود، که ورودی نامعتبر که بهشکل کد رسم میشود است.
و راهحل هرگز فهرستی از کلمههای بد نیست، فرار دادن در لحظه خروج است. ممنوع کردن کلمه script یا برداشتن کروشهها موقع ورود شکست میخورد، چون املاهای بیشتری هست از آنچه کسی بتواند بشمارد و چون همان رشته ذخیرهشده در یک جا امن است و در جای دیگر خطرناک. اعتبارسنجی ورودی یک ویژگی کاربردپذیری است و فرار دادن، ویژگی امنیتی: بررسی کنید شماره تلفن شبیه شماره تلفن باشد چون به آدمی که تایپش میکند کمک میکند، و سر خروجی فرار بدهید چون معنا آنجا تعیین میشود.
یک نکته که در فارسی جدا باید گفته شود: هیچکدام از اینها به الفبا ربط ندارد. آپاستروف داخل یک فیلد فارسی همان کاری را میکند که داخل یک فیلد انگلیسی، و «نام خانوادگی» با یک آپاستروف همانقدر خطرناک است. تصور اینکه چون فیلد فارسی است پس ورودی هم فارسی خواهد بود، دلیل رایج نگذاشتن پارامتر روی همان فیلد است.
آن یکی که تزریق نیست
جعل درخواست میانسایتی شکل دیگری دارد و ارزش دارد جدا شود. هیچ چیز تزریق نمیشود: درخواست کاملاً درستساخت است، با کوکی نشست بازدیدکننده شما میرسد، و تنها مشکل این است که بازدیدکننده شما قصد فرستادنش را نداشته. صفحه دیگری مرورگرش را وادار کرده.
پس دفاعها هم فرق میکنند. SameSite=Lax و یک توکن داخل فرم همان چیزهایی هستند که این را میبندند: آن صفت کوکی جلوی چسباندن نشست به درخواستی را میگیرد که از سایت دیگری شروع شده، و توکن ثابت میکند فرم را شما دادهاید. هیچکدام ربطی به فرار دادن ندارند، که دلیل این است که بایگانی کردنش کنار تزریقها آدمها را به راهحل غلط میبرد. آن درخواستهایی که مرورگر شما به نیابت از کس دیگری میفرستد است.
انتقال هم چیز سومی است و جدا. HTTPS ثابت میکند به همان میزبانی رسیدهاید که در گواهی نوشته شده، و هیچ چیزی درباره خود سایت: حرفی است درباره اینکه با چه کسی حرف میزنید، نه درباره اینکه او صادق است یا نه، و یک صفحه فیشینگ با گواهی معتبر کاملاً عادی است. آنچه میدهد و آنچه نمیدهد آنچه TLS ثابت میکند، و آنچه نمیکند است.
لایهها، صادقانه
هر دفاع چه چیزی را میگیرد، و چه چیزی مستقیم از کنارش رد میشود
فقط یک سطر این شکل یک دسته کامل را از ریشه میبندد، و همان سطری است که کمترین حرف دربارهاش زده میشود.
- فهرستی از کلمههای ممنوع+دقیقاً همان رشتههایی که کسی فکرشان را کرده→هر املای دیگری، که یعنی همهشان
- اعتبارسنجی موقع ورود+شماره تلفنی که شماره تلفن نیست→رشتهای کاملاً معتبر که در بافت بعدی خصمانه است
- یک پرسش پارامتری+هر تزریق SQL را، کامل و از روی ساختار→هر چیزی که مقصدش پایگاه داده نیست
- فرار دادن در لحظه خروج+متنی که بهشکل نشانهگذاری خوانده شود، در همان بافتی که برایش فرار داده شده→همان متن، گذاشتهشده در بافتی دیگر، داخل یک صفت یا یک نشانی
- سیاست امنیت محتوا+اسکریپت تزریقشدهای که بخواهد از جای دیگری چیزی بگیرد→هیچ چیز، اگر صفحه از قبل اسکریپت درونخطی را اجازه داده باشد
سطر سوم همان شکلی است که باید خواستش: دفاعی که یک دسته را برمیدارد بهجای اینکه کمیابش کند.
ابزار، و سالی که این حرف درست است
پویش وابستگیها پرارزشترین ابزار اینجاست و روی هر میزبان کد رایگان است: بیشتر نفوذها امروز از راه یک کتابخانه میآیند نه از کدی که کسی نوشته. جای فهمیدن از یک فهرست پستی هشدار، یا اصلاً نفهمیدن را گرفت.
هدر سیاست امنیت محتوا رایگان است و یک بعدازظهر خرج دارد. جای اعتماد به این را گرفت که هیچ اسکریپتی هرگز تزریق نمیشود، و خط دوم است نه اول: محدود میکند یک اسکریپت تزریقشده چه کاری میتواند بکند، که دقیقاً روز جا افتادن یک فرار دادن اهمیت پیدا میکند.
صدور و تمدید خودکار گواهی، رایگان از سال ۲۰۱۶، جای خریدن سالانه یک گواهی و یادمان رفتن تمدیدش را گرفت. برای اینجا نکته دیگری هم دارد: چون خودکار و رایگان است، هیچ پرداخت ارزی لازم ندارد، و همین آن را تنها بخشی از این صفحه میکند که دسترسیاش از ایران مسئلهای نیست.
اشتباه: این را یک چکلیست دیدن بهجای یک مرز
گیر این است که امنیت بهشکل فهرستی از حملههای نامدار دیده میشود که باید یکییکی جلویشان گرفته شود، پس کار شبیه تیک زدن ده مورد میشود و به دهمی هرگز نمیرسند. تابلوی زنجان متن اعلانش را فرار داده بود، که همان موردی است که کسی اسمش را شنیده بود، و نام تابلو را چسبانده بود، که نشنیده بود.
فهرستی که واقعاً کمک میکند آن ده حمله نیست، مرزهاست: هر جایی که چیزی از بیرون وارد میشود، و هر جایی که چیزی بیرون میرود تا تفسیر شود. آنها معمولاً کمتر از تعداد نام حملهها هستند، با خواندن پیدا میشوند نه با به یاد آوردن، و هرکدام دقیقاً یک درمان درست دارند. آن فهرست ارزش دارد بهعنوان نقطه شروع یاد گرفته شود نه پایان، که فهرستی که ارزش دارد از بر باشید است.
نیمه دیگر گیر، باور کردن این است که کار کس دیگری است. یک سایت عمومی مدام و خودکار توسط برنامههایی حمله میشود که نمیدانند اصلاً چیست، و به همین دلیل تابلوی شال گمشده همان ترافیک یک بانک را میگیرد.
چیزی که این صفحه تعیین نمیکند این است که آن مرزها در یک سامانه مشخص کجا هستند، که پرسشی درباره بکاند است و درباره هر رابطی که به برنامههای دیگر باز شده، در API. خود آن پرسشی هم که چسبانده شد موضوعی جداست، زیر پایگاه داده، و همه اینها زیر وب.