سال‌ها پیش در پروژه‌ای که تیم برای صرفه‌جویی زمان از یک boilerplate ناشناس استفاده کرد بعد از دو ماه یک آسیب‌پذیری در dependencyهای آن پیدا شد که به‌خاطر آن مجبور به بازنویسی کل بخش احراز هویت شدیم. آن پروژه یک درس گران‌قیمت داشت: امنیت boilerplate به‌اندازه‌ی عملکرد آن مهم است. از آن روز فهمیدم Boilerplate های امن یک انتخاب فنی نیست بلکه یک تصمیم امنیتی است. در این متن تجربه‌ی خودم از انتخاب و بررسی امنیت boilerplate ها را با شما در میان می‌گذارم.

چرا امنیت boilerplate مهم است؟

boilerplate نقطه‌ی شروع پروژه است و هر خطایی در آن به تمام پروژه منتقل می‌شود. اگر boilerplate تنظیمات امنیتی نادرست داشته باشد یا dependency آسیب‌پذیر داشته باشد این آسیب‌پذیری در تمام پروژه تکرار می‌شود. برخلاف یک باگ معمولی که در یک بخش محدود می‌ماند آسیب‌پذیری boilerplate اثر زنجیره‌ای دارد.

دلیل دوم پیچیدگی رفع آن است. اگر بعد از چند ماه استفاده از boilerplate متوجه آسیب‌پذیری شوید رفع آن نیاز به بازنویسی بخش‌های زیادی دارد چون بخش‌های دیگر کد به آن ساختار وابسته شده‌اند. مفهوم کلی boilerplate را در Boilerplate چیست و چه کاربردی در برنامه‌نویسی دارد کامل توضیح داده‌ام.

دلیل سوم مسئولیت حقوقی است. اگر پروژه‌ی شما داده‌های کاربران را ذخیره می‌کند boilerplate امن بخشی از تعهدات قانونی شماست. در پروژه‌های بین‌المللی این مسئولیت می‌تواند به جریمه‌های سنگین منجر شود. مسیر کلی امنیت را در راهنمای امنیت وردپرس برای مبتدیان نوشته‌ام.

boilerplate امن یعنی پایه‌ی پروژه از نظر امنیتی تست‌شده است نه این‌که امنیت کامل دارد؛ امنیت کامل نتیجه‌ی تلاش مداوم است.

Boilerplate امن دقیقاً چه معنایی دارد؟

boilerplate امن سه ویژگی اصلی دارد که در تجربه‌ی خودم تعیین‌کننده هستند. اول کد باز و قابل بررسی. یعنی کد شما در مخزن Git قابل مشاهده است و هر فردی می‌تواند آن را بررسی کند. دوم dependencyهای به‌روز و بررسی‌شده. یعنی هیچ کتابخانه‌ی ناشناس یا قدیمی در آن نیست. سوم پیکربندی امن پیش‌فرض. یعنی تنظیمات امنیتی به‌صورت پیش‌فرض اعمال شده‌اند نه این‌که شما بعداً اضافه کنید.

در نگاه دقیق‌تر boilerplate امن یک ترکیب است از سه لایه: کد امن خود boilerplate dependencyهای امن و پیکربندی امن محیط. اگر هر یک از این سه لایه ضعیف باشد کل پروژه آسیب‌پذیر می‌شود. در تجربه‌ی خودم اولین لایه رایج‌ترین دلیل شکست است چون boilerplate های ناشناس ممکن است کد مخرب داشته باشند.

boilerplate امن از boilerplate معمولی در پنج نقطه‌ی مشخص متفاوت است: بخش احراز هویت مدیریت secrets هدرهای امنیتی validaدیت ورودی و لاگ‌گیری. اگر boilerplate ای در یکی از این پنج نقطه ضعیف باشد حتی اگر بخش‌های دیگر قوی باشد باز امن نیست. مسیر بررسی این پنج نقطه را در ادامه توضیح می‌دهم.

ویژگی‌های یک boilerplate امن

