عنوان:

‫ تقویت امنیت ذخیره‌سازی فایل در برنامه‌های وب دات‌نت با استفاده از اصل "کمترین امتیاز" در IIS


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۷/۱۳ ۱۱:۳۵
آدرس: www.dntips.ir
در برنامه‌های تحت وب، قابلیت آپلود فایل توسط کاربر یک ویژگی بسیار رایج و در عین حال بسیار پرخطر است. اگرچه توسعه‌دهندگان تلاش می‌کنند تا با اعتبارسنجی (Validation) نوع و محتوای فایل‌ها در کد برنامه، جلوی آپلود کدهای مخرب یا فایل‌های اجرایی ناخواسته را بگیرند، اما یک اصل اساسی در امنیت وجود دارد: امنیت نباید تنها به یک لایه متکی باشد.
در اینجا، ما به لایه حیاتی امنیت در سطح سیستم عامل (OS-Level) می‌پردازیم که مفهوم دفاع عمقی (Defense in Depth) را پیاده‌سازی می‌کند. هدف این است که حتی اگر مهاجم بتواند تمامی کنترل‌های امنیتی در کد دات‌نت شما را دور بزند، سیستم عامل ویندوز باز هم جلوی دسترسی او به مکان‌های حساس و اجرای عملیات مخرب را بگیرد. این کار با استفاده از اصل کمترین امتیاز (Principle of Least Privilege) از طریق پیکربندی درست هویت App Pool در IIS انجام می‌شود.

هسته امنیتی: هویت Application Pool در IIS

برنامه‌های وب دات‌نتی در وب سرور IIS (Internet Information Services) اجرا می‌شوند. هر وب‌سایت در IIS در یک Application Pool مجزا اجرا می‌شود. این Application Pool به نوبه خود تحت یک هویت (Identity) کار می‌کند که در واقع یک حساب کاربری ویندوز است. تمامی دسترسی‌های برنامه وب شما (مثل خواندن از دیتابیس، نوشتن فایل روی دیسک) توسط امتیازات همین حساب کاربری کنترل می‌شود.

چالش سنتی: بسیاری از توسعه‌دهندگان، برای جلوگیری از مشکلات دسترسی، Application Pool را با هویت‌های با امتیاز بالا مثل LocalSystem یا یک حساب کاربری مدیر (Administrator) تنظیم می‌کنند. این یک اشتباه امنیتی مهلک است. اگر یک مهاجم بتواند از طریق برنامه وب نفوذ کند (مثلاً با بارگذاری یک شل مخرب)، به دلیل امتیاز بالای آن حساب، می‌تواند کنترل کامل سرور را به دست بگیرد.

راه‌حل امن: استفاده از هویت ApplicationPoolIdentity. این هویت یک حساب کاربری مجازی و منحصر به فرد است که به صورت پویا توسط IIS و سیستم عامل ویندوز برای هر Application Pool ایجاد می‌شود. این حساب‌ها:
  • امتیازات بسیار کمی دارند.
  • به طور پیش‌فرض، حتی در گروه کاربران استاندارد (Users) ویندوز هم نیستند.
  • فقط با نام خود Application Pool قابل ارجاع هستند (مثلاً: IIS AppPool\MyAppPool).
این ساختار تضمین می‌کند که دسترسی‌های برنامه وب شما دقیقاً و فقط به اندازه نیاز آن باشد.

پیکربندی امنیتی با PowerShell

کد ارائه شده‌ی در زیر، یک رویکرد عالی و خودکار برای پیاده‌سازی اصل کمترین امتیاز با استفاده از زبان PowerShell در محیط ویندوز سرور است.

مرحله ۱: تنظیم هویت Application Pool

# Set the application pool to use the default identity (not LocalSystem!)
Set-ItemProperty "IIS:\AppPools\MyAppPool" -Name processModel.identityType -Value ApplicationPoolIdentity
تحلیل و تأثیر:
  • دستور:Set-ItemProperty برای تغییر تنظیمات در IIS استفاده می‌شود.
  • مسیر:"IIS:\AppPools\MyAppPool" Application Pool مورد نظر را مشخص می‌کند (در اینجا MyAppPool).
  • تنظیم:processModel.identityType هویت فرآیند Worker را تعیین می‌کند.
  • مقدار:ApplicationPoolIdentity هویت منحصر به فرد و کم‌امتیاز را برای اجرای فرآیند برنامه وب تنظیم می‌کند.
