Skip to content

Latest commit

 

History

History
236 lines (172 loc) · 16.5 KB

SOCKET_DEV_FINDINGS.md

File metadata and controls

236 lines (172 loc) · 16.5 KB

Socket.dev / supply-chain finding attestation (Bahasa Indonesia)

🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇧🇦 bs · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW


Catatan Lingkup: socket.yml mengonfigurasi pemindaian pasca-publikasi sisi registri Socket.dev terhadap artefak npm (jalur-abaikan untuk konten yang tidak dikirim seperti tests/, docs/, dan laporan build). Ini tidak menghubungkan gerbang penggabungan CI/PR — tidak ada alur kerja di .github/workflows, tidak ada skrip package.json, dan tidak ada target Makefile yang memanggil Socket.dev.

Dokumen ini adalah atestasi yang dibuat oleh pemelihara untuk enam temuan potensi malware yang terdeteksi AI yang diajukan terhadap omniroute@3.8.5 dan mitigasi yang diterapkan di omniroute@3.8.6. Tujuannya adalah agar:

  1. Operator pipeline keamanan memiliki satu referensi untuk dikutip ketika mereka perlu mengevaluasi temuan terhadap sumber sebenarnya.
  2. Pemindai AI di masa mendatang dapat mengambil klaim yang ditandatangani pemelihara bahwa setiap jalur yang ditandai adalah disengaja, opt-in, dan didokumentasikan.
  3. Kami memiliki catatan tertulis tentang mengapa setiap situs panggilan dibentuk seperti itu — sehingga refaktor di masa mendatang tidak secara tidak sengaja memperkenalkan kembali sidik jari yang sengaja dihapus.

Jika Anda mengoperasikan pemindai yang menandai ulang salah satu situs panggilan di bawah ini setelah mitigasi v3.8.6 telah dirilis, harap buka masalah dengan jejak pemindaian dan kami akan memperluas atestasi di sini.


§1 — Instalasi root CA MITM (77484.js)

File sumber:

  • src/mitm/cert/install.ts — installCert() / uninstallCert() publik, serta installCertWindows/Mac/Linux khusus per platform.
  • src/mitm/systemCommands.ts — helper bersama execFile / spawn / PowerShell yang digunakan oleh jalur instalasi.

Pemicu: pengguna mengeklik "Aktifkan proksi MITM" di dasbor lokal pada /dashboard/cli-tools/mitm. Rute tersebut hanya dapat diakses melalui loopback — lihat aturan tegas #17 di CLAUDE.md dan src/server/authz/routeGuard.ts::isLocalOnlyPath(). JWT yang bocor dan terekspos melalui tunnel tidak dapat memicu jalur kode ini.

Operasi dengan hak istimewa yang dilakukan (per platform):

OS Perintah
Windows certutil -addstore Root <cert> melalui UAC
macOS sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <cert>
Linux sudo cp <cert> <distro-trust-dir> + sudo update-ca-certificates (Debian) / sudo update-ca-trust (RHEL/SUSE)
Linux+Firefox/Chromium pembaruan DB NSS per profil melalui certutil -d sql:<profile>

Ini adalah perintah yang sama dengan yang digunakan oleh mitmproxy, Charles Proxy, Fiddler, dan Caddy. Keberadaan perintah tersebut di OmniRoute didokumentasikan dalam docs/security/STEALTH_GUIDE.md.

Mitigasi v3.8.6:

  • runElevatedPowerShell() tidak lagi menggunakan -EncodedCommand <base64utf16le>. Payload yang dijalankan dengan hak istimewa ditulis ke file .ps1 sementara untuk setiap pemanggilan (mode 0o600, di dalam direktori privat mkdtempSync) dan dirujuk melalui -File. File tersebut dihapus dalam finally. Perubahan ini menghilangkan sidik klasik eskalasi-via-PowerShell-dengan-base64 yang ditandai oleh pengklasifikasi AI Socket.dev.
  • installCertWindows memuat blok inline SECURITY-AUDITOR-NOTE: yang mengarah ke dokumen ini.

Alasan kami mempertahankannya: proksi MITM adalah fitur terdokumentasi yang digunakan oleh docs/security/STEALTH_GUIDE.md dan docs/frameworks/MITM-PROXY.md. Menghapusnya akan merusak rangkaian fitur agent-bridge.


§2 — Impor kredensial Zed (app/api/providers/zed/import/route.js)

