پرش به محتوای اصلی
آسیب‌پذیری‌های سایت

افشای پوشه .git چه خطری دارد؟ روش‌های جلوگیری از نشت سورس کد سایت

افشای پوشه .git زمانی رخ می‌دهد که اطلاعات داخلی Repository یک سایت از طریق وب‌سرور قابل دسترسی شود و در شرایطی Source Code، Git History و اطلاعات حساس پروژه را در معرض نشت قرار دهد. خطر اصلی فقط نسخه فعلی کد نیست؛ API Key، Token، Password یا فایل‌هایی که در گذشته حذف شده‌اند نیز ممکن است همچنان در تاریخچه Git باقی مانده باشند. جلوگیری از قرار گرفتن .

تیم امنیت رخنه‌کاو ۳۵ دقیقه مطالعه انتشار:

افشای پوشه .git یکی از خطاهای پیکربندی امنیتی خطرناک در وب‌سرورها است که می‌تواند اطلاعات مربوط به مخزن Git، تاریخچه تغییرات، نام فایل‌ها و در شرایطی بخش قابل‌توجهی از سورس کد یک سایت را در دسترس افراد غیرمجاز قرار دهد. اگر API Key، Token، رمز پایگاه داده، کلید خصوصی یا فایل‌های تنظیمات حساس در گذشته وارد Git شده باشند، خطر می‌تواند از یک Source Code Disclosure ساده به نفوذ جدی در زیرساخت تبدیل شود.

بهترین دفاع این نیست که فقط دسترسی وب به .git مسدود شود؛ در معماری صحیح، پوشه .git اساساً نباید بخشی از فایل‌های قابل سرویس‌دهی وب یا Artifact نهایی Production باشد.

مقدمه؛ یک پوشه مخفی که ممکن است بیشتر از سورس فعلی سایت را افشا کند

بسیاری از توسعه‌دهندگان هنگام Deploy کردن یک پروژه، کل Working Directory را از محیط توسعه یا Repository روی سرور کپی می‌کنند. در ظاهر همه چیز طبیعی است: فایل‌های PHP، JavaScript، CSS، تصاویر و تنظیمات سایت در Document Root قرار می‌گیرند و وب‌سرور آن‌ها را ارائه می‌کند.

اما اگر پوشه مخفی .git نیز همراه پروژه منتقل شده باشد، مسئله متفاوت می‌شود.

پوشه .git تنها یک نشانه برای مشخص کردن اینکه پروژه با Git مدیریت می‌شود نیست. این پوشه بخش مهمی از اطلاعات داخلی Repository را در خود نگهداری می‌کند؛ از Referenceها و اطلاعات Branchها گرفته تا Objectهایی که فایل‌ها و Commitهای پروژه را تشکیل می‌دهند.

اگر وب‌سرور به اشتباه اجازه دسترسی HTTP به این اطلاعات را بدهد، مهاجم ممکن است تصویری بسیار دقیق‌تر از پروژه به دست آورد؛ تصویری که صرفاً شامل HTML نهایی یا JavaScript عمومی سایت نیست.

در یک برنامه PHP، Laravel، WordPress سفارشی، Node.js، Python یا هر Backend دیگری، بخش قابل توجهی از منطق برنامه اصولاً قرار نیست برای بازدیدکننده سایت قابل مشاهده باشد. اما افشای Repository می‌تواند همین مرز را از بین ببرد.

مسئله زمانی جدی‌تر می‌شود که Git History را هم در نظر بگیریم.

ممکن است توسعه‌دهنده امروز Password پایگاه داده را از فایل تنظیمات حذف کرده باشد، اما نسخه‌ای از همان Password در Commit شش ماه قبل وجود داشته باشد. ممکن است فایل .env دیگر در نسخه فعلی Repository نباشد، اما زمانی Commit شده باشد. ممکن است Endpoint مدیریتی قدیمی، Debug Code، آدرس داخلی Server یا Token یک سرویس در نسخه‌های گذشته باقی مانده باشد.

بنابراین خطر افشای .git را نباید فقط با این سؤال ارزیابی کرد که «الان داخل سورس چه چیزی وجود دارد؟».

سؤال مهم‌تر این است:

Repository در تمام طول تاریخ خود چه اطلاعاتی در اختیار داشته است؟ پوشه .git چیست؟

پوشه .git چیست؟

وقتی یک Repository معمولی Git ایجاد یا Clone می‌شود، Git اطلاعات داخلی مورد نیاز خود را معمولاً داخل پوشه‌ای با نام .git در Root پروژه نگهداری می‌کند.

این اطلاعات برای مدیریت Version Control ضروری هستند.

Git باید بداند:

  • Branch فعلی چیست.
  • Commitهای قبلی کدام‌اند.
  • چه فایل‌هایی در Repository وجود دارند.
  • وضعیت فایل‌های Stageشده چیست.
  • Tagها به چه Commitهایی اشاره می‌کنند.
  • Remote Repository چیست.
  • Objectهای مربوط به فایل‌ها کجا قرار دارند.
  • تاریخچه Referenceها چگونه تغییر کرده است.

به همین دلیل .git یک Metadata Folder ساده نیست.

در Repository معمولی، این پوشه قلب اطلاعات Version Control پروژه محسوب می‌شود.

فایل HEAD

فایل HEAD مشخص می‌کند Repository در حال حاضر به کدام Branch یا Commit اشاره دارد.

این فایل معمولاً کوچک است، اما افشای آن می‌تواند اولین نشانه واضح باشد که یک Repository Git داخل مسیر قابل دسترسی وب قرار گرفته است.

خود HEAD الزاماً اطلاعات بحرانی مانند Password ندارد، اما ثابت می‌کند ساختار Git احتمالاً در همان محل حضور دارد.

پوشه objects

بخش objects اهمیت بسیار بیشتری دارد.

Git محتوا و ساختار Repository را با مجموعه‌ای از Objectها مدیریت می‌کند که می‌توانند شامل اطلاعات مربوط به فایل‌ها، Directoryها و Commitها باشند.

از دید امنیتی همین نکته اهمیت دارد:

اطلاعاتی که برای بازسازی وضعیت‌ها و تاریخچه Repository لازم است ممکن است داخل .git وجود داشته باشد.

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

پوشه refs

Referenceها یا Refها به نقاط مهم تاریخچه Repository اشاره می‌کنند.

برای مثال Branchها و Tagها با Referenceها ارتباط دارند.

این اطلاعات به Git کمک می‌کنند بفهمد هر Branch در چه نقطه‌ای از تاریخچه قرار دارد.

فایل index

Index که به Staging Area نیز مرتبط است، حاوی اطلاعاتی درباره مسیر فایل‌های موجود در وضعیت فعلی Repository است.

از نظر امنیتی حتی لو رفتن نام و مسیر فایل‌ها هم می‌تواند ارزشمند باشد.

تصور کنید مهاجم بفهمد پروژه دارای فایل‌هایی با نام‌های زیر است:

config-production.php

internal-api.php

payment-service.php

