ایمن کردن داده های حساس به صورت محلی
شناسه پست: 2879
بازدید: 1233

ما مجددا آمدیم تا با مهمترین قسمت از این آموزش سریالی در خدمت شما باشیم – ایمن کردن داده های حساس، زمانیکه با پیکربندی در ASP.NET Core کار میکنیم. به عنوان یک توسعه دهنده نرم افزار، ما مسئول امنیت اپلیکیشنهایی هستیم که ایجاد میکنیم و آن باید در راس اولویتهای ما برای همیشه باشد.

اگر در یک تیم بزرگ یا یک پروژه بزرگ کار میکنید، handle کردن اطلاعات حساس حتی اهمیت بیشتری نیز پیدا میکند، چرا که ما میتوانیم منجربه رخداد مشکلاتی برای دیگر توسعه دهندگان در محیط توسعه آنها بشویم.

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

اگر میخواهید در طول مسیر این مقاله، ما را دنبال کنید، از نقطه شروع یعنی سورس `پروژه Configuration Provider سفارشی استفاده کنید. برای بررسی پروژه تکمیل شده این مقاله، از پروژه نهایی این مقاله یعنی پروژه تکمیل شده ایمن کردن داده ها به صورت محلی استفاده کنید.

در این مقاله، میخواهیم در مورد عناوین زیر صحبت کنیم:

بریم که شروع کنیم.

چه چیزی به عنوان داده های حساس محسوب می شود و چرا باید به آنها اهمیت دهیم

ما هر چیزی که بتواند توسط شخص ثالث مورد سوء استفاده قرار گیرد را به عنوان داده های حساس قلمداد میکنیم. برای مثال، API key ها, token ها, connection string ها, ایمیلها, رمز عبورها, password hashe ها, به طور بالقوه برخی از URL ها.

تقریباً غیرممکن است که شما تابحال نرم افزاری را توسعه داده باشید که هیچ اطلاعات حساسی را در تاریخچه commit های خود نداشته باشید.

چه بدانیم و چه ندانیم.

ما می دانیم که این اطلاعات حساس را در پروژه های خود داریم و افتادن در این دام بسیار آسان است. به فرض شما در حال کار بر روی پروژه جانبی خود هستید و قصد دارید ایده خود را در معرض عموم قرار دهید. برای ایجاد پروژه خود، نیاز است که یه دیتابیس دسترسی داشته باشید و خیلی سریع آن دیتابیس را در Azure/AWS/GCloud ایجاد میکنید. شما connection string را به سرعت فقط جهت تست، در appsettings.json قرار میدهید. چند ساعت بعد، شما از نحوه پیشرفت پروژه خود بسیار خوشحال هستید و از آنجا که نمی خواهید آن را از دست بدهید، سریع آن را به درون push ،GitHub می کنید.

چند سال بعد، شما repository های خود را در GitHub مرور می کنید تا ببینید چقدر پیشرفت کرده اید و همه کارهایی که در طول سال انجام داده اید را ببینید. شما پروژه را باز می کنید و connection string، نام سرور ، رمز عبور و همه چیز را آنجا پیدا می کنید.

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

ذخیره داده های حساس در محیط توسعه

ما به این نتیجه رسیده ایم که داده های حساس نباید در فایل های پیکربندی ذخیره شوند ، به ویژه در خود source code.

اما مناسبترین راه برای ذخیره داده های حساس در محیط توسعه چیست؟

ما میتوانیم انتخاب کنیم که داده های پیکربندی ما، یا در متغیرهای محیطی یا با استفاده از Secret Manager به عنوان یک user secret ذخیره شوند.

هیچ یک از این گزینه ها به اندازه کافی برای مرحله تولید مناسب نیستند زیرا داده های ما را رمزگذاری نمی کنند و به صورت یک متن ساده ذخیره می شوند. با این وجود، ما می توانیم از آنها، هنگام کار با توسعه دهندگان دیگر برای اجتناب از conflict ها در پروژه استفاده کنیم، زیرا ما secret ها و متغیرهای محیطی را commit نمیکنیم. آنها مختص کاربر (یا مختص محیط) هستند، و همینطور نیز باید باشد. به این ترتیب از commit های اتفاقی اطلاعات حساس مانند

API Key ،connection string ها و غیره جلوگیری می کنیم.

این یک اشباه رایج است که برای هرکسی، حداقل یکبار یا دوبار اتفاق افتاده است. اگر چنین اتفاقی بیفتد اغلب باید برای رفع اشتباه به عقب برگردید، چرا که تاریخچه commit ها برای همیشه باقی میمانند.

گاهی اوقات شامل لغو API Key ها یا تغییر گذرواژه های پایگاه داده می شود. این راه کار اصلا جالب نیست.

هردوی user secret ها و متغیرهای محیطی با مسطح سازی ساختار سلسله مراتبی پیکربندی ذخیره می شوند.

برای مثال، یک connection string در فایل appsettings.json، به این صورت به نظر میرسد:

برای آنکه بتوانیم آن را از متغیر محیطی بخوانیم، باید آن را با استفاده از دو علامت زیرخط ایجاد کنیم:

Secret ها، به عنوان مقادیر JSON ذخیره میشوند و میتوانیم آن را با مسطح سازی ساختار با استفاده از “:” ذخیره کنیم، مانند اینکه ما به بخشهای مختلف در source code دسترسی داشته باشیم:

بنابراین secret connection string ما به این شکل خواهد بود:

استفاده از متغیرهای محیطی کاملا راحت است. اما اگر شما چند پروژه را بر روی ماشین توسعه خود, توسعه میدهید، ممکن است به زودی پی ببرید که متغیرهای محیطی زیادی بر روی ماشین شما ذخیره شده است. به این دلیل است که شیوه توصیه شده برای ذخیره داده های حساس به صورت محلی، user secret ها میباشد.

دستورات Secret Manager

User secret ها، مقادیر پیکربندی مختص پروژه هستند و بنابراین برای محیط توسعه بسیار مناسب است، جایی که ما معمولاً ده ها یا صدها پروژه مختلف را می توانیم در اختیار داشته باشیم.

ما برای فعال کردن این مکانیسم و ذخیره secret های خود به صورت محلی، از چیزی به نام “Secret Manager” استفاده میکنیم.

برای شروع استفاده از secret ها، باید ابتدا به دایرکتوری پروژه مورد نظر برویم و با دستور زیر، آن را فعال کنیم:

به عنوان نتیجه، این دستور، یک entry در فایل csproj ایجاد میکند:

ما همچنین میتوانیم این کار را در ویژوال استودیو، با راست کلیک کردن بر روی پروژه و انتخاب “Manage User Secrets” نیز انجام دهیم.

برای ایجاد یا تغییر یک secret connection string، میتوانیم از دستور dotnet user-secrets set استفاده کنیم:

برای بررسی اینکه آیا ما با موفقیت آن را ایجاد کرده ایم یا خیر، میتوانیم از دستور list استفاده کنیم:

secret list در asp.net core

اکنون می توانیم با خیال راحت مقدار را از فایل appsettings.json (و/یا فایل appsettings.Development.json) حذف کنیم.

همچنین به راحتی میتوانیم تمام secret های خود را با راست کلیک کردن بر روی پروژه و انتخاب “Manage User Secrets” چک کنیم. با این کار، فایل secrets.json ویژه پروژه ما باز میشود:

حذف کردن یک secret، به آسانی set کردن آن است:

برای حذف تمام secret ها، میتوانیم از دستور clear استفاده کنیم:

اگر هم اکنون یک فایل secrets دارید که میخواهید به داخل پروژه موجود import کنید، میتوانید این کار را با دستور زیر با علامت pipe انجام دهید:

این می تواند بسیار کمک کند زیرا نیازی به وارد کردن همه تنظیمات به صورت دستی نداریم.

البته استفاده از secret ها، شیوه دسترسی به پیکربندی ما را تغییر نمیدهد، بنابرایم ما میتوانیم برای مپ کردن پیکربندی، از آبجکتهای strongly typed استفاده کنیم.

بسیار راحت است، اینطور نیست؟

مدیریت داده های پیکربندی به عنوان متغیرهای محیطی

اگر شما هنوز ترجیح میدهید که از متغیرهای محیطی برای ذخیره configuration تان استفاده کنید یا بر روی یک پروژه قدیمی کار میکنید که میخواهید این کار را انجام دهید، در این قسمت میخواهیم به آن بپردازیم.

همانطور که پیشتر ذکر کردیم، برای استفاده از متغیرهای محیطی به عنوان مقادیر پیکربندی، باید سلسله مراتب را با دو خط زیرین __، مسطح سازی کنیم.

بنابریان ببینیم که چطور میتوانیم مقادیر را برای پلتفرمهای مختلف set کنیم:

برای ویندوز در CMD، میتوانیم از دستور set استفاده کنیم:

برای بررسی تمام متغیرهای محیطی (مختص کاربر)، میتوانیم set را بدون هیچ آرگومانی، تایپ کنیم. این تمام متغیرهایی را که تا به الان set کردیم را لیست میکند.

ما میتوانیم از PowerShell برای set کردن متغیر نیز استفاده کنیم:

این شیوه نسبت به استفاده از CMD، پیچیده تر است، اما در صورتی که از اسکریپتهای PowerShell برای set کردن متغیرهای پیکربندی استفاده میکنید، میتواند مفید باشد.

میتوانیم متغیرمان را با دستور زیر بررسی کنیم:

در Linux، میتوانیم متغیر را با استفاده از دستور export ست کنیم:

برای لیست کردن تمام متغیرها در Linux، میتوانیم به سادگی، دستور set را تایپ کنیم و برای حذف متغیر، میتوانیم از دستور unset استفاده کنیم:

شما میتوانید شیوه ای را که خودتان ترجیح میدهید را برای ذخیره داده های پیکربندی اتخاذ کنید، اما همانطور که قبلا بحث کردیم، user secret ها، خیلی شیوه راحت تری برای انجام این کار به نظر میرسند. ما یک CLI اختصاصی و یک مکانیسم خوب ویژه پروژه برای انجام این کار در اختیار داریم.

ما با خیال راحت میتوانیم connection string ها و دیگر داده های حساس را از فایلهای appsettings خود حذف کنیم.

نتیجه گیری

در این مقاله، ما در مورد نحوه محافظت از داده های حساس و اجتناب از conflict به طور local و در حالیکه بر روی پروژه های بزرگتر با چند توسعه دهنده نرم افزار کار میکنیم صحبت کردیم. ما در مورد معایب و مزایای user secret ها و متغیرهای محیطی صحبت کردیم و نحوه استفاده از هر دو روش برای set کردن مقادیر پیکربندی برای پروژه خود را دیدیم.

در قسمت بعدی، نحوه محافظت از داده های حساس در محیط production با استفاده از Azure Key Vault را میبنیم.

میتوانید دیگر قسمتهای این سری از آموزش سریالی را در صفحه ASP.NET Core Web API ببینید.

نویسنده

امید عباسی
من امید عباسی هستم. سالهاست که در زمینه برنامه نویسی با تکنولوژی دات نت فعالیت میکنم و عاشق این هستم که تجربیات و دانش خودم را در این زمینه با دیگران به اشتراک بزارم. خیلی دوست دارم که نظر و انتقاد خودتون رو در مورد این نوشته برای من بنویسید تا بتونم در آینده، مطالب بهتر و ارزشمندتری را برای شما فراهم کنم. در صورت داشتن هرگونه سوال هم در قسمت دیدگاه ها میتونید با بنده در ارتباط باشید