İçeriğe geç
Sedat Özdemir
Yazılar

iot-security

Kodu Yazdın mı, Yoksa Sadece Hayal mi Ettin? Vibe Coding’in Karanlık Yüzü

Geçen akşam evde otururken, sırf meraktan yeni çıkan bir LLM modelini denemek istedim. Kafamda bir fikir var, "Hadi şunu bir web uygulamasına dönüştürelim"...

Sedat Özdemir
· 5 dk okuma

Geçen akşam evde otururken, sırf meraktan yeni çıkan bir LLM modelini denemek istedim. Kafamda bir fikir var, "Hadi şunu bir web uygulamasına dönüştürelim" dedim. Cursor’ı açtım, Claude 3.5 Sonnet'e "Bana kullanıcıların dosya yükleyebildiği, profil oluşturabildiği basit bir dashboard yap" komutunu verdim. Beş dakika geçmedi, karşımda pırıl pırıl, React ile yazılmış, Tailwind ile süslenmiş mis gibi bir uygulama duruyor. Gerçekten büyüleyici bir deneyim. Ama işin aslı, o "vibe" yakalandığında insan bir anlığına her şeyin mükemmel olduğunu sanıyor.

İşte tam o noktada içimdeki o huysuz güvenlikçi ses fısıldamaya başladı: "Sedat, bu kodun içini gerçekten kontrol ettin mi?"

Vibe coding dediğimiz olay aslında tam olarak bu. Bir şeyler hissetmek, akışa kapılmak ve yapay zekanın o akıcı cümlelerine güvenip "Tamam ya, çalışıyor işte" diyerek deploy tuşuna basmak. Ama bizim sektörde "çalışıyor" demekle "güvenli" demek arasında uçurumlar var. Son birkaç aydır incelediğim projelerde ve katıldığım siber güvenlik tartışmalarında gördüğüm tek bir şey var: Hız bizi kör ediyor.

"Bana Bir Login Yaz" Demek Neden Riskli?

Diyelim ki bir arkadaşınla kahve içiyorsun ve ona "Abi bana bir giriş ekranı kodu versene" diyorsun. Arkadaşın sana bir kağıda kod yazıp veriyor. Sen o kağıdı alıp direkt sunucuya atar mısın? Atmazsın. Ama yapay zeka yazınca nedense içimizde bir güven oluşuyor.

Geçenlerde bir pentest çalışmasında denk geldiğim bir örneği anlatayım. Ekip, uygulamanın yetkilendirme (authorization) kısmını tamamen bir LLM'e yazdırmış. Kod ilk bakışta harika görünüyor, JWT kullanıyor, her şey yerli yerinde. Ama ufak bir detay var; LLM, isAdmin kontrolünü sadece front-end tarafında yapmış. Yani kullanıcı arayüzünde admin panelini görmüyorsun ama backend'e bir istek attığında kapılar ardına kadar açık.

Senin LLM'e verdiğin prompt ne kadar genel olursa, alacağın kod o kadar "ortalama" olur. Ve ortalama kod, genellikle güvenlikten feragat edilmiş koddur.

Görünmez Tehlike: Mantık Hataları (Logic Flaws)

Yapay zeka sentaks hatası yapmıyor olabilir ama senin iş mantığını (business logic) senin kadar iyi kavrayamaz. Şöyle bir kod bloğu düşün, senin için bir yapay zeka asistanı tarafından üretilmiş olsun:

// Yapay zekanın "hızlıca" yazdığı basit bir middleware
app.post('/update-profile', (req, res) => {
  const { userId, newEmail, role } = req.body;
  
  // Kullanıcı bilgisini güncelle
  db.query('UPDATE users SET email = ?, role = ? WHERE id = ?', [newEmail, role, userId], (err, result) => {
    if (err) return res.status(500).send("Hata oluştu");
    res.send("Profil güncellendi!");
  });
});

Buradaki sorunu gördün mü? Muhtemelen yapay zekaya "Profil güncelleme sayfası yap" dedin. O da kullanıcıdan gelen role alanını sorgusuz sualsiz aldı ve veritabanına yazdı. Şimdi ben, kötü niyetli bir kullanıcı olarak, isteğin içine role: 'admin' eklersem ne olur? Tebrikler, artık sisteminde yeni bir admin var.

İşin aslı şu; vibe coding yaparken "ne yapılacağını" söylüyoruz ama "ne yapılmaması gerektiğini" söylemeyi hep unutuyoruz. "Kullanıcı rolünü asla kullanıcıdan alma" demediğin sürece, o yapay zeka o açığı oraya bırakır. Çünkü onun derdi senin "vibe"ını bozmamak, yani sana çalışan bir kod vermek.

Hallucination (Halüsinasyon) Sadece Metinlerde Değil

Yapay zekanın olmayan kütüphaneleri varmış gibi göstermesine alıştık. Ama daha tehlikeli bir şey var: Eskimiş ve güvenlik zafiyeti barındıran kütüphaneleri önermesi.