backup-handler.php

admin-tools.php

حتی اگر محتوای این فایل‌ها بلافاصله در اختیار او قرار نگیرد، Architecture Discovery بسیار ساده‌تر می‌شود.

فایل config

Repository Configuration ممکن است اطلاعاتی درباره Remoteها و تنظیمات Git داشته باشد.

در شرایط نامناسب، این داده‌ها می‌توانند نام Repository داخلی، آدرس Git Server، نام Organization، مسیرهای Infrastructure یا اطلاعات دیگری درباره محیط توسعه را آشکار کنند.

نباید فرض کرد فایل Configuration همیشه Secret مستقیم دارد، اما حتی اطلاعات غیرمحرمانه نیز می‌توانند برای Reconnaissance مفید باشند.

Logs و Reflog

Git می‌تواند تغییرات Referenceها را در Reflogها ثبت کند.

وجود این اطلاعات به معنی آن است که فقط وضعیت فعلی Repository مهم نیست؛ آثار تغییرات قبلی نیز ممکن است در دسترس باشند.

همین ماهیت تاریخی Git است که Exposure آن را با افشای یک Directory معمولی متفاوت می‌کند.

افشای پوشه .git دقیقاً یعنی چه؟

افشای پوشه .git زمانی رخ می‌دهد که یک Repository یا بخشی از اطلاعات داخلی آن از طریق Web Server برای Client خارجی قابل دریافت باشد.

برای مثال ممکن است سایت در مسیر زیر قرار گرفته باشد:

/var/www/example/

و توسعه‌دهنده کل Repository را همان‌جا Deploy کرده باشد:

/var/www/example/.git/

اگر Apache، Nginx، CDN، Reverse Proxy یا Web Server دیگری درخواست‌های مربوط به این Directory را مسدود نکند، بخشی از محتویات Git ممکن است از طریق HTTP در دسترس قرار گیرد.

Directory Listing تنها مشکل نیست

یکی از تصورات اشتباه این است که اگر Directory Listing خاموش باشد، .git امن است.

این نتیجه‌گیری درست نیست.

Directory Listing فقط تعیین می‌کند آیا Web Server هنگام درخواست یک Directory، فهرست فایل‌های آن را نمایش بدهد یا خیر.

ممکن است Listing غیرفعال باشد، اما اگر نام یک فایل مشخص باشد، Web Server همچنان همان فایل را ارائه کند.

بنابراین امنیت Repository نباید به مخفی ماندن نام فایل‌ها وابسته باشد.

Exposure می‌تواند ناقص باشد

همیشه تمام Repository در دسترس نیست.

ممکن است:

  • فقط بعضی فایل‌های .git قابل دریافت باشند.
  • بعضی مسیرها 403 بدهند و بعضی مسیرها باز باشند.
  • CDN نسخه‌هایی از فایل‌ها را Cache کرده باشد.
  • یک Virtual Host امن باشد ولی Host دیگری همان Directory را منتشر کند.
  • Root اصلی محافظت شده باشد اما Repository دیگری در Subdirectory فراموش شده باشد.

به همین دلیل ارزیابی Exposure باید جامع باشد. چرا افشای پوشه .git خطرناک است؟

چرا افشای پوشه .git خطرناک است؟

شدت آسیب به اطلاعات موجود در Repository، تنظیم Web Server و میزان دسترسی ایجادشده بستگی دارد.

در بدترین سناریوها ممکن است اطلاعات کافی برای بازسازی بخش بزرگی از Repository در اختیار فرد غیرمجاز قرار بگیرد.

این موضوع چند لایه خطر ایجاد می‌کند.

۱. نشت سورس کد Backend

اولین و واضح‌ترین خطر، Source Code Disclosure است.

کدی که Server-side اجرا می‌شود معمولاً برای Browser ارسال نمی‌شود.

برای مثال Browser نتیجه اجرای PHP را دریافت می‌کند، نه فایل PHP اصلی را.

اما اگر Repository افشا شود، مهاجم ممکن است به Source Code اصلی Backend دسترسی پیدا کند.

این کد می‌تواند اطلاعات مهمی درباره موارد زیر آشکار کند:

  • منطق Authentication
  • Authorization
  • Session Management
  • ساختار Database
  • APIهای داخلی
  • Validation
  • File Upload
  • Payment Logic
  • مسیرهای Admin
  • Integrationهای خارجی
  • Featureهای آزمایشی
  • Debug Code
  • Libraryهای اختصاصی
  • کنترل‌های امنیتی

این مسئله الزاماً به معنی وجود Vulnerability نیست، اما هزینه تحلیل سیستم را برای مهاجم کاهش می‌دهد.

امنیت یک نرم‌افزار اصولاً نباید فقط به مخفی بودن Source Code وابسته باشد؛ بااین‌حال ارائه ناخواسته کد Backend به اینترنت همچنان یک Information Disclosure جدی است.

۲. افشای Git History

Git برای نگهداری تاریخچه ساخته شده است.

این ویژگی برای توسعه نرم‌افزار بسیار مفید است، اما در زمان Exposure به یک عامل افزایش ریسک تبدیل می‌شود.

ممکن است اطلاعاتی که مدت‌ها قبل از Source Code فعلی حذف شده‌اند، همچنان در Commitهای قبلی وجود داشته باشند.

برای نمونه توسعه‌دهنده ممکن است در یک Commit اولیه چنین اطلاعاتی قرار داده باشد:

  • Database Password
  • API Key
  • SMTP Password
  • Cloud Token
  • Private Endpoint
  • Debug Credential
  • SSH-related Secret
  • Encryption Key
  • Webhook Secret

بعداً متوجه اشتباه شده و فایل را اصلاح کرده باشد.

از نگاه نسخه فعلی پروژه، Secret دیگر وجود ندارد.

اما حذف یک مقدار در Commit جدید لزوماً آن را از Git History حذف نمی‌کند.

به همین دلیل Exposure Repository باید با دید تاریخی بررسی شود.

۳. نشت Secretها و Credentialها

یکی از جدی‌ترین پیامدهای افشای Git، Credential Leakage است.

Secretهایی مانند API Key، Token و Password گاهی به دلایل مختلف وارد Repository می‌شوند:

  • Hardcode هنگام تست
  • Commit اشتباهی .env
  • نمونه Configuration واقعی
  • فایل Backup
  • Script قدیمی
  • Credential داخل Documentation داخلی
  • کلید Deployment
  • Token سرویس Cloud
  • Connection String

اگر Repository در معرض اینترنت قرار گیرد، این Secretها ممکن است به سیستم دیگری نیز دسترسی ایجاد کنند.

بنابراین Blast Radius محدود به همان وب‌سایت نیست.

برای مثال یک Token می‌تواند به Cloud Storage مرتبط باشد، یک Database Credential ممکن است Database روی Server دیگری را باز کند و یک API Key ممکن است امکان استفاده مالی از سرویس خارجی را بدهد.

۴. افشای فایل‌های حذف‌شده