File sumber:

  • src/app/api/providers/zed/discover/route.ts (baru di v3.8.6)
  • src/app/api/providers/zed/import/route.ts
  • src/lib/zed-oauth/keychain-reader.ts
  • src/lib/zed-oauth/credentialFingerprint.ts (baru di v3.8.6)

Pemicu: pengguna mengeklik "Impor dari Zed" di halaman Penyedia pada dasbor lokal. Endpoint dilindungi oleh requireManagementAuth. Editor Zed sendiri menulis kunci API penyedianya ke keychain OS dengan nama layanan yang terdokumentasi — lihat https://zed.dev/docs/ai/llm-providers.

Perilaku v3.8.5 (yang ditandai oleh Socket.dev):

POST /import menemukan kredensial dan menyimpannya secara otomatis ke penyimpanan SQLite lokal dalam satu kali perjalanan bolak-balik. Tidak ada konfirmasi per akun, tidak ada sidik jari, hanya "ditemukan N token, semuanya diimpor."

Mitigasi v3.8.6 — konfirmasi 2 langkah:

  1. POST /api/providers/zed/discover mengembalikan { candidates: [{ provider, service, account, fingerprint }] }. Token mentah tidak pernah dikirimkan. Sidik jarinya adalah sha256(service|account|token).slice(0,16).
  2. Dasbor menampilkan daftar kandidat, operator memilih mana yang akan diimpor, lalu mengirimkan { confirmedAccounts: [{ service, account, fingerprint }] } ke POST /api/providers/zed/import.
  3. Endpoint impor membaca ulang keychain di server dan memfilter berdasarkan (service, account, fingerprint). Respons penemuan yang telah dimanipulasi atau diputar ulang tidak dapat mengelabui endpoint impor agar menyimpan token yang tidak terkait — jika token aktif telah berubah sejak penemuan, sidik jarinya tidak lagi cocok dan kredensial tersebut dilewati.

Flag env OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true mempertahankan perilaku v3.8.5 bagi operator yang belum memperbarui otomatisasi mereka. Flag ini akan dihapus di v3.9.

Alasan kami mempertahankannya: impor Zed adalah jalur orientasi yang paling mudah bagi pengguna yang sudah menggunakan Zed dan ingin mencerminkan kunci penyedia mereka ke OmniRoute tanpa harus menempelkannya kembali.


§3 — execFile / spawn / PowerShell dengan hak akses lebih tinggi (21843.js)

File sumber: src/mitm/systemCommands.ts.

Alasan ditandai: chunk tersebut mengekspor ulang execFileWithPassword, runElevatedPowerShell, dan helper bersama quotePowerShell. Pengklasifikasi AI Socket.dev melihatnya sebagai "perangkat eksekusi host + eskalasi hak akses" generik. Di dalam OmniRoute, fungsi-fungsi tersebut hanya digunakan oleh jalur instalasi sertifikat MITM (§1) dan oleh execFileWithPassword untuk eksekusi perintah sudo.

Mitigasi v3.8.6:

  • Pemfaktoran ulang runElevatedPowerShell (lihat §1).
  • Blok SECURITY-AUDITOR-NOTE: inline pada runElevatedPowerShell dan execFileWithPassword mendokumentasikan pemanggil yang diizinkan serta daftar executable tetap.
  • Pemanggilan spawn() milik execFileWithPassword memuat penanda nosemgrep beserta daftar executable yang diizinkan untuk diterima oleh helper tersebut — tidak ada jalur dari input pengguna ke finalCommand/finalArgs.

§4 / §6 — Supervisor layanan 9router (api/services/9router/{start,restart}/route.js)

File sumber:

  • src/app/api/services/9router/_lib.ts — factory supervisor.
  • src/app/api/services/9router/{start,stop,restart,status,install,update,auto-start}/route.ts.
  • src/lib/services/ServiceSupervisor.ts — spawn generik / polling kesehatan / buffer log.

Pemicu: pengguna mengeklik "Instal" / "Mulai" pada halaman layanan tersemat di dasbor lokal.