تأثیر امنیتی: این کار مطمئن می‌شود که برنامه وب شما تحت یک حساب با امتیاز محدود اجرا شود و از حساب‌های با امتیاز بالا مانند LocalSystem یا Administrator که می‌توانند به فایل‌های سیستمی دسترسی داشته باشند، جلوگیری می‌کند.

مرحله ۲: اعطای مجوزهای حداقل به مسیر آپلود

# Grant minimal permissions to the upload directory
$uploadPath = "D:\Uploads"
$appPoolIdentity = "IIS AppPool\MyAppPool"

# Remove inherited permissions
$acl = Get-Acl $uploadPath
$acl.SetAccessRuleProtection($true, $false)

# Grant only Write permission (add Read if you need to serve files back)
$writePermission = New-Object System.Security.AccessControl.FileSystemAccessRule(
    $appPoolIdentity,
    "Write",
    "ContainerInherit,ObjectInherit",
    "None",
    "Allow"
)
$acl.AddAccessRule($writePermission)
Set-Acl $uploadPath $acl
تحلیل و تأثیر:
  • تعریف متغیرها: مسیر آپلود فایل ($uploadPath) و نام کامل هویت Application Pool ($appPoolIdentity) ذخیره می‌شوند. نام هویت همیشه به صورت IIS AppPool\نام_AppPool است.
  • دریافت ACL فعلی:$acl = Get-Acl $uploadPath لیست کنترل دسترسی (Access Control List - ACL) فعلی پوشه آپلود را دریافت می‌کند.
  • قطع وراثت مجوزها (بسیار حیاتی):
$acl.SetAccessRuleProtection($true, $false)
  • $true: مجوزهای این پوشه را از والد (مثلاً درایو D:) جدا می‌کند.
  • $false: به جای کپی کردن مجوزهای والد، آن‌ها را حذف می‌کند.
  • تأثیر امنیتی: این مهم‌ترین گام است. با حذف مجوزهای وراثتی، اطمینان حاصل می‌شود که گروه‌های با امتیاز بالا مثل Users یا Authenticated Users که به صورت پیش‌فرض دسترسی دارند، نتوانند به این پوشه دسترسی پیدا کنند.
  • تعریف قانون دسترسی (Access Rule): یک قانون جدید ایجاد می‌شود که فقط به هویت Application Pool اجازه دسترسی می‌دهد.
  • هویت:$appPoolIdentity
  • نوع دسترسی:"Write" (نوشتن). این تنها چیزی است که برای آپلود فایل لازم است. اعطای حق Modify یا Full Control خطرناک است.
  • وراثت:"ContainerInherit,ObjectInherit" تضمین می‌کند که این مجوز فقط به زیرپوشه‌ها و فایل‌های درون پوشه آپلود اعمال شود.
  • اعمال تغییرات: قانون دسترسی جدید به ACL اضافه شده و سپس با Set-Acl بر روی پوشه اعمال می‌شود.
  • تأثیر امنیتی نهایی: اکنون برنامه وب دات‌نت شما فقط و فقط می‌تواند در این یک مسیر خاص فایل بنویسد. اگر مهاجم تلاش کند تا از طریق برنامه، در مسیرهای حساس دیگر (مثلاً پوشه C:\Windows\System32) فایل بنویسد، سیستم عامل به دلیل عدم وجود مجوز در سطح Application Pool، عملیات را مسدود می‌کند.


نکات تکمیلی برای غنی‌سازی امنیت (Defense in Depth)

برای یک رویکرد جامع‌تر در امنیت ذخیره‌سازی فایل در برنامه‌های دات‌نت، علاوه بر اعمال مجوزهای OS-Level، باید اقدامات زیر در لایه کد و پیکربندی IIS نیز انجام شود:

۱. بررسی و اعتبارسنجی نوع فایل در کد دات‌نت

  • اعتبارسنجی پسوند: فقط پسوندهای مجاز (مثل .jpg, .png, .pdf) باید اجازه آپلود داشته باشند.
  • بررسی امضای فایل (Magic Number): صرفاً اتکا به پسوند کافی نیست، زیرا مهاجم می‌تواند آن را تغییر دهد. باید چند بایت اول فایل (Magic Number) را بررسی کنید تا مطمئن شوید که نوع واقعی فایل با پسوند آن مطابقت دارد (مثلاً یک فایل با پسوند .jpg واقعاً یک تصویر JPEG باشد و نه یک فایل .exe تغییر نام داده شده).
  • اسکن محتوا: در صورت امکان، فایل‌های آپلود شده باید با یک آنتی‌ویروس یا اسکنر محتوا بررسی شوند تا بدافزارها و کدهای مخرب شناسایی شوند.

۲. ذخیره‌سازی فایل‌ها خارج از ریشه وب (Web Root)

  • توصیه امنیتی: فایل‌های آپلود شده توسط کاربران (مانند تصاویر پروفایل، اسناد) باید در خارج از پوشه‌هایی که IIS آن‌ها را مستقیماً سرو می‌کند (مثل wwwroot یا مسیر اصلی سایت) ذخیره شوند.
  • دلیل: اگر فایل‌های آپلود شده در داخل ریشه وب باشند، در صورت موفقیت‌آمیز بودن آپلود یک شل مخرب، مهاجم می‌تواند به راحتی با مرورگر به آن دسترسی پیدا کرده و آن را اجرا کند.
  • راه‌حل: فایل‌ها را در مسیری اختصاصی (مانند D:\Uploads که در مثال کد فوق ذکر شد) ذخیره کنید و برای ارائه آن‌ها به کاربر، از یک Controller/Action در ASP.NET استفاده کنید که احراز هویت و مجوز دسترسی را قبل از ارسال فایل به کاربر بررسی می‌کند.

۳. غیرفعال کردن اجرای اسکریپت در مسیر آپلود

کاربرد: حتی اگر فایل‌های آپلود شده در پوشه‌ای خارج از ریشه وب نیستند، باید مطمئن شوید که IIS هرگز سعی نمی‌کند محتوای آن‌ها را به عنوان کد اجرایی (مثل ASPX، PHP یا حتی HTML حاوی اسکریپت) تفسیر کند.
اقدام:
  • در مسیر آپلود فایل، اجرای اسکریپت را در تنظیمات IIS غیرفعال کنید.
  • یا برای اطمینان بیشتر، یک فایل web.config در آن پوشه قرار دهید تا اجرای اسکریپت‌ها را به طور کامل محدود کند.

در ادامه توضیح می‌دهم که چطور قرار دادن یک فایل web.config در پوشه‌ی آپلود، می‌تواند امنیت را با غیرفعال کردن اجرای اسکریپت‌ها به‌طور کامل، تقویت کند.

تقویت امنیت: غیرفعال‌سازی اجرای اسکریپت با Web.config

یکی از حیاتی‌ترین اقدامات امنیتی در برنامه‌های وب، به‌ویژه در پوشه‌هایی که کاربران می‌توانند در آن فایل آپلود کنند، جلوگیری از اجرای هرگونه کد یا اسکریپت است. مهاجمان معمولاً تلاش می‌کنند فایل‌هایی با پسوندهای قابل اجرا (مانند .aspx, .ashx, .php, .exe) را آپلود کنند تا بتوانند از طریق آن‌ها به سرور دسترسی پیدا کنند (معروف به Web Shell).
حتی اگر شما در کد دات‌نت خود، آپلود فایل‌های اجرایی را ممنوع کرده باشید، قرار دادن یک فایل web.config با تنظیمات محدودکننده در پوشه‌ی آپلود، یک لایه‌ی دفاعی دیگر را در سطح خود IIS ایجاد می‌کند. این تنظیمات، هرگونه تلاش برای اجرای فایل‌ها را مستقیماً در وب سرور متوقف می‌کند.
شما باید این فایل را با محتوای زیر در داخل پوشه‌ای که برای آپلود فایل‌ها (مانند D:\Uploads در مثال قبلی) استفاده می‌کنید، قرار دهید:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <clear />
        </handlers>

        <modules>
            <remove name="ManagedEngine" />
        </modules>

        <security>
            <requestFiltering>
                <requestLimits maxAllowedContentLength="52428800" /> </requestFiltering>
        </security>
        
    </system.webServer>