یکی از تفاوت‌های مهم Git با یک File Server معمولی همین است.

حذف کردن فایل از Working Tree لزوماً به این معنی نیست که محتوای تاریخی آن از Repository ناپدید شده باشد.

ممکن است فایلی سال گذشته حذف شده باشد اما نسخه آن در Commitهای قدیمی باقی مانده باشد.

نمونه‌های حساس عبارت‌اند از:

  • .env
  • فایل Backup تنظیمات
  • Configuration قدیمی Production
  • Script مهاجرت
  • Private Key قدیمی
  • SQL Dump
  • فایل Debug
  • نسخه موقت Credential

بنابراین بررسی امنیت Repository باید Git History را نیز پوشش دهد.

۵. افشای معماری داخلی سایت

حتی Repository بدون Password نیز می‌تواند اطلاعات امنیتی ارزشمندی در اختیار مهاجم قرار دهد.

ساختار Directoryها ممکن است معماری برنامه را آشکار کند:

  • Authentication Service
  • Admin API
  • Payment Module
  • Backup Module
  • Internal Queue
  • Worker
  • Cron Job
  • Storage Adapter
  • Webhook Handler

این اطلاعات برای Threat Modeling مفیدند؛ متأسفانه هم برای تیم دفاعی و هم برای مهاجم.

مهاجم دیگر لازم نیست تمام معماری را از رفتار خارجی سایت حدس بزند.

۶. شناسایی Endpointهای پنهان یا قدیمی

ممکن است Source Code دارای Endpointهایی باشد که در Navigation عمومی سایت دیده نمی‌شوند.

برای مثال:

  • Route مدیریتی
  • Endpoint قدیمی
  • API آزمایشی
  • Debug Route
  • Webhook
  • Internal Callback

وجود Endpoint مخفی به معنی آسیب‌پذیر بودن آن نیست، اما افشای Source Code باعث می‌شود Security by Obscurity از بین برود.

اگر Authentication یا Authorization یکی از این مسیرها ناقص باشد، خطر جدی‌تر می‌شود.

۷. مشخص شدن Dependencyها و نسخه‌های قدیمی

Source Code و فایل‌های Package Management می‌توانند اطلاعاتی درباره کتابخانه‌های پروژه ارائه دهند.

برای مثال:

  • Composer
  • npm
  • pip
  • Bundler
  • سایر Dependency Managerها

شناخت دقیق Technology Stack می‌تواند جست‌وجوی Vulnerabilityهای شناخته‌شده را برای مهاجم ساده‌تر کند.

این موضوع یکی دیگر از دلایلی است که Repository Production نباید عمومی باشد.

۸. نشت اطلاعات توسعه‌دهندگان

Commit Metadata ممکن است نام یا Email توسعه‌دهندگان را در خود داشته باشد.

این داده‌ها لزوماً Secret نیستند، اما می‌توانند برای Social Engineering و Phishing ارزشمند باشند.

در یک حمله هدفمند، مهاجم ممکن است بفهمد:

  • چه کسانی روی پروژه کار کرده‌اند.
  • چه الگوی Emailی در سازمان استفاده می‌شود.
  • چه بخش‌هایی توسط چه توسعه‌دهنده‌ای تغییر کرده‌اند.

این اطلاعات می‌توانند مرحله Reconnaissance یک حمله گسترده‌تر را تقویت کنند.

۹. افشای Remote Repository و زیرساخت توسعه

اطلاعات Repository ممکن است نام یا آدرس Remote Source Control را مشخص کنند.

این موضوع می‌تواند ساختار Development Infrastructure را تا حدی نمایان کند.

برای مثال ممکن است مشخص شود پروژه از:

  • GitHub
  • GitLab
  • Bitbucket
  • Git Server داخلی
  • Hostname خصوصی

استفاده می‌کند.

این اطلاعات به تنهایی نفوذ ایجاد نمی‌کنند، اما Exposure غیرضروری Infrastructure محسوب می‌شوند.

۱۰. افزایش ریسک Supply Chain

اگر Repository شامل Tokenهای Registry یا CI/CD Credential باشد، تأثیر ممکن است از همان وب‌سایت فراتر برود.

Credentialهای مرتبط با:

  • Package Registry
  • Container Registry
  • CI/CD
  • Deployment
  • Cloud
  • Artifact Storage

در صورت افشا ممکن است بخش دیگری از Software Supply Chain را تحت تأثیر قرار دهند.

به همین دلیل Incident مربوط به .git باید فقط به عنوان «نشت چند فایل سایت» بررسی نشود.

شدت آسیب‌پذیری افشای .git چقدر است؟

Severity ثابت نیست.

برای ارزیابی درست باید چند سؤال مطرح شود.

<table> <thead> <tr> <th>عامل</th> <th>ریسک کمتر</th> <th>ریسک بالاتر</th> </tr> </thead> <tbody> <tr> <td>میزان Exposure</td> <td>فقط یک Metadata محدود</td> <td>امکان دسترسی گسترده به Objectها و History</td> </tr> <tr> <td>نوع پروژه</td> <td>Static Site عمومی</td> <td>Backend، پنل مالی یا سرویس حساس</td> </tr> <tr> <td>Secretها</td> <td>هیچ Credential فعالی وجود ندارد</td> <td>Token یا Password فعال وجود دارد</td> </tr> <tr> <td>محیط</td> <td>Development جداشده</td> <td>Production</td> </tr> <tr> <td>سطح دسترسی Credential</td> <td>Read-only و محدود</td> <td>Admin، Root یا Cloud Credential</td> </tr> <tr> <td>مدت Exposure</td> <td>مدت کوتاه و بدون نشانه دسترسی</td> <td>Exposure طولانی و Public</td> </tr> </tbody> </table>

اگر Repository Production حاوی Credential فعال باشد، رخداد باید با جدیت بالایی بررسی شود. افشای .git چه خطری برای سایت وردپرسی دارد؟

افشای .git چه خطری برای سایت وردپرسی دارد؟

WordPress Core معمولاً به Git برای Runtime نیاز ندارد.

اما بسیاری از توسعه‌دهندگان برای مدیریت Theme، Plugin یا کل سایت از Git استفاده می‌کنند.

مشکل زمانی ایجاد می‌شود که Repository مستقیماً داخل Web Root قرار بگیرد.

برای مثال ممکن است Repository شامل موارد زیر باشد:

  • Theme اختصاصی
  • Plugin اختصاصی
  • wp-config.php
  • Configurationهای Deployment
  • API Key افزونه‌ها
  • کد Integration
  • Scriptهای مدیریتی
  • نسخه‌های قدیمی فایل‌ها

افشای کد Theme به تنهایی شاید همیشه بحرانی نباشد، اما Plugin اختصاصی ممکن است Business Logic یا Endpointهای مهمی داشته باشد.

اگر اطلاعات wp-config.php یا نسخه تاریخی آن وارد Repository شده باشد، مسئله جدی‌تر می‌شود.

