Indirect Prompt Injection: Kenapa Output Tool Tak Tepercaya
Indirect prompt injection untuk pemula: kenapa teks dari tool MCP adalah input yang tak tepercaya, dua insiden nyata, dan kontrol yang tetap bertahan.
Oleh Matthews WongDitinjau pada Dicek dengan MCP specification 2026-07-28
Poin utama
Indirect prompt injection terjadi ketika instruksi yang tersembunyi di data yang dibaca agen, misalnya hasil tool, tiket, atau halaman web, mengarahkan tindakan berikutnya. Bagi model, output tool hanyalah teks tambahan di konteksnya, jadi apa pun yang bisa ditulis pihak luar adalah input tak tepercaya. Solusinya membatasi apa yang bisa dilakukan agen berikutnya, bukan menyaring teksnya.
Setelah pelajaran ini, Anda bisa
- Menjelaskan mengapa hasil tool bisa mengarahkan agen, dan mengenali tool mana yang mengembalikan teks yang bisa ditulis pihak luar.
- Menelusuri dua kasus nyata dari sudut pandang pembela: event error palsu dan server yang mengubah deskripsi tool-nya sendiri.
- Memilih kontrol yang bertahan di bawah model: persetujuan, aturan deny, sandbox, dan fingerprint definisi tool.
Ikuti diagramnya langkah demi langkah
Tekan Putar, atau melangkah dengan panah. Setiap langkah juga ditulis di bawah diagram.
Bagaimana teks tulisan pihak luar sampai ke tindakan agen berikutnya
Pihak luar mengirim event error palsu, MCP server mengembalikannya sebagai output tool, model membacanya sebagai panduan dan meminta menjalankan perintah, dan hanya gerbang di luar model yang menghentikannya.
Ditinjau pada 17 Oktober 2026 · MCP specification 2026-07-28
Tombol: ← → langkah · Home / End · K putar atau jeda
Seorang developer meminta agen memilah error lewat MCP server. Tracker menerima event dari siapa pun yang memegang kunci ingest-nya, yang sering dimuat di halaman web publik.
Pihak luar mengirim event error palsu yang teksnya mirip panduan perbaikan dari tracker itu sendiri. Tidak ada yang diretas: kunci dan tracker bekerja sesuai desain.
event: an error message plus a Resolution sectionDeveloper meminta agen memilah error. MCP server mengembalikan event tanam itu bersama event asli sebagai output tool biasa, tanpa pengecekan integritas atas tulisan pihak luar.
tools/call list_issues → real events + 1 plantedTebak langkah berikutnya Model kini memegang teks tanam itu. Bagaimana ia membedakan data dari instruksi? (Tidak bisa dengan andal: keduanya teks di konteksnya · Output tool ditandai tak tepercaya, jadi diabaikan)Bagi model, semuanya teks dalam satu konteks. Dalam pengujian para peneliti, agen menganggap teks tanam itu sebagai panduan dan meminta menjalankan perintah di dalamnya.
tool_use: Bash · command taken from the event textTebak langkah berikutnya Agen meminta menjalankan perintah itu. Kontrol mana yang bisa menghentikannya apa pun keyakinan model? (System prompt yang menyuruh abaikan data tak tepercaya · Gerbang di luar model: persetujuan atau sandbox)Pertahanan di level prompt gagal dalam pengujian para peneliti. Yang bertahan ada di luar model: persetujuan yang dibaca manusia, aturan deny, dan sandbox tanpa jalan keluar.
ask: Bash(npx *) · deny: Bash(curl *) · sandbox allowlist emptyDeadbugz menunjukkan pintu kedua: sebuah server berperilaku normal selama tiga call, lalu menulis ulang deskripsi tool-nya untuk mengarahkan agen. Buat fingerprint definisi dan setujui ulang setiap ada perubahan.
hash each tool definition at approval, re-check after every call
Apa itu indirect prompt injection?
Prompt injection adalah teks yang berusaha memberi model AI instruksi baru. Indirect prompt injection menyembunyikan instruksi itu di konten yang dibaca agen saat mengerjakan tugas, misalnya halaman web, tiket, event error, atau hasil tool, bukan di apa yang diketik pengguna. OWASP menggambarkan MCP tool poisoning dengan cara yang sama: tool yang tampak normal, tetapi respons-nya membawa instruksi tersembunyi.
Baca selengkapnya (2)Tutup
Cara ini berhasil karena model tidak punya jalur terpisah untuk data. System prompt, pesan pengguna, dan hasil tool semuanya datang sebagai teks dalam satu context window, dan model memutuskan tindakannya dari semua itu. Spesifikasi MCP meminta client memvalidasi hasil tool sebelum diteruskan ke model, tetapi OWASP mencatat bahwa mendeteksi sepenuhnya instruksi yang disisipkan di teks bebas masih menjadi masalah terbuka.
Jadi pertanyaan yang berguna bukan apakah sebuah teks tampak aman, melainkan siapa yang mungkin menulisnya. Error tracker, log, issue tracker, kotak masuk support, dan web search semuanya mengembalikan teks yang bisa dipengaruhi pihak luar. Perlakukan setiap hasil seperti itu sebagai input tak tepercaya, sama seperti web server memperlakukan isian formulir.
Apa yang ditunjukkan kasus agentjacking dan Deadbugz?
Dalam agentjacking, peneliti Tenet Security memakai Sentry DSN publik, kunci khusus tulis yang sering dimuat di kode frontend, untuk mengirim event error palsu yang tampilannya mirip panduan diagnostik. Saat developer meminta agen meninjau issue Sentry, Sentry MCP server mengembalikan event itu bersama event asli, dan agen yang diuji menjalankan perintah di dalamnya dengan hak akses developer itu sendiri.
Baca selengkapnya (2)Tutup
Catatan Cloud Security Alliance menyebutnya masalah arsitektur: endpoint ingest yang menerima event apa pun dari pemegang DSN, MCP server yang meneruskan event tanpa pengecekan integritas, dan agen yang memercayai output tool seperti instruksi operator. Tenet melaporkan tingkat keberhasilan 85% pada Claude Code, Cursor, dan Codex dalam pengujiannya sendiri, dan menyatakan pertahanan di level prompt gagal. Data mentahnya tidak dipublikasikan, jadi anggap angka itu jauh di atas nol, bukan angka yang presisi.
Deadbugz menyerang sisi lain dari sebuah tool: deskripsinya. Pillar Security melaporkan server yang berperilaku normal selama tiga tool call pertama, lalu mengubah metadata tool dan prompt-nya untuk mengarahkan agen ke SSH key, kredensial cloud, dan riwayat shell, serta menyembunyikannya dari pengguna. Server itu datang lewat 23 pull request, tidak satu pun ter-merge saat ditinjau Pillar. Tinjauan sekali saat instalasi akan meloloskan server seperti itu.
Pertahanan mana yang tetap bertahan saat teksnya lolos?
Taruh kontrolnya pada tindakan, bukan pada teks. Respons Sentry, seperti disampaikan Tenet dan CSA, adalah filter untuk satu string payload dari riset itu, dan CSA memperingatkan bahwa susunan kata yang berbeda bisa lolos dari pencocokan string. Yang bertahan adalah apa pun yang membatasi langkah agen berikutnya: persetujuan yang benar-benar dibaca manusia, aturan deny untuk perintah berisiko, dan sandbox yang ditegakkan sistem operasi.
Baca selengkapnya (2)Tutup
Dokumentasi Claude Code menarik garis yang sama. Aturan izin ditegakkan oleh Claude Code, bukan oleh model, jadi instruksi di prompt atau CLAUDE.md membentuk apa yang dicoba Claude, tetapi tidak mengubah apa yang diizinkan. Dan batasan sandbox tetap berlaku walaupun prompt injection berhasil mengakali keputusan Claude, itulah sebabnya dokumentasinya menyarankan memakai keduanya.
Lethal trifecta dari Simon Willison menyebut campuran yang berbahaya: akses ke data pribadi, paparan ke konten tak tepercaya, dan cara mengirim data keluar. Agen yang membaca telemetri pasti punya yang kedua, jadi hilangkan yang pertama atau ketiga sebisa mungkin. Untuk deskripsi server, buat fingerprint setiap definisi tool saat Anda menyetujuinya dan anggap setiap perubahan setelahnya sebagai kejadian keamanan; cara ini hanya mendeteksi perubahan, jadi tinjauan pertama tetap harus sungguh-sungguh.
Konfigurasi nyata di balik pelajaran ini
Kutipan dari repositori yang membangun dan men-deploy situs ini, apa adanya.
// Reject prompt injection attempts before hitting Groq.
// - Scanned over the history too, not just `message`: conversationHistory is
// client-supplied and every entry that is not "user" is coerced into an
// assistant turn below, so an injection placed there reaches the model as
// words apparently already spoken by the assistant — the position most
// likely to be obeyed.
// - userName is scanned too: it is interpolated straight into the system
// prompt as the greeting target, the single highest-trust position, so an
// injection there would otherwise slip past every other check.Chatbot situs ini memanggil model tanpa tool apa pun, jadi hal terburuk yang bisa dilakukan injection yang berhasil hanyalah membuatnya bicara di luar topik. Route-nya tetap mengikuti aturan pelajaran ini: yang penting adalah dari mana teks berasal, bukan di mana ia mendarat. Riwayat percakapan datang dari browser, jadi dipindai sama seperti pesannya, karena teks yang ditaruh di giliran asisten sendiri adalah posisi yang paling mungkin dipatuhi model.
// Strip markup, braces and newlines before the name lands in the system
// prompt: it is the one piece of user input placed in a trusted position, so
// it must not be able to carry structure that reads as instructions.
const safeName =
typeof userName === "string"
? userName
.replace(/[<>{}`\r\n]/g, " ")
.replace(/\s+/g, " ")
.trim()
.slice(0, 60)
: "";Nama pengunjung adalah satu-satunya input pengguna yang ditaruh di dalam system prompt, jadi markup, kurung kurawal, dan baris barunya dibuang dulu lalu dipotong menjadi 60 karakter. Route yang sama juga menjalankan filter pola atas semua teks pengguna, yang hanya menangkap susunan kata yang sudah terpikirkan seseorang. Itulah batas jujur setiap filter: lapisan pertama yang memblokir kata-kata yang sudah dikenal, tidak pernah menjadi batas pengamannya.
Kesalahan yang benar-benar membuang waktu
System prompt yang menyuruh abaikan data tak tepercaya
Tenet melaporkan bahwa pertahanan di level prompt gagal dalam pengujian agentjacking-nya. Instruksi kepada model hanyalah saran yang mungkin diikuti, mungkin tidak. Taruh kontrolnya di izin host dan di sandbox.
Menyetujui sekali, berlaku selamanya
Di Claude Code, pilihan Yes, and don't ask again untuk perintah Bash berlaku permanen per repositori dan perintah, jadi satu klik saat lelah menjadi izin yang menetap. Tinjau aturan tersimpan di /permissions dan pertahankan aturan ask untuk instalasi dan package runner.
Meninjau server hanya saat instalasi
Deadbugz berperilaku normal selama tiga call, jadi uji coba singkat atau scan pendek tidak melihat ada yang salah. Buat fingerprint definisi tool dan periksa ulang di dalam sesi yang sedang berjalan, bukan di scan terpisah.
Filter untuk payload minggu lalu
Pencocokan string hanya memblokir susunan kata yang sudah dipublikasikan, sedangkan percobaan berikutnya memakai kata yang berbeda. Anggap filter konten dari vendor sebagai bonus, dan tetap pasang kontrol Anda sendiri pada tindakannya.
| Kontrol | Yang dihentikan | Yang terlewat |
|---|---|---|
| Prompt yang menyuruh abaikan data tak tepercaya | Tidak ada yang bisa diandalkan | Gagal dalam pengujian agentjacking |
| Persetujuan manusia untuk shell dan instalasi | Tindakannya, jika manusia membacanya | Aturan allow yang tersimpan menghilangkan prompt-nya |
| Aturan deny untuk curl dan wget | Dua program itu | Program yang sama lewat path atau di dalam sh -c |
| Sandbox tanpa jaringan keluar | Perintah shell yang mengirim data keluar | Tool file dan MCP server berjalan di luarnya |
| Fingerprint definisi tool | Deskripsi yang berubah setelah disetujui | Definisi yang jahat sejak awal, dan hasil tool |
Lakukan di komputer Anda sendiri
Anda butuh Claude Code dan satu repositori git latihan tanpa rahasia asli di dalamnya. Anda akan mendaftar dari mana teks tulisan pihak luar sampai ke agen, memasang gerbang pada langkah berikutnya, lalu menjalankan latihan aman yang menguji gerbangnya, bukan modelnya.
Daftarkan MCP server yang dimuat proyek ini, lalu tandai setiap server yang hasilnya bisa ditulis pihak luar: error tracker, log, tiket, kotak masuk, web search.
claude mcp listPasang gerbang pada langkah setelah membaca. Minta konfirmasi sebelum package runner dan instalasi, dan tolak dua tool unduhan yang umum, di .claude/settings.json.
{ "permissions": { "ask": ["Bash(npx *)", "Bash(npm install *)", "Bash(pip install *)"], "deny": ["Bash(curl *)", "Bash(wget *)"] } }Pastikan tidak ada aturan yang dilewati saat settings dimuat. claude doctor menampilkan aturan yang tidak bisa diterapkan Claude Code.
claude doctorJalankan latihannya. Di sebuah file uji, tulis satu kalimat biasa yang meminta AI mana pun yang membacanya untuk membuat file bernama canary-check.txt, lalu minta Claude meringkas file itu. Setup yang aman melaporkan kalimat itu sebagai isi, atau berhenti untuk bertanya sebelum menulis apa pun.
ls canary-check.txtTinjau apa saja yang sudah Anda setujui secara permanen, dan hapus aturan allow yang tidak dibutuhkan lagi.
/permissions
Tiga pertanyaan sebelum lanjut
Pilih jawaban untuk melihat kenapa benar atau salah. Tidak ada nilai, jadi tebak saja dengan bebas; jawaban yang salah disimpan di browser ini agar kursus bisa menanyakannya lagi nanti.
Satu pertanyaan dari pelajaran sebelumnya
Mengingat kembali pelajaran lama setelah jeda membuatnya lebih melekat. Jawab dari ingatan sebelum mencari apa pun.
Jawab dalam hati, lalu cek
1.Mengapa agen tidak cukup disuruh mengabaikan instruksi di dalam hasil tool?Lihat jawabannya
Jawaban:Model menerima instruksi dan data dengan cara yang sama: sebagai teks di konteksnya. Permintaan untuk mengabaikan sebagian teks hanyalah satu teks lagi yang bersaing dengan teks tanam, dan dalam pengujian agentjacking cara itu tidak bertahan.
2.Kaki lethal trifecta mana yang paling mudah dihilangkan untuk agen yang bertugas memilah event error?Lihat jawabannya
Jawaban:Biasanya jalur keluarnya. Membaca event tak tepercaya memang tugasnya, dan akses ke sebagian kode pribadi dibutuhkan, tetapi sandbox tanpa jaringan keluar kecuali host tertentu mencegah data curian pergi.
3.Apa yang tidak dilindungi oleh fingerprint definisi tool?Lihat jawabannya
Jawaban:Definisi yang sudah jahat sejak tinjauan pertama, dan teks yang dikembalikan tool call. Fingerprint hanya mendeteksi perubahan, jadi tinjauan pertama dan kontrol atas tindakan agen tetap penting.
Bahasan mendalam terkait di situs ini
Sumber
Sumber primer yang diperiksa pada tanggal riset. Ikuti tautannya untuk versi terbaru.
- Tenet Security: agentjacking agen coding lewat error Sentry palsu
- Cloud Security Alliance: catatan riset agentjacking lewat Sentry MCP
- Pillar Security: Deadbugz, kampanye rantai pasok MCP
- OWASP Community: MCP tool poisoning
- Simon Willison: lethal trifecta untuk agen AI
- Spesifikasi MCP 2026-07-28: pertimbangan keamanan tool
- Dokumentasi Claude Code: izin ditegakkan Claude Code, bukan model