</configuration>

تحلیل و تأثیر هر بخش

۱. حذف Handlerها (Handlers)
<handlers>
    <clear />
</handlers>
تحلیل: بخش handlers در IIS مسئول نگاشت پسوندهای فایل به ماژول‌های پردازشگر است. به عنوان مثال، Handler مربوط به ASP.NET، درخواست‌های مربوط به فایل‌های .aspx را به موتور دات‌نت ارجاع می‌دهد.
تأثیر امنیتی: تگ تمام Handlerهای ارث‌بری شده از سایت اصلی را حذف می‌کند. این عمل به IIS می‌گوید که "این پوشه نمی‌تواند هیچ فایلی را اجرا کند، حتی اگر پسوند آن مربوط به یک Handler ثبت شده باشد". در نتیجه، اگر مهاجم یک فایل .aspx مخرب هم آپلود کند، IIS صرفاً آن را به عنوان یک فایل متنی یا باینری در نظر می‌گیرد و نه یک برنامه قابل اجرا، که عملاً از اجرای آن جلوگیری می‌کند.

۲. حذف ماژول‌های مدیریتی (Modules)
<modules>
    <remove name="ManagedEngine" />
</modules>
تحلیل: ماژول‌ها در IIS عملکرد اصلی سرور (مانند احراز هویت، کشینگ یا فشرده‌سازی) را انجام می‌دهند. ماژول ManagedEngine مسئول بارگذاری و اجرای کدهای دات‌نت است.
تأثیر امنیتی: با حذف این ماژول، عملاً قابلیت‌های اجرای ASP.NET از روی این پوشه برداشته می‌شود. این اقدام یک لایه‌ی دفاعی مضاعف در برابر هرگونه سوء استفاده‌ای است که بخواهد از طریق چارچوب دات‌نت در این مسیر اجرا شود.

۳. محدودیت‌های درخواست (Request Limits)
<requestLimits maxAllowedContentLength="52428800" />
تحلیل: این بخش به IIS اجازه می‌دهد تا محدودیت‌هایی را برای درخواست‌های HTTP اعمال کند.
تأثیر امنیتی: با تنظیم maxAllowedContentLength، شما حداکثر اندازه مجاز فایل برای آپلود در این پوشه را محدود می‌کنید (در مثال فوق ۵۰ مگابایت). این کار جلوی حملات محروم‌سازی از سرویس (DoS) را می‌گیرد که مهاجم در آن‌ها سعی می‌کند با ارسال فایل‌های بسیار بزرگ، منابع سرور را مصرف کند.

نتیجه‌گیری:
با قرار دادن این فایل web.config در پوشه آپلود و ترکیب آن با مجوزهای محدود سیستم عامل (فقط Write) و اعتبارسنجی نوع فایل در کد دات‌نت، شما یک دیوار دفاعی چندلایه ایجاد می‌کنید که نفوذ به سرور از طریق آپلود فایل را عملاً غیرممکن می‌سازد. این مصداق واقعی اجرای اصل دفاع عمقی (Defense in Depth) است.

نظرات

  • وحید نصیری در ۱۴۰۴/۰۷/۱۵ ۰۹:۴۲
    یک نکته‌ی تکمیلی:

    FileSignatures: کتابخانه‌ای در جهت پیاده سازی قسمت «بررسی امضای فایل (Magic Number): صرفاً اتکا به پسوند کافی نیست، زیرا مهاجم می‌تواند آن را تغییر دهد. باید چند بایت اول فایل (Magic Number) را بررسی کنید تا مطمئن شوید که نوع واقعی فایل با پسوند آن مطابقت دارد (مثلاً یک فایل با پسوند .jpg واقعاً یک تصویر JPEG باشد و نه یک فایل .exe تغییر نام داده شده).»