به همین دلیل در سایت WordPress نیز Git Repository باید از مسیر Public Web جدا باشد یا حداقل .git هرگز در Deployment Artifact قرار نگیرد.

آیا فقط مخفی بودن پوشه .git کافی است؟

خیر.

. در ابتدای نام فایل یا Directory در Linux باعث می‌شود آن مورد در برخی Listingهای معمولی مخفی باشد.

اما Hidden File به معنی Protected File نیست.

اگر Web Server اجازه خواندن آن را بدهد، مخفی بودن نام هیچ Security Boundary ایجاد نمی‌کند.

همین اصل درباره فایل‌هایی مانند زیر نیز صدق می‌کند:

  • .env
  • .htpasswd
  • .svn
  • .DS_Store
  • فایل‌های Dotfile دیگر

نام مخفی جای Access Control را نمی‌گیرد.

چگونه سایت خودمان را از نظر افشای .git بررسی کنیم؟

بررسی باید فقط روی سایت یا سامانه‌ای انجام شود که مالک آن هستید یا مجوز تست آن را دارید.

هدف بررسی این است که مطمئن شویم درخواست خارجی نمی‌تواند محتوای Repository را دریافت کند.

بررسی از بیرون شبکه

فقط بررسی فایل‌های Server از داخل کافی نیست.

ممکن است روی Server تصور کنید Rule امنیتی فعال است، اما Reverse Proxy، CDN یا Virtual Host دیگری رفتار متفاوتی داشته باشد.

از یک Client خارجی بررسی کنید درخواست به مسیرهای مربوط به .git آیا:

  • 404 Not Found
  • 403 Forbidden

برمی‌گرداند یا اینکه محتوای داخلی Git را نمایش می‌دهد.

هدف این است که هیچ Metadata واقعی Repository از اینترنت تحویل داده نشود.

فقط Root سایت را بررسی نکنید

گاهی Repository اصلی محافظت شده ولی Repository دیگری در مسیر فرعی باقی مانده است.

برای مثال:

  • نسخه قدیمی سایت
  • Staging
  • Backup
  • Subdomain
  • مسیر Development
  • Plugin اختصاصی
  • Application فرعی

Inventory دقیق Web Rootها اهمیت دارد.

Virtual Hostها را بررسی کنید

یک Directory ممکن است توسط چند Hostname قابل دسترسی باشد.

گاهی Security Rule روی Domain اصلی فعال است، اما:

  • IP مستقیم
  • Subdomain قدیمی
  • Development Host
  • Default Virtual Host

همان Directory را بدون حفاظت ارائه می‌کند.

CDN و Cache را فراموش نکنید

اگر فایل حساس قبلاً از طریق CDN در دسترس بوده باشد، صرفاً اصلاح Origin ممکن است تمام نسخه‌های Cacheشده را فوراً حذف نکند.

در Incident واقعی باید Cache و Edge Configuration نیز بررسی شوند. بهترین روش جلوگیری: .git را وارد Production Web Root نکنید

بهترین روش جلوگیری: .git را وارد Production Web Root نکنید

مهم‌ترین اصل پیشگیری همین است.

Web Server برای اجرای Application معمولاً به Repository Metadata احتیاجی ندارد.

پس چرا باید .git کنار فایل‌های Public قرار گیرد؟

در Deployment حرفه‌ای بهتر است Artifact نهایی فقط شامل فایل‌هایی باشد که Application برای اجرا نیاز دارد.

به بیان ساده:

Production باید محصول Build یا Deployment باشد، نه Clone کامل محیط توسعه.

این طراحی چند مزیت دارد:

  • .git در Web Root نیست.
  • فایل‌های Development منتقل نمی‌شوند.
  • Testها کمتر وارد Production می‌شوند.
  • Documentation داخلی حذف می‌شود.
  • فایل‌های موقت منتقل نمی‌شوند.
  • Attack Surface کاهش می‌یابد.
  • Deployment قابل تکرارتر می‌شود.

Deploy مستقیم با Git روی سرور چه مشکلی دارد؟

برخی تیم‌ها وارد Web Root می‌شوند و همان‌جا Repository را Update می‌کنند.

این روش ساده است، اما باعث می‌شود .git دقیقاً کنار فایل‌هایی قرار گیرد که Web Server می‌تواند به آن‌ها دسترسی داشته باشد.

ممکن است Rule فعلی Web Server آن را مسدود کند، اما در آینده Configuration تغییر کند.

بنابراین شما یک Asset حساس را داخل Public Directory نگهداری کرده‌اید و امیدوارید Access Control همیشه درست باقی بماند.

روش قوی‌تر این است که Repository یا Build Workspace خارج از Document Root باشد و فایل‌های لازم به محل Deployment منتقل شوند.

جلوگیری از افشای .git در Apache

اگر به هر دلیل .git روی همان Server وجود دارد، Web Server باید دسترسی به آن را به‌طور صریح مسدود کند.

در Apache 2.4 می‌توان در Configuration اصلی یا Virtual Host از Rule مبتنی بر Directory استفاده کرد.

نمونه دفاعی:

<DirectoryMatch "(^|/)\.git(/|$)">
    Require all denied
</DirectoryMatch>

هدف این Rule جلوگیری از سرو شدن Directoryهای .git است.

در معماری‌هایی که تنها به .htaccess دسترسی دارند، می‌توان با Rule مناسب درخواست‌های مربوط به .git را Reject کرد:

RewriteEngine On
RewriteRule (^|/)\.git(?:/|$) - [F,L]

بعد از تغییر Configuration باید Syntax و رفتار واقعی سایت بررسی شود.

تنها قرار دادن Rule در فایل بدون Test کافی نیست.

جلوگیری از افشای .git در Nginx

در Nginx نیز می‌توان درخواست مربوط به .git را در سطح Server Block مسدود کرد.

نمونه ساده:

location ~ /\.git(?:/|$) {
    return 404;
}

بازگرداندن 404 به جای ارائه فایل باعث می‌شود Repository از طریق این مسیر قابل دریافت نباشد.

در بعضی معماری‌ها ممکن است تصمیم گرفته شود اکثر Dotfileها مسدود شوند.

اما هنگام طراحی چنین Rule گسترده‌ای باید موارد قانونی مانند مسیر .well-known که برای بعضی سرویس‌ها کاربرد دارد در نظر گرفته شوند.

بنابراین Rule عمومی Dotfile باید قبل از اعمال روی Production با معماری سایت تطبیق داده شود.

چرا حذف Directory Listing کافی نیست؟

فرض کنید Apache یا Nginx فهرست محتویات .git را نشان نمی‌دهد.

این فقط مانع نمایش خودکار فهرست می‌شود.

اگر File Handler همچنان اجازه ارائه یک فایل مشخص را بدهد، عدم Listing جلوی آن را نمی‌گیرد.

Security Control باید Access را Block کند، نه فقط نمایش Index را.

این تفاوت مهمی است.

Permission فایل‌ها مشکل را حل می‌کند؟

Permission سیستم‌عامل ضروری است، اما راه‌حل اصلی Exposure وب نیست.