در تجربه‌ی خودم یک boilerplate امن هفت ویژگی اصلی دارد که هر یک قابل بررسی است.

  1. کد باز در مخزن معتبر: boilerplate باید در GitHub یا GitLab با تاریخچه‌ی commit فعال باشد نه در یک zip ناشناس.
  2. dependencyهای به‌روز: همه‌ی dependencyها باید در آخرین نسخه‌ی پایدار باشند و vulnerability scan پاس کرده باشند.
  3. مدیریت secrets با فایل environment: هیچ رمز یا کلید API در کد نباید hardcode شده باشد.
  4. احراز هویت امن: اگر بخش احراز هویت دارد باید از الگوهای استاندارد مثل JWT یا session امن استفاده کند نه روش‌های خانگی.
  5. هدرهای امنیتی پیش‌فرض: هدرهای مثل CSP و X-Frame-Options و Strict-Transport-Security باید به‌صورت پیش‌فرض فعال باشند.
  6. validaدیت ورودی: تمام ورودی‌های کاربر باید در سطح boilerplate اعتبارسنجی شوند نه فقط در بخش‌های اختصاصی.
  7. لاگ‌گیری و مانیتورینگ: boilerplate باید ساختار لاگ‌گیری برای رویدادهای امنیتی داشته باشد.

این هفت ویژگی را می‌توانید به‌عنوان چک‌لیست امنیتی برای انتخاب boilerplate استفاده کنید. اگر boilerplate ای بیش از دو ویژگی را نداشت انتخاب بعدی را جدی بگیرید. مسیر مشابه بررسی امنیت قالب را در آیا استفاده از قالب‌های رایگان وردپرس امن است نوشته‌ام.

منبع boilerplate و امنیت

منبع boilerplate یکی از مهم‌ترین عوامل امنیتی است. در تجربه‌ی خودم چهار سطح منبع وجود دارد که امنیت متفاوتی دارند.

سطح اول مخازن رسمی و شناخته‌شده: مثل boilerplate های رسمی Vue و React. این boilerplate ها بازبینی جامعه و نگهداری رسمی دارند. سطح دوم مخازن شخصی با اعتبار: boilerplate های ساخته‌شده توسط توسعه‌دهندگان شناخته‌شده که سابقه‌ی طولانی دارند. سطح سوم مخازن نیمه‌ناشناس: boilerplate هایی که در GitHub هستند اما سازنده‌ی ناشناخته دارند. سطح چهارم سایت‌های دانلود ناشناس: boilerplate هایی که از سایت‌های دانلود رایگان گرفته شده‌اند.

در تجربه‌ی خودم فقط دو سطح اول قابل اعتماد هستند. سطح سوم نیاز به بررسی دقیق دارد و سطح چهارم باید به کلی اجتناب شود. در پروژه‌های امنیتی حساس حتی سطح دوم هم باید بررسی شود چون boilerplate های شخصی ممکن است خطاهای امنیتی داشته باشند. مسیر مشابه این بررسی را در چگونه افزونه و قالب وردپرس مطمئن دانلود کنیم نوشته‌ام.

بررسی dependencyها

dependencyها یکی از بزرگ‌ترین منابع آسیب‌پذیری در پروژه‌های مدرن هستند. حتی یک boilerplate امن اگر dependencyهایش آسیب‌پذیر باشند امن نیست. در تجربه‌ی خودم سه روش بررسی dependency وجود دارد.

روش اول ابزارهای خودکار vulnerability scan. ابزارهایی مثل npm audit و Snyk و Dependabot امکان بررسی خودکار آسیب‌پذیری‌ها را می‌دهند. این ابزارها باید بخشی از فرآیند CI/CD پروژه باشند. روش دوم بررسی دستی dependencyها. قبل از انتخاب boilerplate همه‌ی dependencyها را فهرست کنید و برای هر یک سه سوال بپرسید: سازنده کیست؟ تاریخ آخرین به‌روزرسانی کِی بوده؟ آیا آسیب‌پذیری شناخته‌شده دارد؟

روش سوم کاهش تعداد dependencyها. هر dependency یک سطح حمله‌ی جدید است. اگر boilerplate ده‌ها dependency دارد احتمال آسیب‌پذیری بیشتر است. در تجربه‌ی خودم boilerplate های مینیمال با dependencyهای کم امن‌تر از boilerplate های پرامکانات هستند. مسیر مشابه کاهش سطح حمله را در افزونه‌های ضروری وردپرس برای هر سایت و افزونه‌های وردپرس چگونه روی سرعت سایت اثر می‌گذارند نوشته‌ام.

هر dependency در boilerplate یک سطح حمله‌ی جدید است؛ boilerplate ای که با حداقل dependency ساخته شده باشد امن‌تر از boilerplate ای با کتابخانه‌های فراوان است.

