اگر امروز از ZCode برای کدنویسی استفاده میکنید، احتمالاً تمام اسرار تجاری و تاریخچه تغییرات پروژههایتان در سرورهای یک شرکت چینی ذخیره شده است. این ابزار برخلاف ادعای خود، تنها تکههایی از کد را برای استنتاج نمیفرستد، بلکه کل فضای کاری شما را میبلعد.
به گزارش تحقیقی که در ۱۸ سپتامبر ۲۰۲۶ منتشر شد، اپلیکیشن ZCode محصول شرکت Zhipu AI، بهطور مخفیانه کل محیطهای کاری محلی را به ابر منتقل میکند. این برنامه نهتنها قطعات کد فعال، بلکه کل تاریخچه .git، حافظه نهان LFS و تنظیمات داخلی را در قالب آرشیوهای رمزنگاریشده ارسال میکند.
این اتفاق در حالی رخ میدهد که توسعهدهندگان بهطور فزایندهای از عاملهای هوش مصنوعی (AI Agents) — شبیه به دستیارهای هوشمندی که میتوانند بهجای شما ابزارها را اجرا کنند — در محیط IDE خود استفاده میکنند و تصور میکنند تنها دادههای مرتبط با تسک جاری به اشتراک گذاشته میشود. در حالی که اکثر ابزارها تنها فایلهای خاصی را برای استنتاج (Inference) — یعنی همان لحظهای که مدل واقعاً جواب تولید میکند، شبیه به خودِ آشپزی و نه دوره آموزش آشپز — ارسال میکنند، رفتار ZCode یک تغییر خطرناک به سمت آینهسازی کامل مخزن (Repository) بدون رضایت کاربر است. این موضوع برای پروژههای تجاری که پوشه .git آنها حاوی سالها مالکیت معنوی و رمزهای حذفشده است، بحرانی است. این آسیبپذیری در مدیریت مخازن، یادآور حفره امنیتی Claude Code در مخازن Git است که پیشتر نشان داد چگونه دسترسی به Git میتواند ریسکهای امنیتی جدی ایجاد کند.
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، اعتماد کورکورانه به ابزارهای متصل به ابر میتواند منجر به نشتهای ساختاری شود.
نقطه شروع: یک آرشیو ۳۱۳ مگابایتی
این بررسی زمانی آغاز شد که یک کاربر در حین پاکسازی روتین فضای دیسک، متوجه شد دایرکتوری ~/.zcode بیش از ۷۰۰ مگابایت فضا اشغال کرده است. بررسی دقیق ریشه دادهها نشان داد که این فضا به سه بخش اصلی تقسیم شده است: پوشه cli/ با حجم حدود ۲۵۷ مگابایت که حاوی پایگاه دادههای نشست (Session) و لاگهای اجرا است، پوشه computer-use/ با حجم حدود ۱۳۰ مگابایت برای وابستگیهای باندل شده برنامه، و پوشه v2/checkpoints/ با حجم حدود ۳۰۳ مگابایت که مشکوکترین بخش بود.
در این پوشه، یک فایل .enc به حجم ۳۱۳ مگابایت یافت شد که همراه با یک فایل متادیتای وضعیت (State Metadata) بود. این متاداتا صراحتاً این آرشیو را به مسیر یک پروژه تجاری مرتبط میکرد و ثبت کرده بود که اندازه اصلی فضای کاری ۳۴۵,۵۴۹,۱۷۳ بایت بوده که به حجم رمزنگاریشده ۳۱۳,۰۷۰,۸۴۲ بایت فشرده شده است. این فایل با برچسب «baseline» (اسنپشات کامل) مشخص شده بود. نکته قابل توجه این است که متاداتا ۵۶۴ تلاش ناموفق برای آپلود را ثبت کرده بود؛ این یعنی آرشیو در یک دایرکتوری محلی در وضعیت «در انتظار» (Pending) مانده بود تا در اولین فرصت دوباره برای ارسال تلاش کند.
سازوکار استخراج دادهها
طبق گزارش وبسایت blog.ferstar.org، فرآیند با شناسایی یک فضای کاری فعال شروع میشود. برنامه پروژه را اسکن کرده، پوشههایی مثل node_modules و چند دایرکتوری دیگر را استثنا میکند و یک آرشیو فشرده میسازد. این آرشیو سپس بهصورت محلی با استفاده از الگوریتم AES-256-CTR رمزنگاری میشود.
برای درک اینکه دادهها به کجا میروند، محقق فایل app.asar کلاینت را مهندسی معکوس کرد. خط لوله آپلود در دو مرحله مجزا عمل میکند:
۱. درخواست اعتبارنامه: کلاینت به آدرس https://zcode.z.ai متصل میشود (که در کد با نام VITE_ZCODE_ENDPOINT_ORIGIN شناسایی شده است). سرور در پاسخ، امضاهای فرم OSS (شامل policy و x-oss-signature)، یک کلید شیء (Object Key) پویا، محدودیتهای اندازه و کلید عمومی RSA برای آن دور رمزنگاری خاص را ارسال میکند.
۲. آپلود مستقیم: کلاینت پس از رمزنگاری استریمشده محلی، سرورهای اپلیکیشن Zhipu را دور میزند و فایل tar.gz.enc را مستقیماً از طریق یک فرم HTTP POST به گرههای ذخیرهسازی Aliyun OSS ارسال میکند. سپس Aliyun OSS یک بازگشت (Callback) به بکاند Zhipu میفرستد تا اسنپشات ثبت شود.
بررسی سوکتهای فعال، این جریان را تأیید کرد و اتصالات HTTPS مداوم به نقاط انتهایی IP مربوط به zcode.z.ai و دو گره ذخیرهسازی Aliyun OSS را نشان داد.
قفل رمزنگاری در سمت سرور
نکته تکاندهنده این است که پیادهسازی رمزنگاری از مدل استاندارد «رمزنگاری پاکت» (Envelope Encryption) استفاده میکند. سیستم از rsa-oaep-sha256 به عنوان keyWrapAlgorithm و یک publicKeySpkiPem که توسط سرور ارائه شده است، استفاده میکند. محتوا با یک کلید متقارن موقت (Ephemeral) از طریق AES-256-CTR رمز میشود و سپس آن کلید متقارن، با استفاده از کلید عمومی RSA سرور «بسته» یا Wrap میشود.
چون کلید خصوصی متناظر تنها در بکاند Zhipu AI وجود دارد و هرگز به دستگاه کاربر نمیرسد، کاربر حتی نمیتواند متن رمزنگاریشدهای را که روی دیسک خودش قرار دارد رمزگشایی کند. تلاشها برای باز کردن کلید پاکت با استفاده از تمام کلیدهای خصوصی محلی موجود در سیستم با شکست مواجه شد. این انتخاب معماری یک زنگ خطر جدی است؛ اگر این قابلیت برای بازگشت به نسخههای قبلی (Rollback) یا همگامسازی بین دستگاهها برای کاربر طراحی شده بود، کلیدها باید بهصورت محلی ذخیره میشدند (شبیه به Git یا Time Machine). کلیدی که منحصراً در اختیار سرور است، تضمین میکند که تنها سرور میتواند کدها را بخواند. جزئیات فنیتر این سازوکار رمزنگاری دادهها با کلید اختصاصی Z.ai نشان میدهد که کنترل کامل دادهها بهطور مطلق در دست شرکت توسعهدهنده است.
چه دادههایی دزدیده میشوند؟
تحلیل لیست فایلهای متنی (Manifest) که در حین بستهبندی تولید شده، نشان داد که بخش اعظم دادههای آپلود شده، کد منبع فعلی نیست، بلکه تبار و تاریخچه مخزن است. در یک اسنپشات تست شده با ۴۲,۴۱۱ فایل، توزیع دادهها به شرح زیر بود:
- .git/lfs/: حدود ۱۹۶.۱ مگابایت (۵۶.۸٪) شامل تمام داراییهای باینری و رسانههای حجیمی که تا به حال دانلود شدهاند.
- .git/objects/: حدود ۱۰۲.۲ مگابایت (۲۹.۶٪) شامل ذخیرهگاه کامل اشیاء تاریخچه کامیتها (commits, trees, blobs).
- .git/logs/: حدود ۰.۶ مگابایت (۰.۲٪) شامل reflogها، تاریخچه شاخههای محلی و ردپاهای عملیاتی ارسال نشده.
- کد منبع و مستندات: ۴۶.۲ مگابایت (۱۳.۴٪) شامل فایلهای واقعی
src/و فایلهای تنظیمات.
در این مثال، پوشه .git به تنهایی ۸۶.۶٪ حجم ارسالی را تشکیل میداد. این یعنی هر کلید API که زمانی کامیت و سپس حذف شده، یا نام شاخههای محلی که نقشه راه آینده محصول را لو میدهد، و حتی نام میزبانهای داخلی GitLab و مسیرهای مخزن که در .git/config تنظیم شدهاند، مستقیماً به سرورها میروند. علاوه بر این، یک فایل به نام repo_snapshot_extra_manifest هشهای فایلهای تنظیمات جهانی ZCode (مانند settings.behavior.json) را گرفته و آنها را در هر اسنپشات همراه با فضای کاری باندل میکند.
توهم کنترل
تنظیمات رابط کاربری ZCode عملاً فریبدهنده هستند. بررسی متقاطع گزینههای UI با کد منبع، موارد زیر را آشکار کرد:
- بهینهسازی تجربه (Optimize Experience -
optimizeAgentExperienceEnabled): کاربران انتظار دارند این گزینه تلهمتری را غیرفعال کند. در واقعیت، این گزینه فقط کنترل میکند که آیا دادهها برای آموزش مدل مجاز هستند یا خیر. ثبت و آپلود اسنپشاتها همچنان بدون وقفه ادامه مییابد. - اندکسگذاری اسنپشات (Repo Snapshot Indexing -
repoSnapshotIndexingEnabled): کاربران تصور میکنند این گزینه قابلیت اسنپشات را غیرفعال میکند. در واقعیت، این گزینه فقط کنترل میکند که آیا سرور اسنپشاتهای آپلود شده را اندکس (فهرست) کند یا خیر. بستهبندی محلی و آپلود بدون تغییر ادامه مییابد.
تحلیل کد اسمبلی میزبان نشان میدهد که Sidecar مربوط به کپچر و آپلود، در لحظه شروع برنامه بدون هیچ شرطی نمونهسازی (Instantiate) میشود. هیچ بررسی یا گیتکیپی بر اساس ترجیحات کاربر وجود ندارد؛ تنها پیشنیاز، یک JWT معتبر از tokenProvider است. عملیات کپچر قبل از هر پرامپت (captureBeforePrompt) و پس از اتمام تسکهایی که با تگ repo-wiki-update علامتگذاری شدهاند، رخ میدهد. در یک جلسه ضبط شده، برنامه ۶۲ رویداد کپچر مجزا ایجاد کرد.
تناقض در سیاست حریم خصوصی
سیاست حریم خصوصی ZCode میگوید تنها «متون، فایلها و کدهایی که در طول گفتگوها ارسال میشوند» جمعآوری میگردند، که برای کانتکست مدلهای زبانی (LLM) استاندارد است. با این حال، هیچ اشارهای به بستهبندی مخفیانه کل فضای کاری یا تاریخچه کامل Git نشده است. تنها اشاره مرتبط، یک قالب کلی است که میگوید «برنامه بهینهسازی بهطور پیشفرض خاموش است و ورودیها بدون رضایت برای آموزش استفاده نخواهند شد». سیاستها، FAQها و یادداشتهای تغییرات (Changelogs) بهطور کامل درباره خط لوله اسنپشات پسزمینه سکوت کردهاند. این رویکرد در تضاد کامل با استانداردهای جدیدی است که برخی شرکتها اتخاذ کردهاند؛ برای مثال OpenAI با سیستم پردازش ایمنی خصوصی تلاش کرده است تا ذخیرهسازی دادههای مشتریان را به حداقل برساند.
راهکار مقابله
حذف دستی فایلها بیفایده است چون برنامه بهطور خودکار دادهها را دوباره بستهبندی میکند و شمارنده تلاشها را افزایش میدهد (مثلاً از ۵۶۴ به ۵۶۵). تنها راه دفاع دائمی، قفل کردن دایرکتوری در سطح هسته (Kernel) برای رد کردن دسترسی نوشتن است.
برای کاربران macOS:
rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
chflags uchg ~/.zcode/v2/checkpoints
برای کاربران لینوکس:
rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
sudo chattr +i ~/.zcode/v2/checkpoints
این کار باعث میشود برنامه نتواند آرشیو بسازد و در نتیجه آپلود متوقف شود. اگرچه این اقدام قابلیت UI مربوط به «بازگشت به چکپوینت / تایملاین» را غیرفعال میکند، اما چت معمولی، تکمیل خودکار کد و اجرای ابزارها همچنان بدون مشکل کار میکنند. برای بازگرداندن دسترسی، کاربران میتوانند دستورات chflags nouchg (در macOS) یا sudo chattr -i (در لینوکس) را اجرا کنند.
این انتخاب معماری — جایی که سرور تنها کلید رمزگشایی را در اختیار دارد — نشان میدهد که این قابلیت برای جمعآوری متمرکز دادهها طراحی شده است، نه برای پشتیبانگیری کاربر. برای توسعهدهندگان، این یک یادآوری تلخ است که ابزارهای «قدرت گرفته از AI» اغلب با مجوزهایی عمل میکنند که بسیار فراتر از نیازهای تسک محول شده به آنهاست. وقتی نرمافزاری راهی برای انصراف (Opt-out) از استخراج دادهها ارائه نمیدهد، تنها مرز باقیمانده، لایه امنیتی خودِ سیستمعامل است.
کاربران باید همین حالا دایرکتوریهای ~/.zcode محلی خود را بررسی کنند تا ببینند آیا فایلهای حجیم .enc در انتظار آپلود به سرورهای Aliyun هستند یا خیر.
گام بعدی شما
- فوراً دایرکتوری
~/.zcodeرا در سیستم خود بررسی کنید تا ببینید آیا فایلهای حجیم.encدر انتظار آپلود هستند یا خیر. - اگر از ZCode استفاده میکنید، دستورات محدودسازی دسترسی (Lock) ذکر شده در بالا را اجرا کنید.
- در تمامی ابزارهای AI-powered، به جای تکیه بر تنظیمات UI، از ابزارهای مانیتورینگ شبکه برای بررسی مقصد دادهها استفاده کنید.
اما داستان خطرناکتر، نفوذ این ابزارها به زنجیره تأمین نرمافزار است — به تحلیل ما دربارهی امنیت عاملهای هوشمند در محیطهای سازمانی مراجعه کنید.




گفتگو