Web Server Process برای اجرای سایت باید بتواند فایل‌های زیادی را بخواند.

اگر همان Process بتواند .git را نیز بخواند و Configuration اجازه سرو کردن آن را داشته باشد، Permission معمولی ممکن است مانع Exposure نشود.

بنابراین چند لایه لازم است:

  1. .git خارج از Public Root باشد.
  2. Web Server دسترسی HTTP به آن را مسدود کند.
  3. File Permission براساس Least Privilege تنظیم شود.
  4. Deployment Process مانع ورود Repository Metadata شود.

جلوگیری از افشای Git در Docker

Container Image یکی دیگر از نقاطی است که Repository Metadata ممکن است ناخواسته وارد آن شود.

برای مثال اگر هنگام Build کل Directory پروژه بدون محدودیت وارد Image شود، .git نیز ممکن است همراه آن منتقل شود.

بهتر است Build Context و Ignore Rules طوری طراحی شوند که فایل‌های غیرضروری وارد Image نشوند.

Artifact نهایی باید حداقل محتوا را داشته باشد.

این اصل فقط برای .git نیست.

موارد زیر نیز معمولاً نباید بدون دلیل وارد Runtime Image شوند:

  • Test Data
  • Development Config
  • Local Cache
  • Backup
  • IDE Files
  • Documentation داخلی
  • Secret Files
  • Repository Metadata

هرچه Image کوچک‌تر و هدفمندتر باشد، Attack Surface نیز بهتر کنترل می‌شود.

جلوگیری در CI/CD

بهترین محل برای جلوگیری از ورود .git به Production معمولاً Deployment Pipeline است.

CI/CD می‌تواند Artifact تمیزی بسازد که تنها شامل Runtime Files باشد.

به این ترتیب Deploy به Server به معنی انتقال Build Artifact است، نه Copy کردن Workspace کامل توسعه.

Pipeline همچنین می‌تواند کنترل‌هایی داشته باشد که در صورت مشاهده موارد زیر Build را Fail کند:

  • .git
  • .env واقعی
  • Private Key
  • Secretهای شناخته‌شده
  • Backupهای ناخواسته
  • Development Artifactها

این نوع کنترل باعث می‌شود اشتباه انسانی قبل از رسیدن به Production متوقف شود.

Secret Scanning چه نقشی دارد؟

حتی اگر .git از اینترنت قابل دسترسی نباشد، Repository همچنان باید از نظر Secret Leakage بررسی شود.

Secret Scanning به دنبال الگوهایی مانند موارد زیر می‌گردد:

  • API Key
  • Access Token
  • Private Key
  • Password
  • Connection String
  • Service Credential

بهتر است این بررسی در چند مرحله انجام شود.

قبل از Commit

Developer باید از وارد کردن Secret واقعی به Source Control خودداری کند.

هنگام Push

Push Protection می‌تواند بعضی Secretها را قبل از ورود به Remote Repository تشخیص دهد.

در CI/CD

Pipeline می‌تواند Repository را Scan کند.

به صورت دوره‌ای

Repositoryهای قدیمی نیز باید بررسی شوند؛ زیرا ممکن است Secretی سال‌ها قبل Commit شده باشد.

.gitignore چه کمکی می‌کند؟

.gitignore ابزار مهمی است، اما نقش آن باید درست فهمیده شود.

می‌توان فایل‌هایی مانند:

.env

را Ignore کرد تا به‌طور ناخواسته وارد Commitهای بعدی نشوند.

اما اگر یک فایل قبلاً Track شده باشد، اضافه کردن نام آن به .gitignore تاریخچه قبلی را پاک نمی‌کند.

همچنین .gitignore هیچ تأثیری روی Web Server ندارد.

وجود این Rule:

.env

به این معنی نیست که Web Server دیگر فایل .env را ارائه نمی‌کند.

Git Ignore و Web Access Control دو مسئله متفاوت هستند. اگر .git قبلاً افشا شده چه کنیم؟

اگر .git قبلاً افشا شده چه کنیم؟

اگر متوجه شدید Repository مدتی از طریق سایت قابل دسترسی بوده است، فقط Rule جدید اضافه نکنید و Incident را تمام‌شده در نظر نگیرید.

ممکن است اطلاعات قبلاً Download شده باشند.

باید Incident Response انجام شود.

مرحله اول: Exposure را فوراً متوقف کنید

اولین کار جلوگیری از دسترسی بیشتر است.

ترجیحاً .git از Document Root خارج شود.

اگر انتقال فوری ممکن نیست، دسترسی Web Server باید فوراً مسدود شود.

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

مرحله دوم: محدوده Exposure را مشخص کنید

مشخص کنید:

  • چه Repositoryای در معرض بوده؟
  • Production بوده یا Staging؟
  • چه مدت Exposure وجود داشته؟
  • چه Hostnameهایی به آن دسترسی داشته‌اند؟
  • آیا CDN در مسیر بوده؟
  • آیا Repository کامل بوده؟
  • آیا Backup دیگری نیز وجود دارد؟

مرحله سوم: Git History را از نظر Secret بررسی کنید

این مرحله بسیار مهم است.

فقط Source فعلی را Scan نکنید.

History باید برای موارد حساس بررسی شود.

تمرکز ویژه روی:

  • Password
  • API Key
  • Token
  • Private Key
  • Cloud Credential
  • Database Connection String
  • SMTP Credential
  • Webhook Secret
  • Deployment Token

باشد.

مرحله چهارم: Secretهای افشاشده را Revoke یا Rotate کنید

اگر Secret واقعی در Repository افشاشده وجود داشته است، فرض امن این است که Secret دیگر قابل اعتماد نیست.

صرفاً حذف مقدار از Git کافی نیست.

Credential باید:

  • Revoke شود، یا
  • Rotate شود و مقدار قبلی از اعتبار خارج شود.

این اصل حتی اگر هیچ نشانه واضحی از سوءاستفاده مشاهده نشده باشد اهمیت دارد.

ندیدن Attack در Log به معنی اثبات ندیدن Secret توسط شخص دیگری نیست.

مرحله پنجم: وابستگی Secret را بررسی کنید

قبل یا هم‌زمان با Rotation مشخص کنید کدام سرویس‌ها از Credential استفاده می‌کنند.

برای نمونه یک Database Password ممکن است در:

  • Web Application
  • Worker
  • Cron Job
  • Backup Service
  • Reporting Service

استفاده شود.

Rotation بدون Dependency Mapping ممکن است باعث Downtime شود.

در محیط‌های حساس بهتر است Secret جدید ایجاد، سرویس‌ها منتقل و سپس Credential قدیمی Revoke شود.

مرحله ششم: Logها را بررسی کنید

Web Access Log، CDN Log، WAF Log و سایر Telemetryها باید برای بازه Exposure بررسی شوند.

هدف این است که بفهمیم آیا درخواست مشکوکی به .git ثبت شده است یا خیر.