مدیریت رمزها و secrets

یکی از رایج‌ترین اشتباهات امنیتی در پروژه‌های وب hardcode کردن رمزها و کلیدهای API در کد است. boilerplate امن باید از این اشتباه جلوگیری کند. در تجربه‌ی خودم سه قانون طلایی وجود دارد.

قانون اول استفاده از فایل .env برای همه‌ی secrets. هیچ رمز یا کلید API نباید در کد مستقیماً نوشته شود. همه باید در فایل .env باشند که در مخزن Git ثبت نشده. قانون دوم فهرست .gitignore استاندارد. boilerplate باید فایل .gitignore داشته باشد که .env و فایل‌های مشابه را نادیده می‌گیرد. قانون سوم فایل .env.example. boilerplate باید فایل .env.example داشته باشد که ساختار رمزها را نشان می‌دهد اما مقادیر واقعی ندارد.

در تجربه‌ی خودم پروژه‌هایی دیده‌ام که رمز دیتابیس در فایل config عمومی بوده و در مخزن GitHub commit شده. این اشتباه می‌تواند به نشت اطلاعات منجر شود. boilerplate امن این نوع اشتباه را از همان ابتدا غیرممکن می‌کند. مسیر مشابه در مدیریت رمزهای وردپرس را در چگونه فایل wp-config را امن کنیم نوشته‌ام.

بخش احراز هویت در boilerplate

اگر boilerplate بخش احراز هویت دارد این بخش حساس‌ترین قسمت است و باید با دقت بررسی شود. در تجربه‌ی خودم چهار ویژگی امنیتی در احراز هویت boilerplate تعیین‌کننده است.

ویژگی اول استفاده از استانداردهای شناخته‌شده. اگر boilerplate از JWT یا OAuth استفاده می‌کند این استانداردهای شناخته‌شده‌اند. اما اگر از روش خانگی استفاده می‌کند احتمال خطاهای امنیتی بالا است. مسیر کامل JWT و OAuth را در JWT چیست و چه کاربردی در احراز هویت دارد و OAuth چیست و چگونه کار می‌کند نوشته‌ام.

ویژگی دوم ذخیره‌سازی امن رمزها. رمزها باید با الگوریتم‌های hash قوی مثل bcrypt یا Argon2 ذخیره شوند نه با md5 یا sha1 ساده. ویژگی سوم محافظت در برابر حملات رایج. boilerplate امن باید در برابر CSRF و XSS و brute force محافظت داشته باشد. مسیر کامل این حملات را در CSRF چیست و چگونه از آن جلوگیری کنیم و حملات XSS چیست و چگونه دفع می‌شود نوشته‌ام.

ویژگی چهارم مدیریت session امن. اگر boilerplate از session استفاده می‌کند باید session cookie با پرچم‌های Secure و HttpOnly و SameSite تنظیم شود. مسیر مشابه این تنظیمات را در فعال‌سازی 2FA برای کاربران وردپرس برای مکمل احراز هویت نوشته‌ام.

هدرهای امنیتی و پیکربندی

هدرهای امنیتی یک لایه‌ی دفاعی مهم در پروژه‌های وب هستند. boilerplate امن باید این هدرها را به‌صورت پیش‌فرض اعمال کند. در تجربه‌ی خودم چهار هدر اصلی تعیین‌کننده هستند.

Content-Security-Policy (CSP): جلوگیری از تزریق کد مخرب در صفحات. این هدر پیچیده است و boilerplate باید یک CSP پایه داشته باشد که قابل توسعه باشد. Strict-Transport-Security (HSTS): اجبار HTTPS برای همه‌ی درخواست‌ها. X-Frame-Options: جلوگیری از clickjacking. X-Content-Type-Options: جلوگیری از MIME sniffing در مرورگرها.

در کنار هدرها دو پیکربندی مهم دیگر وجود دارد: CORS (Cross-Origin Resource Sharing یا اشتراک منابع بین دامنه‌ای) که باید دقیق تنظیم شود تا فقط دامنه‌های معتبر به API دسترسی داشته باشند و rate limiting که جلوی حملات brute force و DDoS را می‌گیرد. مسیر کامل مدیریت این هدرها در هدرهای امنیتی HTTP چه کاربردی دارند و چگونه امنیت وب‌سایت را افزایش دهیم نوشته‌ام.

به‌روزرسانی و نگهداری امن

