Claude Code'un "Tekrar Sorma" Özelliği API Anahtarlarını GitHub'a Sızdırıyor: Nasıl Kontrol Edilir ve Düzeltilir

"Don't Ask Again" ile bir komutu onaylamak, şifreler dahil olmak üzere komutu kelimesi kelimesine kaydeder. Depolarınız için tek komutluk kontrolü, temizlik sırasını ve anahtarların ajan onaylarına nasıl girmeyeceğini burada bulabilirsiniz.

Ahmed Waheed

Ahmed Waheed

12 November 2026

Claude Code'un "Tekrar Sorma" Özelliği API Anahtarlarını GitHub'a Sızdırıyor: Nasıl Kontrol Edilir ve Düzeltilir

Kurumsal İçin Apidog

Şirket İçi (On-Premises) Dağıtım

SSO ve RBAC

SOC 2 Uyumlu

Apidog Enterprise'ı Keşfedin

Claude Code’un “Tekrar Sorma” düğmesi, onayladığınız komutu birebir .claude/settings.local.json dosyasına izin (allow) kuralı olarak kaydediyor. Bu komutta parola veya API anahtarı varsa, gizli bilgi artık proje klasörünüzde düz metin olarak duruyor ve dosya commit edilirse herkese açık hale geliyor. Güvenlik firması Apiiro, herkese açık GitHub’da bu şekilde 1.122 dosya ve bunlarda 1.379 gerçek gizli bilgi buldu. İşte kendi depolarınızı tek komutla kontrol etmenin, temizlemenin ve bunun tekrar yaşanmasını önlemenin yolu.

Ne oldu: Apiiro bulguları sayılarla

Apiiro, herkese açık GitHub’da Claude Code’un kişisel izin onaylarınızı sakladığı proje başına dosya olan .claude/settings.local.json kopyalarını aradı. Araştırma, 103.617 depoda 104.185 kopya buldu. iTnews’in araştırma hakkındaki yazısına göre bunlardan 1.122’sinde en az bir gerçek gizli bilgi vardı; toplamda 1.379 farklı gizli bilgi.

Gizli bilgi türü Adet
Veritabanı parolaları 379
Supabase service-role anahtarları 122
Herkese açık sunucular için SSH giriş bilgileri 43
GitHub, GitLab ve npm token’ları 42
AWS anahtarları 23

Apiiro aramayı dosyanın eski git sürümlerine, paylaşılan .claude/settings.json dosyasına ve kayıtlı ajan günlüklerine genişlettiğinde sayı, 1.994 depoda 2.539 gizli bilgiye çıktı. Apiiro kimlik bilgilerinin hâlâ çalışıp çalışmadığını test etmedi, ancak bilgilendirdiği bir kuruluş anahtarın aktif olduğunu doğruladı.

Tarama sonuçları en çok endişelenmeniz gereken kısım. Gerçek gizli bilgi içeren 1.122 dosyanın 643’ünü TruffleHog, 564’ünü gitleaks işaretledi. 215 dosya ikisinden de kaçtı. Yani “gizli bilgi tarayıcımız var” demek temiz olduğunuzun kanıtı değil.

Olay, 582 puanla Hacker News’ün zirvesine yerleşti. Anthropic’te Claude Code’un başındaki Boris Cherny, başlıkta Claude Code’un tarihsel olarak gizli bilgileri temizlemediğini ve ekibin bunu incelediğini belirtti. Orijinal Apiiro araştırmasını okuyun.

“Tekrar Sorma” nasıl olur da gizli bilgileri bir dosyaya koyar?

Claude Code bir Bash komutu çalıştırmak istediğinde önce sorar. “Evet ve tekrar sorma” seçeneğini seçtiğinizde Claude Code, Anthropic’in ayarlar dokümantasyonunda anlatıldığı gibi kalıcı bir onayı .claude/settings.local.json dosyasına allow kuralı olarak yazar. Kural, komut metnini kaydeder. Komut şu olsaydı:

psql "postgresql://admin:Sup3rS3cret@db.example.com:5432/prod" -c "select count(*) from users"

ayarlar dosyanız artık şuna benzer bir içerik barındırıyordu:

{
  "permissions": {
    "allow": [
      "Bash(psql \"postgresql://admin:Sup3rS3cret@db.example.com:5432/prod\" -c \"select count(*) from users\")"
    ]
  }
}

Parola kuralın içinde, çünkü komutun içindeydi. Claude Code, onayladığınızı kelimesi kelimesine kaydeder.

Diagram of how a Claude Code approval with an inline password flows into settings.local.json and then into a public GitHub repository

Neden GitHub’a düşüyor

Claude Code bu dosyayı git dışında tutmaya çalışır. Halihazırda yok sayılmayan bir depoda ilk kez .claude/settings.local.json yazdığında, global git hariç tutma (excludes) dosyanıza **/.claude/settings.local.json ekler. Ancak bu korumada boşluklar var:

Depolarınızı tek komutla kontrol edin

Bulunduğunuz depoyla başlayın. Şu komutlar dosyanın şu anda takip edilip edilmediğini ve hiç commit edilip edilmediğini söyler:

git ls-files | grep -E '(^|/)\.claude/settings(\.local)?\.json$'
git log --all --name-only --format= | grep -E '\.claude/settings(\.local)?\.json$' | sort -u

İlk satır bir şey yazdırıyorsa, dosya mevcut ağacınızda demektir. İkinci satır bir şey yazdırıyorsa, dosya sonradan silinmiş olsa bile geçmişinizdedir.

Bir klasör altındaki tüm depoları tek seferde taramak için:

find ~/code -path '*/.claude/settings.local.json' -exec sh -c \
  'cd "$(dirname "$1")/.." && git ls-files --error-unmatch .claude/settings.local.json >/dev/null 2>&1 && echo "TRACKED: $PWD"' _ {} \;

Bir GitHub organizasyonu için GitHub CLI, dosya adına göre kod arayabilir:

gh search code permissions --owner your-org --filename settings.local.json

Sonra bulduğunuz her dosyanın içine bakın. Tarayıcılar sızan dosyaların %19’unu kaçırdığı için yeşil bir tarama sonucuna güvenmek yerine kuralları kendiniz okuyun:

grep -nE 'Bash\(' .claude/settings.local.json | grep -iE 'pass|token|key|secret|://[^/]*:[^@]*@'

user:password@ içeren bir bağlantı dizesi, Authorization: Bearer başlığı, -p ardından yazılmış bir parola ya da sk-, ghp_, AKIA veya eyJ ile başlayan her şey bir kimlik bilgisidir. İkinci bir geçiş olarak — tek geçiş değil — depo üzerinde gitleaks çalıştırın.

Sızan bir ayarlar dosyası nasıl düzeltilir

Sıralama önemli. Önce anahtar değişimi gelir; çünkü dosyayı silmek, fork’larda, klonlarda ve önbelleklerde duran kopya için hiçbir şey yapmaz.

  1. Dosyanın içerdiği her kimlik bilgisini değiştirin. Dosyanın tüm geçmişini git log -p --all -- .claude/settings.local.json ile inceleyin, içindeki her gizli bilgiyi listeleyin ve her birini sağlayıcısında iptal edin. Apiiro’nun rehberi bu adımı ilk sıraya koyar.
  2. Dosyayı takipten çıkarın ve deponun kendisinde yok sayın:
git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git add .gitignore && git commit -m "Stop tracking Claude Code local settings"
git check-ignore -v .claude/settings.local.json

Son komut eşleşen .gitignore satırını yazdırmalı. Depodaki bir kural her klonu korur.

  1. Depo herkese açıksa veya geniş çapta paylaşıldıysa geçmişi temizleyin. git-filter-repo dosyayı her commit’ten kaldırır:
git filter-repo --invert-paths --path .claude/settings.local.json
git push --force --all

Bu, herkes için geçmişi yeniden yazar; bu yüzden önce ekibinizi uyarın. Fork’lara da ulaşmaz; yani bu bir temizlik işlemidir, 1. adımın yerine geçmez.

  1. Yerel dosyayı da temizleyin. .claude/settings.local.json dosyasını açın, gerçek bir gizli bilgi içeren her kuralı silin ve yerine bir desen (bir sonraki bölüm) koyun.
  2. Push korumasını açın. GitHub secret scanning push protection, tanınan gizli bilgi biçimlerini içeren push’ları engeller. 215 dosyanın kaçtığı gösterdiği gibi her şeyi yakalamaz ama yaygın token biçimlerini durdurur.

Tekrar yaşanmasını önleyin

Çözümü söylemek basit: ajanınızın çalıştırdığı bir komuta asla gerçek bir gizli bilgi yazmayın ve tam komutlar yerine desenleri onaylayın.

Side-by-side comparison of a risky Claude Code allow rule containing a literal password and a safe rule that references an environment variable

Gizli bilgilere atıfta bulunun, yazmayın. Kabuk, bir değişkeni çalışma anında açar; ancak allow kuralı metni yazıldığı gibi saklar. Yani psql "$DATABASE_URL" komutu, kurala parolayı değil $DATABASE_URL’i kaydeder:

{
  "permissions": {
    "allow": ["Bash(psql \"$DATABASE_URL\" *)", "Bash(npm run test *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}

deny kuralları doğrudan Anthropic’in ayarlar dokümanlarından alınmıştır; Claude Code’un .env dosyalarınızı okumasını engeller, böylece bir anahtar oradan bir komuta yapıştırılamaz.

Kuralları dar tutun. Araştırmayı alıntılayan HN yorumcuları, dosyaların %5’inin herhangi bir kabuk komutuna izin verdiğini ve %43’ünün Bash(python:*) gibi yorumlayıcı kuralları olduğunu söyledi. Böyle bir kural, ajanın her şeyi Python üzerinden çalıştırmasına izin verir; yani fazladan adımlarla “her şeye izin ver” kuralıdır.

Auto modu ve bir sandbox düşünün. Cherny, elle yazılmış izin kuralları yerine auto modu önerdi ve Anthropic’in açık kaynaklı bir sandbox geliştirdiğini söyledi. Birkaç yorumcu, auto modun bir güvenlik sınırı değil bir sınıflandırıcı olduğunu belirtti; bu yüzden onu yukarıdaki alışkanlıklarla birlikte kullanın.

Ajanları üretim gizli bilgilerinden uzak tutun. En güvenli anahtar, ajanın hiç görmediği anahtardır. Bu konudaki desenleri AI ajanlarının API anahtarlarını görmeden nasıl kullanacağı yazımızda, saldırganların sızan AI anahtarlarıyla yaptıklarını ise çalınan AI API anahtarları ve LLMjacking yazımızda ele almıştık.

Apidog CLI ile kodlama ajanınızın anahtar yazmadan API çağırmasını sağlayın

Bir anahtarın onaylanmış bir komuta düşmesinin yaygın yollarından biri hızlı bir API çağrısıdır: bir endpoint’i kontrol etmek için curl -H "Authorization: Bearer sk-...". Bu işi yerine Apidog CLI’ya devredebilirsiniz. Anahtar bir Apidog ortam değişkeninde durur, test senaryonuz ona {{API_KEY}} olarak atıfta bulunur ve ajanınızın çalıştırdığı komut yalnızca proje, senaryo ve ortam ID’leri içerir. Kaydedilecek gizli bir şey yoktur.

Kurulumu bir kez yapın — ajan üzerinden değil kendi terminalinizde — böylece erişim token’ınız hiçbir onaydan geçmez:

npm install -g apidog-cli@latest
apidog auth login
npx -y skills add https://apidog.com   # pick Claude Code when prompted

Sonra Claude Code’a tek bir prompt verin:

List the environments in Apidog project 123456, then run test scenario 7890
against the staging environment and summarise any failed assertions.
The API key is stored in that environment as {{API_KEY}}. Never pass a key,
token or password on the command line, and never use --env-var for secrets.

Ajan, “Tekrar Sorma” ile güvenle onaylanabilecek şu tür komutları çalıştırır:

apidog environment list --project 123456
apidog run -t 7890 --project 123456 -e <envId> -r cli,json

İki dürüst uyarı. Birincisi, apidog run değişkenin paylaşılan değerini kullanır; bu değer Apidog’a senkronize edilir ve proje üyeleri tarafından görülebilir, bu yüzden oraya üretim root anahtarı değil kapsamı daraltılmış bir test anahtarı koyun. Değerleri diskte tutmak isterseniz, apidog run ayrıca --variables <path> parametresini alır; onu deponun dışındaki bir dosyaya yönlendirin. İkincisi, --env-var "key=value" parametresi komut satırından değişken geçmek için vardır ve tam da bu desen sızdırır; bu yüzden ajanınıza gizli bilgiler için bunu kullanmamasını söyleyin.

Enterprise planındaki ekipler ayrıca Apidog Vault Secrets ile HashiCorp Vault, Azure Key Vault veya AWS Secrets Manager’dan gizli bilgileri çekebilir ve Enterprise SaaS Secret Scanner, Apidog isteklerine, script’lerine ve değişkenlerine kaydedilen anahtarları işaretler. GitHub depolarını taramaz; bu yüzden yukarıdaki kontrolleri de sürdürün. Tam kurulum rehberi için Claude Code’da Apidog CLI nasıl kullanılır ve Apidog’da ortamları ve gizli değişkenleri yönetme yazılarına bakın. Apidog’un Free planı 4 kullanıcıya kadar kapsar.

button

SSS

Claude Code’un settings.local.json dosyası varsayılan olarak gitignore edilir mi?

Kısmen. Claude Code bir git deposunda dosyayı oluşturduğunda, global git excludes dosyanıza **/.claude/settings.local.json ekler. Bu yalnızca kendi makinenizi korur ve dosyayı elle oluşturduysanız ya da zorla eklediyseniz geçerli değildir. Satırı deponun kendi .gitignore dosyasına da ekleyin.

Dosyayı silmek sızan anahtarı kaldırır mı?

Hayır. Anahtar git geçmişinde, fork’larda ve herkese açık olduğu süreçte yapılan her klonda durur. Önce anahtarı değiştirin, sonra dosyayı takipten çıkarın ve geçmişi git-filter-repo ile temizleyin.

gitleaks veya TruffleHog bu sızıntıları yakalar mı?

Güvenilir şekilde hayır. Apiiro’nun örneğinde, gerçek gizli bilgi içeren 1.122 dosyanın 215’i her iki araç tarafından da kaçırıldı. Bir tarayıcı çalıştırın, sonra dosyadaki Bash(...) kurallarını kendiniz okuyun.

Bu bir model sorunu mu, yoksa Claude Code sorunu mu?

Apiiro bunu Opus 5.5 ve Fable 5.1 ile yeniden üretti ve bir model özelliği değil, Claude Code özelliği olarak nitelendirdi. Onay, komutu yazan model ne olursa olsun komut metnini saklar.

Claude Code’da komutları güvenle nasıl onaylarım?

Bash(npm run test *) gibi desenleri onaylayın ve gizli bilgilere $DATABASE_URL gibi ortam değişkenleriyle atıfta bulunun. Read(./.env) ve Read(./.env.*) için deny kuralları ekleyin.

API Tasarım-Öncelikli Yaklaşımı Apidog'da Uygulayın

API'leri oluşturmanın ve kullanmanın daha kolay yolunu keşfedin