باید توجه داشت نبود Log نیز اثبات نمی‌کند هیچ دسترسی انجام نشده؛ Retention محدود، Cache، Proxy یا Logging ناقص می‌توانند Visibility را کاهش دهند.

مرحله هفتم: سیستم‌های مرتبط با Credentialها را Audit کنید

اگر Token یا Password فعال افشا شده است، Log سرویس مقصد نیز باید بررسی شود.

برای مثال اگر Database Credential افشا شده، فقط Web Server Log کافی نیست.

Database Audit نیز اهمیت دارد.

اگر Cloud Credential بوده، Cloud Activity Log باید بررسی شود.

اگر API Key متعلق به سرویس خارجی بوده، Usage History آن سرویس بررسی شود.

مرحله هشتم: Production را از Artifact پاک بازسازی کنید

بعد از رخداد، بهترین کار این است که Deployment تمیز ایجاد شود.

به جای اصلاح دستی ده‌ها فایل روی Server، Build و Artifact شناخته‌شده و کنترل‌شده Deploy شود.

این کار احتمال باقی ماندن نسخه‌های قدیمی، Backup یا Dotfileهای فراموش‌شده را کاهش می‌دهد.

مرحله نهم: Root Cause را پیدا کنید

پرسش مهم این است که چرا .git وارد Web Root شد.

علت ممکن است یکی از این موارد باشد:

  • git clone مستقیم داخل Document Root
  • Copy کامل پروژه
  • Deployment Script اشتباه
  • Docker Build Context نامناسب
  • Backup Restore
  • CI/CD Misconfiguration
  • Shared Hosting
  • Migration اشتباه

بدون اصلاح Root Cause، آسیب‌پذیری ممکن است در Deployment بعدی دوباره ایجاد شود.

آیا پاک کردن .git بعد از Exposure کافی است؟

برای جلوگیری از دسترسی آینده ممکن است کافی باشد، اما برای Incident Response خیر.

اگر Repository قبلاً قابل دسترسی بوده است، باید فرض کنید اطلاعات آن قابلیت Copy شدن داشته‌اند.

در این شرایط باید اثر اطلاعات افشاشده بررسی شود.

به‌خصوص Secretها نیازمند Rotation هستند.

حذف .git از Server نمی‌تواند Credentialی را که فرد دیگری قبلاً ذخیره کرده است بی‌اعتبار کند.

اگر Secret را از Git پاک کنیم، مشکل حل می‌شود؟

نه لزوماً.

این یکی از مهم‌ترین اشتباهات در Git Security است.

فرض کنید API Key در Commit شماره ۱ قرار داشته است.

در Commit شماره ۲ Key را حذف می‌کنید.

در Branch فعلی دیگر Key وجود ندارد.

اما Commit قبلی همچنان ممکن است حاوی آن باشد.

اولین اقدام امنیتی برای Credential افشاشده معمولاً Revoke یا Rotate کردن است.

بعد از آن، در صورت نیاز می‌توان درباره پاک‌سازی History تصمیم گرفت.

بازنویسی Git History چه ملاحظاتی دارد؟

پاک کردن Sensitive Data از تاریخچه Git امکان‌پذیر است، اما موضوع ساده‌ای نیست.

History Rewrite می‌تواند Commit Hashها را تغییر دهد و همکاری توسعه‌دهندگان را پیچیده کند.

همچنین اگر یکی از اعضای تیم Clone قدیمی را دوباره Push کند، داده حساس می‌تواند مجدداً وارد Repository شود.

به همین دلیل ترتیب Incident Response اهمیت دارد:

ابتدا Credential را بی‌اعتبار کنید.

سپس درباره پاک‌سازی History تصمیم بگیرید.

History Cleanup نباید جای Rotation را بگیرد.

آیا WAF می‌تواند جلوی افشای .git را بگیرد؟

WAF می‌تواند یک لایه دفاعی اضافه باشد و درخواست‌های شناخته‌شده به فایل‌های حساس را Block کند.

اما WAF نباید کنترل اصلی باشد.

اگر .git داخل Web Root قرار دارد و Origin Web Server آن را ارائه می‌کند، معماری همچنان ضعیف است.

دفاع بهتر چنین ترتیبی دارد:

Deployment Artifact تمیز → Web Server Rule → Permission مناسب → WAF → Monitoring

نه اینکه Repository در Public Root باقی بماند و فقط WAF از بیرون روی آن قرار گیرد.

آیا Robots.txt برای مخفی کردن .git مناسب است؟

خیر.

robots.txt یک Security Control نیست.

این فایل فقط به Crawlerهای سازگار اعلام می‌کند چه مسیرهایی را Index نکنند.

قرار دادن مسیر حساس در robots.txt نه‌تنها Access را Block نمی‌کند، بلکه می‌تواند وجود آن مسیر را نیز آشکار کند.

برای فایل حساس باید Access Control واقعی وجود داشته باشد.

آیا تغییر نام پوشه .git راهکار امنیتی است؟

خیر.

Security نباید به مخفی ماندن نام Directory وابسته باشد.

ضمن اینکه تغییر ساختار Git ممکن است Workflow پروژه را پیچیده کند.

راهکار اصولی این است که Repository Metadata خارج از Public Web Root باشد.

Git Repository روی Production؛ خوب یا بد؟

وجود Repository روی Production همیشه به خودی خود Vulnerability نیست.

ممکن است Repository در مسیری کاملاً خارج از Web Root قرار داشته باشد و دسترسی سیستم‌عامل نیز محدود باشد.

مسئله اصلی Exposure و ضرورت است.

اگر Git روی Production نیازی ندارد، حذف آن از Runtime Architecture ساده‌تر و امن‌تر است.

اگر برای Deployment Workflow به Repository نیاز دارید، بهتر است Working Directory و Public Document Root از هم جدا باشند.

برای مثال ساختار مفهومی می‌تواند چنین باشد:

deployment-workspace/
    repository-and-build-files/

public-web-root/
    runtime-files-only/

در این مدل Repository Metadata در مسیری نیست که Web Server آن را سرو کند.

اصل Least Privilege در حفاظت از Repository

Repository نیز باید مانند هر Asset حساس دیگری براساس Least Privilege مدیریت شود.

همه کاربران Server لازم نیست Repository Production را بخوانند.

همه CI Jobها نباید Secretهای Production داشته باشند.

همه Branchها نباید امکان Deployment داشته باشند.

همه Developerها نیز الزاماً نیازمند دسترسی مستقیم Production نیستند.

کاهش Permission می‌تواند Blast Radius یک Credential Leak را کاهش دهد.

تفکیک Development، Staging و Production

استفاده از Credentialهای یکسان بین محیط‌ها یک Anti-pattern مهم است.

اگر Repository Development افشا شود و همان Database Password در Production نیز استفاده شده باشد، جداسازی محیط‌ها عملاً از بین رفته است.

هر Environment باید تا حد ممکن Identity و Credential مستقل داشته باشد.

برای مثال:

Development Database User

Staging Database User

Production Database User

و همین اصل برای:

API Key

Cloud Account

Storage Credential