Perlindungan yang sudah tersedia:

  • Semua route /api/services/* bersifat LOCAL_ONLY sesuai src/server/authz/routeGuard.ts (aturan wajib #17). Penerapan loopback dilakukan sebelum pemeriksaan autentikasi apa pun — JWT yang bocor tidak dapat menjangkaunya.
  • Baris DB 9router diinisialisasi sebagai status='not_installed', auto_start=0 (lihat src/lib/db/migrations/071_services.sql:19). Layanan tersebut tidak dimulai saat peluncuran pertama.
  • spawn() dipanggil dengan path biner yang dikembalikan oleh resolveSpawnArgs(apiKey, PORT) di src/lib/services/installers/ninerouter.ts, yang merupakan daftar tetap biner yang didukung.
  • Stdout/stderr disimpan dalam buffer di memori (batas 5 MB, lihat _lib.ts) — tidak ada penulisan ke disk kecuali pengguna mengaktifkan pencatatan log dari dasbor.

Mitigasi v3.8.6: tidak ada perubahan fungsional. Profil build minimal (OMNIROUTE_BUILD_PROFILE=minimal) mengganti src/lib/services/installers/ninerouter.ts dengan stub bagi pengguna yang ingin jalur dengan hak akses istimewa dihapus secara fisik dari bundle.

Alasan kami mempertahankannya: 9router adalah layanan pendamping opsional yang dapat diinstal secara lokal (seperti plugin bergaya WordPress) — sepenuhnya berbasis keikutsertaan eksplisit.


§5 — Penulisan kembali kredensial OmniRoute Cloud Sync (api/keys/[id]/route.js)

File sumber:

  • src/lib/cloudSync.ts — syncToCloud() / updateLocalTokens().
  • src/app/api/keys/[id]/route.ts — memanggil syncKeysToCloudIfEnabled().

Pemicu: isCloudEnabled() mengembalikan true (diatur dari dasbor) dan CLOUD_URL dikonfigurasi. Jika keduanya dinonaktifkan, tidak ada panggilan jaringan keluar ke endpoint Cloud.

Perilaku v3.8.5 (bug yang terdeteksi Socket.dev dengan tepat):

updateLocalTokens() menimpa accessToken, refreshToken, dan providerSpecificData dari respons Cloud ketika cloudUpdatedAt > localUpdatedAt. Tanpa HMAC, tanpa tanda tangan, tanpa checksum. CLOUD_URL yang salah dikonfigurasi atau berbahaya (atau MITM pada saluran) dapat mengganti token OAuth penyedia secara diam-diam.

Mitigasi v3.8.6:

  1. Verifikasi HMAC: verifyCloudSignature(rawBody, sigHeader) memeriksa header X-Cloud-Sig (HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody)) sebelum mengurai JSON. Jika rahasia telah ditetapkan, tanda tangan wajib ada. Jika belum (mode lama), peringatan dicatat dan respons diterima — rahasia akan diwajibkan dalam v3.9.
  2. Keikutsertaan eksplisit untuk bidang rahasia: accessToken / refreshToken / providerSpecificData hanya ditimpa ketika OMNIROUTE_CLOUD_SYNC_SECRETS=true. Mode default hanya menyinkronkan metadata nonkredensial (expiresAt, status, lastError*, rateLimitedUntil, updatedAt). Ini merupakan perubahan yang merusak kompatibilitas bagi pengguna yang mengandalkan sinkronisasi token jarak jauh — mereka harus ikut serta secara eksplisit.

Mengapa kami mempertahankannya: Cloud Sync adalah satu-satunya cara bagi tenant OmniRoute Cloud untuk memusatkan kredensial tim. Perbaikan ini membuat model ancaman menjadi jelas: "server menandatangani, klien memverifikasi, operator ikut serta."


Profil build: minimal

Untuk pengguna yang memerlukan artefak yang kompatibel dengan Socket, build dengan:

OMNIROUTE_BUILD_PROFILE=minimal npm run build

NormalModuleReplacementPlugin webpack mengalihkan empat modul ke stub:

Modul Stub
src/mitm/cert/install.ts src/mitm/cert/install.stub.ts
src/lib/zed-oauth/keychain-reader.ts src/lib/zed-oauth/keychain-reader.stub.ts
src/lib/cloudSync.ts src/lib/cloudSync.stub.ts
src/lib/services/installers/ninerouter.ts src/lib/services/installers/ninerouter.stub.ts

Setiap stub mengekspor antarmuka yang sama, tetapi setiap fungsi melempar featureDisabledError(name) saat runtime. Rute yang bergantung pada modul yang dinonaktifkan akan mengembalikan HTTP 503 dengan pesan yang jelas, alih-alih mengaktifkan jalur kode sensitif.

Bundle yang dihasilkan dimaksudkan untuk dipublikasikan sebagai omniroute-secure.


Pemisahan plugin (dilacak untuk v4)

Dalam jangka panjang, kami bermaksud memisahkan package npm menjadi modul-modul yang dapat diaudit secara terpisah. Lihat milestone v4 di pelacak issue GitHub untuk issue pelacakannya.