Geçenlerde bir Electron masaüstü uygulaması üzerinde çalışıyordum. Ana süreçten (main process) renderer sürecine (renderer process) veri göndermem ve bunu işlemem gerekiyordu. Her zamanki gibi, `webContents.executeJavaScript()` metoduna sarıldım. Ama tam "gönder" butonuna basacakken, içimde bir şüphe uyandı. "Ya kullanıcı bu kod çalıştırma işini manipüle ederse?" diye düşünmeye başladım. Meğer sorun tam da buradaymış.
Klasik hikaye: Hızlıca işi halletmek için güvenliği ikinci plana attım. Dışarıdan gelen, kullanıcı tarafından doldurulmuş bir formun verisini, azıcık temizlemeden (sanitization) direkt olarak `executeJavaScript` içine string olarak ekliyordum. Şaka gibi ama, bir XSS (Cross-Site Scripting) davetiyesi çıkartıyormuşum meğerse.
JavaScript:
// BU YAPMAYIN! (Eski ve tehlikeli yol)
let userInput = document.getElementById('someInput').value; // Diyelim ki bu "<script>kötüNiye tKod()</script>"
mainWindow.webContents.executeJavaScript(`updateUI("${userInput}")`); // Felaket!
Yukarıdaki gibi bir kullanım, eğer `userInput` değeri temizlenmezse, renderer'da keyfi kod çalıştırılmasına neden olabilir. StackOverflow'da bile tam istediğim cevabı bulamamıştım, ta ki kendi başıma çökene kadar.
Araştırmalarım sonucunda, `executeJavaScript`'in kendi başına mutlak bir güvenlik açığı OLMADIĞINI, ancak YANLIŞ kullanımın açığa yol açtığını anladım. Çözüm, veriyi güvenli bir kanaldan göndermek ve renderer tarafında da güvenli bir şekilde işlemek.
Anahtar nokta, contextBridge ve ipcRenderer ile güvenli bir iletişim köprüsü kurmak. Ana süreçten, sadece veriyi (komut değil) gönderiyorsun. Renderer süreci de bu veriyi kendi kontrollü fonksiyonlarıyla işliyor.
JavaScript:
// Preload.js'de - ContextBridge ile güvenli bir API oluştur
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('myAPI', {
onDataUpdate: (callback) => ipcRenderer.on('data-update', (event, data) => callback(data))
});
// Main.js'de - Veriyi güvenli kanalla gönder
mainWindow.webContents.send('data-update', { info: safeUserData });
// Renderer'da (Artık güvendeyiz) - Sadece veriyi al ve işle
window.myAPI.onDataUpdate((data) => {
document.getElementById('output').innerText = data.info;
});
Bu yöntemde, renderer'a "şu kodu çalıştır" demiyorsun, "işte verin, sen kendi preload'tan sana verdiğim fonksiyonunla bunu işle" diyorsun. Aradaki fark devasa.
`executeJavaScript` güçlü bir silah. Doğrudan DOM manipülasyonu veya hızlı debug için kullanılabilir. Ancak, dışarıdan gelen hiçbir veriyi temizlemeden oraya sokmamak gerekiyor. Güvenlik için en iyi pratik, iş mantığını mümkün olduğunca preload script'lerine ve güvenli IPC kanallarına taşımak.
Siz ne düşünüyorsunuz? `executeJavaScript` için başka güvenlik tuzaklarına düştünüz mü? Yoksa "abartıyorsun, şöyle kullanılır" diyecek bir yolunuz var mı? Yorumlarda buluşalım!