SMTP Credential

Deploy Token

نیز صدق می‌کند.

فایل .env و افشای .git

.env و .git دو مسئله جدا اما مرتبط‌اند.

ممکن است .env اکنون به‌درستی داخل .gitignore باشد.

اما اگر قبل از اضافه شدن Rule یک بار Commit شده باشد، نسخه قدیمی آن ممکن است در History وجود داشته باشد.

به همین دلیل هنگام بررسی Repository Exposure باید سؤال کنیم:

آیا فایل حساس در هر زمانی از عمر Repository Commit شده است؟

نه فقط اینکه اکنون Track می‌شود یا خیر.

نقش Code Review

Code Review فقط برای پیدا کردن Bug نیست.

Reviewer باید به ورود اطلاعات حساس نیز توجه کند.

نشانه‌های مهم شامل:

  • Token طولانی
  • Password Hardcoded
  • Connection String
  • Private Key
  • URL دارای Credential
  • Secret داخل Test Fixture
  • Configuration Production

است.

البته تشخیص انسانی کافی نیست و باید با Secret Scanner تکمیل شود.

Pre-commit و Push Protection

یکی از مؤثرترین راه‌ها جلوگیری از Secret Leakage این است که Credential قبل از ورود به Repository متوقف شود.

کنترل می‌تواند در چند لایه اجرا شود:

Developer Workstation

Pre-commit

Pre-push

Git Hosting

CI/CD

هرچه Detection زودتر باشد، Remediation ساده‌تر خواهد بود.

Secretی که هنوز وارد Shared Repository نشده، معمولاً دردسر بسیار کمتری نسبت به Credentialی ایجاد می‌کند که در ده‌ها Clone و Backup تکثیر شده است.

Monitoring برای درخواست‌های فایل‌های حساس

Web Server Monitoring می‌تواند درخواست به مسیرهای غیرعادی را شناسایی کند.

برای مثال درخواست‌های مکرر به:

  • Dotfileها
  • Backupها
  • Configurationها
  • Repository Metadata

می‌توانند نشانه Reconnaissance باشند.

اما Alert نباید جای Prevention را بگیرد.

هدف اصلی این است که فایل اصلاً قابل دریافت نباشد.

Monitoring فقط کمک می‌کند تلاش‌ها را ببینیم.

خطاهای رایج در جلوگیری از افشای پوشه .git

اشتباه اول: فقط خاموش کردن Directory Listing

Listing با Access Control متفاوت است.

فایل شناخته‌شده ممکن است همچنان در دسترس باشد.

اشتباه دوم: اعتماد به مخفی بودن Dotfile

Hidden بودن در Linux مانع HTTP Access نمی‌شود.

اشتباه سوم: استفاده از robots.txt

Crawler Directive مکانیزم امنیتی نیست.

اشتباه چهارم: نگهداری .git در Web Root و اعتماد کامل به WAF

Repository حساس همچنان در محل اشتباه قرار دارد.

اشتباه پنجم: حذف API Key از Commit جدید و تمام‌شده دانستن Incident

Secret ممکن است در History باقی مانده باشد و باید Rotate یا Revoke شود.

اشتباه ششم: بررسی نکردن Staging و Subdomainها

بسیاری از Exposureها روی محیط‌های فراموش‌شده اتفاق می‌افتند.

اشتباه هفتم: استفاده از Credential یکسان در تمام Environmentها

این کار Blast Radius را افزایش می‌دهد.

اشتباه هشتم: Deploy کردن کل Workspace

Production به فایل‌های Development و Repository Metadata نیاز ندارد.

اشتباه نهم: نداشتن Secret Scanning

یک Secret ممکن است ماه‌ها داخل History باقی بماند بدون اینکه تیم متوجه شود.

اشتباه دهم: فرض اینکه Repository خصوصی همیشه امن است

حتی Repository Private نیز نباید محل Hardcode کردن Credential باشد.

چک‌لیست جلوگیری از نشت سورس کد از طریق .git

برای ارزیابی اولیه می‌توانید این موارد را بررسی کنید:

  • پوشه .git داخل Document Root نباشد.
  • Deployment Artifact فقط Runtime Fileها را شامل شود.
  • درخواست HTTP به .git پاسخ حاوی Repository Data ندهد.
  • Apache یا Nginx Rule صریح برای جلوگیری از دسترسی داشته باشد.
  • تمام Virtual Hostها بررسی شوند.
  • Subdomainهای قدیمی بررسی شوند.
  • Staging و Development عمومی بررسی شوند.
  • CDN Configuration بررسی شود.
  • Docker Image شامل .git نباشد.
  • Build Context محدود باشد.
  • CI/CD از Artifact تمیز استفاده کند.
  • .env و Secret Fileها Commit نشوند.
  • Repository با Secret Scanner بررسی شود.
  • Git History نیز Scan شود.
  • Credentialهای Production با Development متفاوت باشند.
  • API Keyها براساس Least Privilege صادر شوند.
  • Secretهای افشاشده Rotate یا Revoke شوند.
  • Web Server Log برای درخواست‌های مشکوک Monitoring شود.
  • Backupهای سایت عمومی نباشند.
  • فایل‌های قدیمی و Deploymentهای قبلی پاک‌سازی شوند.
  • Permissionهای Server حداقلی باشند.
  • Root Cause هر Exposure مستند و اصلاح شود.

رویکرد امن برای Deployment سایت

یک Deployment Pipeline حرفه‌ای بهتر است تقریباً این مدل را دنبال کند:

مرحله ۱: دریافت Source در محیط Build

Repository داخل Build Environment یا Workspace غیرعمومی قرار می‌گیرد.

مرحله ۲: بررسی Security

Dependency Scan، Secret Scan و کنترل‌های لازم اجرا می‌شوند.

مرحله ۳: Build

فقط فایل‌های مورد نیاز Runtime ساخته می‌شوند.

مرحله ۴: Artifact

Artifact نهایی بدون Repository Metadata و Development Fileها ایجاد می‌شود.

مرحله ۵: Deploy

Artifact به Production منتقل می‌شود.

مرحله ۶: Verification

پس از Deploy بررسی می‌شود فایل حساس، Dotfile یا Repository Metadata منتشر نشده باشد.

این معماری علاوه بر امنیت، Deployment را قابل تکرارتر و قابل Audit می‌کند. دفاع چندلایه برای جلوگیری از Source Code Disclosure

دفاع چندلایه برای جلوگیری از Source Code Disclosure

برای جلوگیری از افشای .git نباید به یک کنترل وابسته بود.

مدل بهتر چندلایه است.

لایه اول: طراحی Deployment

.git وارد Web Root نشود.

لایه دوم: Web Server

دسترسی به Repository Metadata و فایل‌های حساس Block شود.

لایه سوم: File System

Permission براساس Least Privilege باشد.

لایه چهارم: CI/CD

Artifact بررسی شود و Secretها Scan شوند.

لایه پنجم: WAF

درخواست‌های شناخته‌شده و Reconnaissance محدود شوند.