boilerplate امن یک وضعیت ثابت نیست بلکه یک فرآیند مداوم است. در تجربه‌ی خودم سه اصل برای نگهداری امن وجود دارد.

اصل اول به‌روزرسانی دوره‌ای dependencyها. هر ماه باید dependencyها به آخرین نسخه‌ی پایدار به‌روز شوند. این کار vulnerabilityهای شناخته‌شده را می‌بندد. اصل دوم پایش مستمر آسیب‌پذیری‌ها. ابزارهای مثل Dependabot یا Snyk باید به مخزن متصل باشند تا در صورت کشف آسیب‌پذیری جدید اطلاع بدهند. اصل سوم نسخه‌بندی معنادار. هر به‌روزرسانی امنیتی باید یک نسخه‌ی جدید با changelog داشته باشد تا تیم بداند چه چیزی تغییر کرده. مسیر مشابه را در به‌روزرسانی سرور چه اهمیتی دارد نوشته‌ام.

در تجربه‌ی خودم تیم‌هایی که به‌طور منظم boilerplate خود را به‌روز می‌کنند کمتر با آسیب‌پذیری مواجه می‌شوند. برعکس تیم‌هایی که boilerplate را یک‌بار انتخاب و رها می‌کنند در طول سال‌ها با انباشت مشکلات امنیتی روبرو می‌شوند.

روش بررسی امنیت boilerplate

برای اینکه بدانید یک boilerplate امن است یا نه نیاز به یک فرآیند بررسی منظم دارید. در تجربه‌ی خودم این فرآیند پنج مرحله دارد.

  1. بررسی منبع: boilerplate از کجا آمده؟ سازنده کیست؟ آیا مخزن فعال است؟ تاریخچه‌ی commit چه می‌گوید؟
  2. اسکن خودکار: با ابزارهای vulnerability scan مثل Snyk یا OWASP Dependency-Check اسکن کنید.
  3. بررسی دستی dependencyها: برای هر dependency اصلی سه سوال سازنده آخرین به‌روزرسانی و آسیب‌پذیری شناخته‌شده را بپرسید.
  4. بررسی پیکربندی: فایل‌های config و .env.example را بررسی کنید. آیا secrets در کد hardcode شده‌اند؟
  5. بررسی بخش احراز هویت: اگر بخش احراز هویت دارد با دقت بررسی کنید که از استانداردهای شناخته‌شده استفاده کند.

این پنج مرحله می‌تواند بین نیم‌روز تا یک روز وقت بگیرد اما از آسیب‌پذیری‌های گران‌قیمت در آینده جلوگیری می‌کند. مسیر مشابه این بررسی را برای افزونه‌ها در اشتباهات رایج امنیت وب کدامند و تست امنیت وب‌سایت چگونه انجام می‌شود نوشته‌ام.

اشتباهات امنیتی رایج در boilerplate

  • استفاده از boilerplate ناشناس: boilerplate ای که از منبع نامعتبر گرفته شده ممکن است کد مخرب داشته باشد.
  • hardcode کردن رمزها: قرار دادن رمز دیتابیس یا کلید API در کد که در مخزن Git commit می‌شود.
  • استفاده از dependencyهای قدیمی: dependencyهایی که نسخه‌های قدیمی دارند احتمال آسیب‌پذیری بالاتری دارند.
  • نبود هدرهای امنیتی: boilerplate ای که هدرهای امنیتی پیش‌فرض ندارد تیم باید آن‌ها را دستی اضافه کند که اغلب فراموش می‌شود.
  • احراز هویت خانگی: اگر boilerplate بخش احراز هویت دارد و از روش خانگی به‌جای استاندارد استفاده می‌کند احتمال خطاهای امنیتی بالاست.
  • نبود به‌روزرسانی منظم: boilerplate ای که بعد از ساخت رها شده باشد به‌سرعت آسیب‌پذیر می‌شود.

این اشتباهات با فرآیند بررسی پنج‌مرحله‌ای که توضیح دادم قابل اجتناب هستند. مسیر مشابه در انتخاب افزونه‌های امنیتی وردپرس را در بهترین افزونه‌های امنیتی وردپرس برای محافظت از سایت نوشته‌ام.

پرسش‌های پرتکرار درباره boilerplate های امن

چطور بفهمم یک boilerplate امن است؟

