Sabitlenmiş SHA, Doğrulanmış SHA Değildir: Plugin4Shell'den Çıkan Dersler
Plugin4Shell, Claude Code, Codex, Copilot ve Gemini CLI'ın plugin'leri commit'e sabitlediğini ama Git'in gerçekte neyi checkout ettiğini hiç kontrol etmediğini gösterdi. Neyi güncellemeli, neyi denetlemeli, neyi düzeltmeli?
Umut Korkmaz
Yayın tarihi: 4 dk okuma
Bu sayfada6
17 Eylül'de güvenlik girişimi AIR, Plugin4Shell adını verdiği bir açığı yayımladı. Açık, dört popüler kodlama ajanının plugin kurma biçiminde ortaya çıkan, sıfır tıklamayla uzaktan kod çalıştırmaya (RCE) izin veren bir zafiyet: Claude Code, OpenAI Codex, GitHub Copilot ve Gemini CLI. Dördü de bir marketplace'in plugin'i incelenmiş bir commit'e sabitlemesine izin veriyordu. Hiçbiri, sonunda çalıştırdığı commit'in sabitlenen commit olup olmadığını kontrol etmiyordu. Buradan çıkan ders, AI plugin'lerinin çok ötesine uzanıyor.
Atlatma nasıl çalışıyor
Commit SHA'sına sabitlemenin güvenli seçenek olması beklenir. Marketplace bir commit'i inceler, 40 karakterlik hash'ini manifest'e yazar ve her kurulum tam olarak o kodu checkout eder. Claude Code'un marketplace dokümantasyonu bunu, ref alanına göre öncelikli olan bir sha alanı olarak sunuyor.
AIR'a göre Claude Code, Codex ve Copilot önce git clone, ardından git checkout <pinned-sha> çalıştırıyordu. İşin püf noktası şu: Bazı Git host'ları, adı commit hash'ine benzeyen branch'leri kabul ediyor. Bir isim hem bir ref'e hem de bir commit'e karşılık geldiğinde Git ref'i tercih ediyor ve yalnızca refname is ambiguous uyarısı basıyor. Plugin repository'sini kontrol eden bir saldırgan, sabitlenen hash'le aynı isimde bir branch açıyor, bu branch'i kötü amaçlı koda yönlendiriyor ve onu default branch yapıyor. Ajan commit'i istiyor, branch'i alıyor.
AIR'ın tarif ettiği saldırı zinciri sabır istiyor: Zararsız bir plugin yayımla, sabitlenmesini ve kurulmasını sağla, marketplace'in yeniden sabitlemesi için zararsız bir güncelleme gönder, sonra yeni pin'le aynı isimde bir branch yerleştir. AIR'a göre Claude Code ve Codex'te varsayılan olarak açık olan arka plan otomatik güncellemesi, kimse hiçbir şeye tıklamadan checkout'u yeniden çalıştırıyor. Gemini CLI'da ise bir varyant vardı: SHA'yı fetch ediyor, ardından git checkout FETCH_HEAD çalıştırıyordu; FETCH_HEAD adlı bir default branch de kazanıyordu.
GitHub, 40 hex karakterlik branch isimlerini doğrudan reddediyor; dolayısıyla bu numara, bu tür isimlere izin veren bir host gerektiriyor. AIR, Bitbucket'ın ve self-hosted her Git sunucusunun buna izin verdiğini belirtiyor; Claude Code'un plugin dokümantasyonu da her ikisinden gelen Git URL'lerini kabul ediyor.
Hangi vendor nerede duruyor
AIR açığı mayısta buldu ve haziranda vendor'lara bildirdi. Kendi zaman çizelgesine ve InfoWorld'ün haberine göre:
- Claude Code: 2.1.179'da düzeltildi, Anthropic 17 Haziran 2026'da doğruladı.
- Codex: 0.146.0'da düzeltildi, 12 Ağustos 2026'da doğrulandı.
- GitHub Copilot: Düzeltme yayımlanmadı. GitHub, The Register'a commit SHA'larına benzeyen versiyon veya tag isimlerini zaten kısıtladığını ve bunun GitHub ile marketplace'inde saldırıyı engellediğini söyledi. AIR ise marketplace'lerin Bitbucket gibi başka yerlerde de bulunabileceğini, dolayısıyla bunun yeterli olmayabileceğini belirtiyor.
- Gemini CLI: Google aracı deprecate etti ve 4 Ağustos'ta düzeltme yayımlanmayacağını doğruladı. AIR, Antigravity'ye geçilmesini öneriyor.
Sabitlemek doğrulamak değildir
Pin bir talimattır. Doğrulama ise sonucu geri okumaktır. AIR'ın önerdiği çözüm, checkout'tan sonra istenen ref'i değil, çözümlenmiş HEAD'i pin ile karşılaştıran tek bir assertion. Açık haliyle:
git checkout --quiet "$PINNED_SHA"
actual="$(git rev-parse HEAD)"
if [ "$actual" != "$PINNED_SHA" ]; then
echo "pin mismatch: wanted $PINNED_SHA, got $actual" >&2
exit 1
fi
SHA'nın 40 karakterin tamamını saklayın: rev-parse HEAD tam hash'i döndürür, dolayısıyla kısaltılmış bir pin güvenli tarafta kalarak başarısız olur (fail closed).
AIR, pin istemci tarafında çözümlendiği için bu kontrolün ajanın içinde olması gerektiğinin altını çiziyor; marketplace bu açığı tek başına kapatamaz. Sabitlemeye dayanan her inceleme süreci bu açığı miras alır: İnceleme geçer, pin yazılır ve kurulan kod başka bir kod olur.
Aynı kalıp AI dışında da karşımıza çıkıyor: git checkout $RELEASE_SHA çalıştıran deploy script'leri, dahili bir Git sunucusundan sabitlenmiş bir aracı çeken CI job'ları, bir bağımlılığı commit üzerinden vendor'layan bootstrap script'leri. Host hash isimli branch'lere izin veriyorsa ve script HEAD'i hiç geri okumuyorsa, pin sadece bir öneriden ibarettir.
Pazartesi günü neleri kontrol ederdim
- Ajan versiyonları. Claude Code 2.1.179 veya üzeri, Codex 0.146.0 veya üzeri olmalı. CI runner'lar dahil her yerde
claude --versionvecodex --versionçalıştırın. - Plugin envanteri. Claude Code'da
/plugin marketplace list, herkesin neler eklediğini gösterir. GitHub dışındaki her Git URL'sini işaretleyin. Managed settings ile kişilerin hangi marketplace'leri ekleyebileceğini de kısıtlayabilirsiniz. - Copilot ve Gemini CLI. Copilot bir düzeltme yayımlayana kadar, onu GitHub'da barındırılan güvenilir plugin'lerle sınırlardım. Gemini CLI ise emeklilik planına alınmalı.
- Otomatik güncelleme politikanızı ikiye ayırın. Vendor yamalarının gelmesi için ajanların kendisinin otomatik güncellenmesine devam edin. Plugin kaynakları konusunda ise bilinçli davranın: Claude Code dokümantasyonuna göre resmi Anthropic marketplace'leri varsayılan olarak otomatik güncelleniyor, diğer üçüncü taraf marketplace'lerde bu özellik kapalı başlıyor ve her marketplace için ayrı ayrı açıp kapatabiliyorsunuz.
- Tespit. InfoWorld'ün görüşüne başvurduğu analist Pareekh Jain, zafiyetli ajanları çalıştıran makinelerde olağandışı process'lerin, ağ bağlantılarının, plugin dosyalarının, Git aktivitesinin ve credential kullanımının incelenmesini; ayrıca EDR, Git, CI/CD, cloud IAM ve kimlik doğrulama log'larının kontrol edilmesini öneriyor.
- Kendi script'leriniz. SHA değişkeniyle kullanılan
git checkoutçağrılarını arayın ve arkasına geri okuma kontrolünü ekleyin.
Benim görüşüm
Kodlama ajanları kaynak kodun, credential'ların ve CI/CD'nin hemen yanında duruyor; Jain de bu noktaya dikkat çekiyor. Kurulu plugin'ler kolayca unutuluyor, bu da sessiz bir otomatik güncelleme yolunu cazip bir hedef haline getiriyor. Ekipler kenarlara kontroller ekleyebilir, ancak asıl çözüm vendor'ların sorumluluğunda ve dört vendor'dan ikisi bunu yayımladı.
Ajan araçları geliştiriyorsanız (ben de Convoke ile geliştiriyorum), kural basit: Gerçekte neyi checkout ettiğinizi çözümleyin ve pin ile eşleşmeyen hiçbir şeyi çalıştırmayı reddedin. İsteğe değil, sonuca güvenin.
Kaynaklar
Bu yazıda yararlanılan birincil kaynaklar.
- air.security/blog-posts/plugin4shell (yeni sekmede açılır)
- infoworld.com/article/4223907/a-zero-click-rce-flaw-in-ai-coding-agents-could-have-exposed-enterprise-systems.html (yeni sekmede açılır)
- code.claude.com/docs/en/plugin-marketplaces (yeni sekmede açılır)
- code.claude.com/docs/en/discover-plugins (yeni sekmede açılır)