لایه ششم: Monitoring

Requestهای مشکوک و Access Anomaly شناسایی شوند.

لایه هفتم: Incident Response

برای Credential Leakage برنامه آماده وجود داشته باشد.

این همان مفهوم Defense in Depth است.

سؤالات متداول درباره افشای پوشه .git

افشای پوشه .git چیست؟

افشای پوشه .git زمانی رخ می‌دهد که اطلاعات داخلی Repository Git از طریق Web Server برای کاربران اینترنت قابل دسترسی شوند. این اطلاعات ممکن است Metadata، تاریخچه Commit، نام فایل‌ها و در بعضی شرایط داده کافی برای افشای بخش زیادی از Source Code را در بر بگیرند.

آیا وجود .git روی سرور به تنهایی آسیب‌پذیری است؟

خیر. اگر .git خارج از Document Root باشد و کاربران غیرمجاز نتوانند به آن دسترسی داشته باشند، وجود آن الزاماً Vulnerability نیست. مشکل اصلی زمانی است که Repository از طریق وب یا Permission نامناسب قابل دسترسی شود.

چرا افشای .git از افشای یک فایل معمولی خطرناک‌تر است؟

چون Git فقط نسخه فعلی فایل‌ها را مدیریت نمی‌کند و دارای تاریخچه است. اطلاعات حذف‌شده یا تغییرکرده ممکن است در Commitهای قبلی باقی مانده باشند.

آیا خاموش بودن Directory Listing کافی است؟

خیر. خاموش بودن Listing فقط مانع نمایش خودکار لیست فایل‌ها می‌شود و لزوماً مانع دسترسی مستقیم به فایل مشخص نیست.

آیا .gitignore جلوی افشای .git را می‌گیرد؟

خیر. .gitignore رفتار Git را هنگام Tracking فایل‌ها کنترل می‌کند و Security Rule وب‌سرور نیست.

اگر .env در .gitignore باشد، دیگر خطری وجود ندارد؟

نه لزوماً. اگر .env قبلاً Commit شده باشد، ممکن است نسخه آن در Git History باقی مانده باشد.

اگر API Key را از Repository حذف کنیم کافی است؟

اگر API Key افشا شده باشد، خیر. Credential باید Rotate یا Revoke شود. حذف آن از Source Code نمی‌تواند نسخه‌ای را که قبلاً Copy شده بی‌اعتبار کند.

آیا باید Git History را پاک کنیم؟

این تصمیم به نوع داده و نیازهای امنیتی یا Compliance بستگی دارد. برای Secret واقعی، اولین اقدام باید Revoke یا Rotation باشد. History Rewrite مرحله جداگانه‌ای است و می‌تواند روی Cloneها و Commit Hashها اثر بگذارد.

آیا WAF برای جلوگیری از افشای Git کافی است؟

خیر. WAF یک لایه دفاعی است. بهتر است Repository اصلاً در Document Root نباشد و Web Server نیز Access را مستقیماً مسدود کند.

Apache برای .git چه کاری باید انجام دهد؟

بهترین روش حذف .git از Public Root است. در صورت وجود، Apache باید با Access Control مناسب دسترسی HTTP به آن را Deny کند.

در Nginx چطور؟

Nginx نیز باید Location مربوط به .git را Block کند و Artifact Production ترجیحاً اصلاً Repository Metadata نداشته باشد.

آیا افشای سورس کد به معنی هک شدن قطعی سایت است؟

خیر. Source Code Disclosure الزاماً به معنی دسترسی اجرایی نیست، اما اطلاعات ارزشمندی به فرد غیرمجاز می‌دهد و اگر Secret یا Vulnerability در کد وجود داشته باشد، ریسک می‌تواند بسیار افزایش پیدا کند.

افشای .git برای WordPress هم خطرناک است؟

بله، مخصوصاً اگر Repository شامل Plugin اختصاصی، Theme اختصاصی، Configuration، Credential یا نسخه تاریخی فایل‌های حساس باشد.

چگونه متوجه شویم قبلاً کسی به .git دسترسی داشته است؟

Web Server Log، CDN Log، WAF Log و سایر Telemetryها باید بررسی شوند. بااین‌حال نبود Request مشکوک در Log اثبات نمی‌کند هیچ دسترسی انجام نشده است.

اگر .git مدتی Public بوده چه اقدامی مهم‌تر است؟

پس از مسدود کردن Exposure، Repository و History باید از نظر Credential بررسی شوند و هر Secret معتبر افشاشده فوراً Rotate یا Revoke شود. سپس Scope رخداد و Logها ارزیابی شوند.

جمع‌بندی

افشای پوشه .git یک خطای ساده در ظاهر است که می‌تواند پیامدهایی بسیار فراتر از نمایش یک Directory مخفی داشته باشد.

Repository Git می‌تواند اطلاعاتی درباره Source Code، ساختار پروژه، نام فایل‌ها، Branchها و تاریخچه تغییرات داشته باشد. از آن مهم‌تر، Git History ممکن است داده‌هایی را نگهداری کند که مدت‌ها قبل از نسخه فعلی برنامه حذف شده‌اند.

به همین دلیل یک Secret پاک‌شده از Source فعلی لزوماً از Repository حذف نشده است.

API Key، Access Token، Database Password، Cloud Credential یا Private Key قدیمی می‌تواند Incident را از Information Disclosure به Credential Compromise تبدیل کند.

اصولی‌ترین راه جلوگیری از این مشکل آن است که Repository Metadata هرگز وارد Public Document Root نشود.

Production باید از Artifact تمیز و حداقلی استفاده کند؛ Artifactی که فقط فایل‌های مورد نیاز Runtime را در خود دارد.

Apache، Nginx، Reverse Proxy و WAF نیز باید به‌عنوان لایه‌های تکمیلی دسترسی به .git و سایر فایل‌های حساس را مسدود کنند.

CI/CD باید مانع انتقال .git، .env و Development Artifactهای غیرضروری شود و Secret Scanning نیز Repository و History را تحت پوشش قرار دهد.

اگر Repository قبلاً افشا شده است، صرفاً حذف .git یا تغییر Configuration کافی نیست.

باید بررسی شود چه داده‌هایی قابل دسترسی بوده‌اند، آیا Secret فعال در History وجود داشته است، چه Credentialهایی نیاز به Rotation یا Revocation دارند و Logهای سیستم چه نشانه‌هایی از دسترسی احتمالی نشان می‌دهند.

در نهایت، امنیت صحیح Git در Production با «مخفی کردن پوشه» به دست نمی‌آید.

راهکار واقعی ترکیبی از Deployment امن، جداسازی Repository از Web Root، Least Privilege، Secret Management، Web Server Hardening، Monitoring و Incident Response است.

وقتی این کنترل‌ها از ابتدا در معماری Deployment قرار بگیرند، یک اشتباه ساده در Copy کردن فایل‌ها نمی‌تواند به نشت کامل سورس کد و اطلاعات حساس سایت تبدیل شود.

مطالب مرتبط