با پنج مرحله‌ی بررسی: منبع dependencyها پیکربندی secrets بخش احراز هویت و به‌روزرسانی. اگر boilerplate ای در منبع معتبر باشد dependencyهای به‌روز داشته باشد secrets را در فایل .env نگه دارد از استانداردهای احراز هویت استفاده کند و به‌طور منظم به‌روز شود احتمالاً امن است.

آیا boilerplate های رسمی همیشه امن هستند؟

نه همیشه. boilerplate های رسمی از منابع معتبر مثل Boilerplate code معمولاً امن‌تر هستند چون بازبینی جامعه دارند اما همچنان باید بررسی شوند چون dependencyهای آن‌ها ممکن است آسیب‌پذیر باشند. هیچ boilerplate ای نباید بدون بررسی استفاده شود.

چند وقت یک‌بار باید boilerplate را به‌روز کنم؟

dependencyها را ماهانه. خود boilerplate را هر شش ماه یک بار بازبینی کنید. اگر vulnerability جدیدی گزارش شد فوری به‌روز کنید. به‌روزرسانی منظم یکی از مهم‌ترین عوامل امنیت boilerplate است.

آیا boilerplate اختصاصی امن‌تر از boilerplate عمومی است؟

boilerplate اختصاصی می‌تواند امن‌تر باشد چون شما کنترل کامل روی dependencyها و پیکربندی دارید. اما فقط در صورتی که خودتان دانش امنیتی کافی داشته باشید. اگر تیم شما تجربه‌ی امنیتی کم دارد boilerplate عمومی از منبع معتبر ممکن است انتخاب بهتری باشد.

آیا استفاده از boilerplate قدیمی خطر امنیتی دارد؟

بله اگر بیش از یک سال به‌روز نشده باشد. آسیب‌پذیری‌ها سریع کشف می‌شوند و boilerplate قدیمی می‌تواند حاوی آسیب‌پذیری‌های شناخته‌شده باشد. قبل از استفاده از boilerplate تاریخ آخرین commit یا release را چک کنید.

چطور secrets را در boilerplate مدیریت کنم؟

با فایل .env. تمام رمزها و کلیدهای API در فایل .env نگهداری شوند و این فایل در .gitignore قرار بگیرد. یک فایل .env.example با ساختار (اما بدون مقادیر واقعی) در مخزن بگذارید. این روش استاندارد امروز است و در محیط‌های production با سیستم‌های مدیریت secrets مثل HashiCorp Vault تقویت می‌شود.

آیا استفاده از boilerplate می‌تواند سطح حمله را افزایش دهد؟

بله اگر boilerplate پرdependency باشد. هر dependency یک سطح حمله‌ی جدید است. boilerplate های مینیمال با dependencyهای کم سطح حمله‌ی کمتری دارند. برای پروژه‌های امنیتی حساس boilerplate مینیمال انتخاب بهتری است.

آیا باید boilerplate را در مخزن خصوصی نگه دارم؟

اگر boilerplate حاوی secrets یا کد اختصاصی شرکت است بله. اما اگر boilerplate عمومی است نگه‌داشتن در مخزن عمومی می‌تواند به بازبینی جامعه کمک کند. این تصمیم بستگی به سیاست امنیتی سازمان دارد.

معادله‌ی امنیت boilerplate

امنیت boilerplate یک ویژگی ثابت نیست بلکه یک وضعیت است که با انتخاب دقیق و نگهداری منظم به دست می‌آید. تفاوت بین یک تیم حرفه‌ای و یک تیم متوسط در برخورد با امنیت boilerplate این است: تیم حرفه‌ای امنیت را به‌عنوان بخشی از انتخاب می‌بیند نه به‌عنوان چیزی که بعداً اضافه می‌شود.

معادله‌ی امنیت boilerplate در تجربه‌ی خودم سه ضریب دارد: انتخاب از منبع معتبر dependencyهای به‌روز و نگهداری مداوم. اگر هر یک از این سه ضریب صفر باشد امنیت مطلوب به‌دست نمی‌آید. پیشنهاد عملی من: قبل از استفاده از هر boilerplate فرآیند بررسی پنج‌مرحله‌ای را اجرا کنید. اگر در انتخاب یا بررسی boilerplate ای گیر کرده‌اید نوع پروژه و حساسیت داده‌هایش را بنویسید تا با جزئیات بیشتری کمک کنم. اگر هم تجربه‌ای از boilerplate ای دارید که امنیت پروژه‌تان را نجات داد در دیدگاه‌ها به اشتراک بگذارید. 🔒