Bir projede karşılaştım; yapay zeka görüntü işleme için çok eski bir kütüphaneyi önermiş ve kodun içine entegre etmişti. Kütüphanenin o sürümünde meşhur bir RCE (Remote Code Execution) zafiyeti vardı. Geliştirici arkadaşımız ise sadece "Valla Claude öyle dedi, ben de kurdum" diyordu.

İşte dikkat etmen gereken yer tam burası. LLM'in önerdiği her paket, her npm install komutu potansiyel bir risk. O paket gerçekten var mı? Bakımı yapılıyor mu? En son ne zaman güncellendi? Bunları kontrol etmezsen, vibe coding maceran bir veri sızıntısıyla sonuçlanabilir.

Secrets: O API Key'i Oraya Kim Koydu?

Vibe coding sırasında en sık yapılan hatalardan biri de "hardcoded secrets". Yapay zeka örnek kod verirken genellikle şöyle yapar:

import stripe
stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" # Buraya kendi anahtarınızı yazın

Sen o anki heyecanla kendi gerçek API key'ini oraya yapıştırıyorsun, kod çalışıyor, her şey harika. Sonra bir bakıyorsun, o dosya çoktan GitHub'a pushlanmış. Botlar saniyeler içinde o key'i yakalıyor ve senin Stripe hesabın üzerinden birileri bayram ediyor.

Benim tavsiyem; vibe coding yaparken her zaman .env dosyası kullanmayı bir refleks haline getir. Hatta yapay zekaya "Bana bu kodu yaz ama gizli anahtarları .env dosyasından okuyacak şekilde yapılandır" diye özellikle belirt.

Input Validation: "Nasılsa Yapay Zeka Yazdı, Temizdir" Yanılgısı

Sıkça karşılaştığım bir durum da input validation (girdi doğrulama) eksikliği. Yapay zeka sana bir form yazdığında, genellikle sadece "mutlu yolu" (happy path) düşünür. Yani kullanıcı adını düzgün girerse ne olacağını yazar. Ama kullanıcı adı yerine bir SQL injection payload'u girerse ne olacağını çoğu zaman atlar.

Bak şuna bir göz at:

// LLM tarafından üretilen "hızlı" bir arama fonksiyonu
app.get('/search', (req, res) => {
  const query = req.query.q;
  const sql = "SELECT * FROM products WHERE name LIKE '%" + query + "%'";
  
  db.query(sql, (err, rows) => {
    // sonuçları dön...
  });
});

Burada query parametresi doğrudan SQL sorgusuna gömülmüş. Klasik bir SQL Injection. "Ama abi 2024 yılındayız, yapay zeka bunu yapmaz herhalde" deme, yapıyor. Özellikle karmaşık sorgularda veya nadir kullanılan dillerde/frameworklerde bu tarz hatalar çok daha sık karşımıza çıkıyor.

Peki Ne Yapmalı? Vibe'ı Nasıl Korumalı?

Şimdi "Sedat, hiç mi kullanmayalım bu araçları?" diyeceksin. Tabii ki kullan. Ben de kullanıyorum. Ama öğrenmeye açık bir tonla, sorgulayarak kullanman lazım. İşte benim güvenli vibe coding için uyguladığım birkaç basit kural:

  1. Güvenlik Promptları Ekle: Sadece "Bana şunu yap" deme. "Bana şunu yap, OWASP Top 10 standartlarına uygun olsun ve input validation eklemeyi unutma" de.
  2. Kodu Satır Satır Oku: Yapay zekanın yazdığı kodu asla ama asla okumadan projene ekleme. O an bir "arkadaşınla konuşuyor gibi" olabilirsin ama o arkadaşın bazen çok saçmalayabiliyor.
  3. Statik Analiz Araçları Kullan: Snyk, SonarQube veya basit bir npm audit bile hayat kurtarır. Yapay zekanın yazdığı kodu bu araçlardan geçir.
  4. Least Privilege (En Az Yetki) Prensibi: Uygulamanın veritabanı kullanıcısına sadece ihtiyacı olan yetkileri ver. Eğer bir SQL Injection olursa, saldırgan en azından tüm veritabanını silemesin.

Son Söz Niyetine

Vibe coding, yazılım geliştirme dünyasında devrim niteliğinde bir olay. Kabul edelim, çok eğlenceli ve inanılmaz hız kazandırıyor. Ama bu hızın bizi felakete sürüklemesine izin vermemeliyiz. Güvenlik, sonradan üzerine eklenecek bir özellik değil, kodun karakteridir.

Bir dahaki sefere yapay zekaya bir şey yazdırdığında, o "vibe"ın büyüsüne kapılmadan önce kendine şu soruyu sor: "Ben bu kodu bir başkası yazmış olsaydı, ona bu kadar güvenir miydim?"

Cevabın "Hayır" ise, o klavyeye biraz daha sert basmanın ve kodu incelemenin vakti gelmiş demektir. Güvende kal, vibe'ını bozma!

İlgili yazılar