۵۴۳٬۶۹۹ اعتبارنامه زنده در مخزنهای عمومی GitHub؛ مسئله ابطال است
Truffle Security در ۲۲۴ میلیون مخزن عمومی، ۵۴۳٬۶۹۹ اعتبارنامه زنده یافت. GitHub هک نشده است؛ افشای اعتبارنامه در GitHub تا ابطال ارائهدهنده زنده میماند.

فهرست مطالب
افشای اعتبارنامه در GitHub مسئله تازهای نیست، اما مقیاس آن تازه اندازهگیری شده است. شرکت امنیتی Truffle Security در گزارش ۷ مهر (۲۹ سپتامبر) خود، ۲۲۴٬۵۵۳٬۲۹۵ مخزن عمومی را گشت و ۵۴۳٬۶۹۹ اعتبارنامه (credential) یافت که هنگام آزمایش در برابر سرویس صادرکننده همچنان معتبر بودند. یافته مهم اما عدد تیتر نیست: راز لو رفته تنها وقتی میمیرد که ارائهدهنده خودکار ابطالش کند، نه وقتی GitHub جلوی پوش را بگیرد.
هیچ نفوذی به GitHub رخ نداده است؛ این رازها را خود توسعهدهندهها در کد عمومی کامیت کردهاند.
چرا افشای اعتبارنامه در GitHub زنده میماند؟
قویترین شاهد گزارش، نرخ بقا (survival rate) به تفکیک ارائهدهنده است.
| ارائهدهنده | افشاشده | همچنان معتبر | نرخ بقا |
|---|---|---|---|
| رشته اتصال Postgres | ۱۲٬۹۸۵ | ۱۱٬۴۶۵ | ۸۸٪ |
| رشته اتصال MySQL | ۲٬۴۲۱ | ۱٬۸۰۶ | ۷۵٪ |
| حساب سرویس Google Cloud | ۱۲۶٬۹۶۳ | ۶۹٬۰۴۱ | ۵۴٪ |
| کلید SendGrid | ۲۲٬۸۰۰ | ۹٬۱۸۹ | ۴۰٪ |
| کلید دسترسی AWS | ۸۲٬۴۱۱ | ۶٬۸۱۹ | ۸٪ |
| توکن Slack | ۸٬۹۰۳ | ۱۹۸ | ۲٪ |
| توکن شخصی GitLab | ۳٬۷۷۸ | ۲۴ | ۰٫۶۴٪ |
| توکن GitHub | ۷۳٬۰۴۸ | ۲۶۰ | ۰٫۳۶٪ |
| توکن Hugging Face | ۳۰٬۴۳۷ | ۱۵ | ۰٫۰۵٪ |
| توکن npm | ۱۰۱٬۸۸۶ | ۱ | ۰٫۰۰۱٪ |
دو سر جدول کل استدلالاند: از ۱۰۱٬۸۸۶ توکن npm فقط یک مورد زنده مانده، اما از ۱۲٬۹۸۵ رشته اتصال (connection string) Postgres، ۱۱٬۴۶۵ مورد. در تحلیل گزارش، آنچه این شکاف را میسازد ابطال است، نه بلاک شدن در لحظه پوش.
مستندات GitHub همین تقسیم کار را تأیید میکند: وقتی راز یک ارائهدهنده شریک تشخیص داده شود، GitHub به همان ارائهدهنده خبر میدهد تا «اقدام کند، مثلاً اعتبارنامه را ابطال کند». خود GitHub کلید را نمیبندد؛ پس ارائهدهندهای که در این برنامه نباشد، کلیدش زنده میماند.
این عدد چقدر وزن دارد؟
گزارش درباره محدودیتهای روش خود صریح است:
- پیکره، مجموعهداده عمومی The Stack v3 است که برای آموزش مدلهای هوش مصنوعی گردآوری شد. خزش آن ۷ اوت ۲۰۲۵ بسته شد و تحلیل ۲۷ و ۲۸ ژوئیه ۲۰۲۶ اجرا شد؛ پس اینها افشاهای تازه نیستند.
- تنها شاخههای پیشفرض (default branch) بررسی شدهاند، بدون دید به تاریخچه کامیت، و تاریخ لو رفتن از زمان تغییر فایل استنتاج شده است؛ پس ۵۴۳٬۶۹۹ کف برآورد است، نه سقف.
- کلیدهای خصوصی از نرخ بقا بیرون ماندهاند، چون بدون دسترسی به میزبان آزمایشپذیر نیستند؛ آدرسهای MongoDB هم حذف شدهاند، چون آشکارساز فقط اتصال موفق را گزارش میکند و نرخ بقا برایشان بیمعنا میشود.
عمر این رازها کوتاه نیست: میانه ۷۸۴ روز، صدک نودم ۶٫۳ سال و قدیمیترین کلید معتبر از ۱۳ ژوئن ۲۰۰۹، یعنی ۱۶٫۱ سال.
محافظت از پوش کار میکند، اما نیمی از ماجرا را نمیبیند
به اعلام GitHub، هشدارهای اسکن اسرار (secret scanning) در ۲۸ فوریه ۲۰۲۳ و محافظت از پوش (push protection) در ۹ مه ۲۰۲۳ برای مخزنهای عمومی رایگان شدند. در ۲۹ فوریه ۲۰۲۴ هم GitHub فعالسازی آن را روی همه حسابهای کاربری رایگان آغاز کرد تا کاربر را «بهطور خودکار از کامیت تصادفی راز در مخزنهای عمومی محافظت کند، فارغ از آنکه خود مخزن اسکن اسرار را فعال کرده باشد یا نه».
اثرش قابل اندازهگیری است: در دوازده ماه پیش و پس از اجرا، نرخ افشای انواع تحت پوشش ۵۳ درصد افت کرد و انواع بیپوشش فقط ۷ درصد؛ گزارش همین ۵۳ درصد را یک کف میداند.
مشکل جای دیگری است: ۵۱٫۸ درصد رازهای زنده این پیکره شکلی دارند که محافظت پیشفرض مخزنهای عمومی جلویشان را نمیگیرد — رشتههای اتصال پایگاه داده، کلیدهای API Google و کلیدهای خصوصی. Truffle از ۳٬۲۸۹٬۲۲۶ کلید API Google فقط Gemini را راستیآزمایی کرد و ۳۱٬۳۷۴ کلید زنده یافت. گزارش دلیلش را میگوید: «کلید Gemini یک اعتبارنامه هزینهدار است که به یک نقطه پایانی مدل وصل شده؛ کلید Maps با همان پیشوند AIzaSy ساخته شده تا در صفحه وب منتشر شود.»
چگالی افشا هم بالا میرود: از ۳٫۷۲ اعتبارنامه در هر میلیون فایل در ۲۰۱۴ به ۱۱٫۶۲ در هفت ماه نخست ۲۰۲۵. بلاک، در قاب گزارش، دمِ در کار میکند و «درباره آن ۵۴۳٬۶۹۹ موردی که از قبل داخلاند حرفی برای گفتن ندارد».
امروز چه کنید
توصیههای Truffle Security:
- هر اعتبارنامهای را که کامیت شده سوخته بدانید، چه علامت خورده باشد چه نه. اول بچرخانید (rotate)، بعد تاریخچه را تمیز کنید.
- مخزنهای قدیمی را اسکن کنید. محافظت پیشفرض بر کد منتشرشده پیش از فوریه ۲۰۲۴ اثری ندارد.
- اعتبارنامههای دارای انقضا را ترجیح دهید و برای رازهای فعال انقضای خودکار بگذارید.
- بررسی کنید ارائهدهنده شما در برنامه ابطال مشارکت میکند یا نه. همین بند تفاوت میان ۰٫۰۰۱ و ۸۸ درصد است.
سادهترین کار اما این است که راز هرگز وارد مخزن نشود: مقدارها را از متغیر محیطی بخوانید و در Secrets سامانه CI نگه دارید؛ الگویش در آموزش CI/CD با GitHub Actions آمده است. قدم صفرش یک .gitignore درست است که .env را بیرون مخزن نگه دارد؛ آموزش Git و GitHub نمونهاش را دارد. اسکن اسرار هم یکی از کنترلهای پایه در راهنمای OWASP Top 10 نسخه ۲۰۲۵ است.




دیدگاهها
دیدگاهها پس از بررسی تحریریه منتشر میشوند. توهین، تبلیغ و لینکهای بیربط حذف میشوند؛ نقد فنی و مستند همیشه خوشآمد است.
هنوز کسی چیزی ننوشته. اولین دیدگاه را شما ثبت کنید.