Cara Mengatasi Suntikan Prompt Pada Ejen Pengekodan
Ketahui cara ejen pengekodan terdedah kepada serangan suntikan prompt melalui fail dan input luaran. Kami memetakan permukaan serangan serta menyenaraikan pertahanan berkesan.
Apakah suntikan prompt terhadap ejen pengekodan
Suntikan prompt terhadap ejen pengekodan boleh dinyatakan dengan mudah: teks yang dibaca oleh ejen dianggap sebagai arahan yang perlu diikuti oleh ejen tersebut. Ejen membuka fail, komen pull request, halaman web atau hasil daripada panggilan alat. Kesemuanya sampai sebagai jenis teks yang sama seperti permintaan anda sendiri. Jika penyerang mengawal mana-mana teks tersebut, penyerang sedang menulis ke dalam sesi anda.
Setiap produk ejen semasa mempunyai sifat ini. Model menerima satu jujukan token. Permintaan anda, prompt sistem, kandungan fail dan hasil alat digabungkan bersama, dan model meramalkan apa yang akan berlaku seterusnya. Tiada bit keistimewaan pada token. Tiada apa-apa dalam format tersebut yang menyatakan bahagian mana yang anda benarkan dan bahagian mana yang datang daripada fail README orang asing.
Halaman ini merupakan model ancaman: di mana teks yang dikawal penyerang sampai kepada ejen yang berjalan pada pelayan, apa yang diperolehi oleh penyerang pada setiap titik, dan pertahanan yang berbaloi untuk dilakukan. Nasihat pengurungan dalam panduan kami yang lain hanya masuk akal apabila anda tahu apa yang anda sedang kurung daripada ejen tersebut.
Mengapa model tidak dapat memisahkan kandungan daripada arahan
Latihan membantu tetapi tidak menyelesaikannya. Model semasa dilatih untuk melayan teks yang diambil dengan penuh curiga, dan ia menolak banyak percubaan kasar. Penolakan adalah satu kebarangkalian, bukan peraturan. Penyerang boleh menyusun semula ayat, mencuba lagi, dan menyembunyikan teks dalam format yang tidak dirancang oleh sesiapa, dan tiada had kepada berapa banyak olahan kata yang boleh mereka cuba.
Projek OWASP GenAI menjejaki perkara ini sebagai LLM01:2025 Prompt Injection dan membahagikannya kepada dua. Suntikan langsung (direct injection) ialah arahan pengguna sendiri yang mengubah kelakuan model. Suntikan tidak langsung (indirect injection) ialah kandungan luaran, seperti laman web atau fail, yang mengubah kelakuan apabila model memprosesnya. Suntikan tidak langsung adalah perkara yang penting pada pelayan, kerana ejen membaca lebih banyak teks daripada yang anda taip.
Kajian sistematik pertama ialah Greshake dan rakan-rakan, Not what you've signed up for (2023). Kesimpulan mereka adalah ayat yang perlu diingat: apabila aplikasi menyuapkan teks yang diambil ke dalam model yang boleh memanggil alatan, memproses teks tersebut adalah hampir sama dengan pelaksanaan kod arbitrari (arbitrary code execution).
Keadaan yang menjadikan pembacaan sebagai satu pelanggaran
Membaca teks yang berniat jahat bukanlah kerosakan dengan sendirinya. Kerosakan memerlukan laluan keluar daripada mesin tersebut.
Simon Willison menamakan gabungan itu sebagai the lethal trifecta pada Jun 2025. Ejen yang menyimpan data peribadi, terdedah kepada kandungan yang tidak dipercayai, dan boleh menghantar data keluar boleh dipujuk untuk memindahkan data peribadi melalui laluan ketiga.
Ejen pengekodan pada VPS anda mempunyai semua ciri tersebut sejak hari pertama. Data peribadi tersebut ialah kod sumber anda, fail .env anda, kunci SSH anda dan sejarah shell anda. Kandungan yang tidak dipercayai ialah setiap repositori, halaman dan hasil alat yang dibacanya. Laluan keluar ialah git push, curl, npm publish, badan pull request, atau pautan yang dipaparkan dalam terminal anda yang anda klik.
Anda tidak boleh membuang keadaan kedua, kerana membaca teks yang tidak dipercayai adalah tugas yang anda berikan kepada ejen tersebut. Oleh itu, setiap pertahanan praktikal berfungsi pada dua keadaan yang lain.
Apabila teks yang tidak dipercayai sampai kepada ejen pengekodan pada pelayan
Repositori tempat ejen bekerja
Setiap fail dalam daftar keluar (checkout) adalah input. Komen sumber, README.md, log perubahan, lekapan ujian (test fixtures), kod yang dibekalkan (vendored code), dan fail arahan ejen itu sendiri: CLAUDE.md, AGENTS.md serta setaranya. Ejen yang diminta untuk memahami pangkalan kod akan membacanya, kerana itulah yang anda minta.
Apa yang diperoleh penyerang di sini ialah capaian kepada sesiapa sahaja yang mengklon repositori tersebut dan menghalakan ejen kepadanya. Fail arahan adalah laluan paling terus, kerana ia wujud untuk dibaca sebagai arahan. Permintaan tarik (pull request) yang menambah empat baris berguna pada CLAUDE.md dan satu baris yang mengubah hala ejen adalah perubahan yang mungkin terlepas pandang oleh penyemak manusia.
Isu, permintaan tarik dan komen semakan kod
Apa-apa sahaja yang boleh ditaip oleh orang asing ke dalam penjejak anda akan sampai kepada ejen sebaik sahaja anda memintanya untuk melakukan triaj. Pada Mei 2025, Invariant Labs menerbitkan penemuan GitHub MCP dengan bentuk yang tepat seperti ini. Ejen seorang pembangun mempunyai akses kepada satu repositori awam dan repositori peribadi. Seorang penyerang memfailkan isu dalam repositori awam tersebut. Apabila pembangun meminta ejen untuk melihat isu terbuka, ejen membaca kandungan repositori peribadi dan menulisnya ke dalam permintaan tarik di bahagian awam.
Laporan itu menerangkan masalah seni bina dan bukannya kecacatan kod dalam pelayan MCP. Ejen tersebut memegang satu token akses yang luas, membaca daripada peti masuk awam, dan mempunyai kebenaran untuk menulis. Tiada apa-apa yang tersalah konfigurasi dalam erti kata biasa, itulah sebabnya jawapannya adalah skop (scoping) dan bukannya menampal (patching).
Halaman web yang diambil oleh ejen
Dokumentasi, jawapan forum, halaman vendor, hasil carian. Mana-mana daripadanya boleh membawa teks yang ditulis untuk ejen dan bukannya untuk anda. HTML yang ditukar kepada teks memberikan ruang tambahan kepada penyerang, kerana kandungan yang tidak pernah dipaparkan oleh pelayar masih sampai kepada model.
Penyerang mendapat kawalan pada saat ejen paling kurang diawasi. Tiada siapa yang membaca teks penuh halaman yang diambil oleh ejen semasa mencari sesuatu.
Output alat MCP
MCP (model context protocol) ialah cara biasa ejen bersambung dengan alat luaran. Hasilnya kembali sebagai teks dan terus masuk ke dalam tetingkap konteks. Terdapat dua permukaan di sini, bukan satu. Data yang dikembalikan oleh alat adalah yang jelas. Nama dan penerangan alat itu sendiri, yang dibaca oleh model untuk memutuskan bila untuk memanggilnya, adalah satu lagi, dan pelayan yang tidak anda kawal boleh menukar mana-mana daripadanya antara panggilan.
Penyerang yang meletakkan teks dalam output satu alat akan mencapai setiap alat lain yang dimiliki oleh ejen tersebut. Begitulah cara suntikan dalam sesuatu yang bernilai rendah akhirnya mengawal sesuatu yang bernilai tinggi.
Log CI, output binaan dan metadata dependensi
npm install mencetak teks daripada pakej yang tidak anda tulis. Kegagalan ujian mencetak mesej asersi daripada pustaka. Log kerja penyepaduan berterusan (CI) adalah beribu-ribu baris output pihak ketiga. Minta ejen untuk membaiki binaan yang gagal dan ia akan membaca kesemuanya.
Di sini penyerang mendapat mesin binaan, yang biasanya memegang kelayakan penggunaan (deploy credentials) dan token pendaftaran serta kurang mendapat perhatian berbanding komputer riba.
Apa yang sebenarnya diperolehi oleh penyerang
Terdapat empat hasil yang perlu dirancang.
Kecurian kelayakan. Apa sahaja yang boleh dibaca oleh proses ejen adalah dalam skop: pemboleh ubah persekitaran, ~/.aws/credentials, ~/.ssh, token gh, atau fail konfigurasi Docker. Menghantarnya keluar tidak memerlukan curl. Komit ke cawangan, huraian pull request, pakej yang diterbitkan ke dalam daftar, atau carian DNS untuk nama yang dikawal oleh penyerang, semuanya memindahkan data keluar dari pelayan.
Perubahan kod yang anda luluskan. Menulis kod adalah tugas ejen, jadi memintanya menulis satu baris yang salah secara halus adalah hasil yang paling mudah dicapai. Penambahan dependensi, atau panggilan log yang membawa token ke dalam log yang anda hantar ke tempat lain.
Kegigihan (Persistence). Fail yang ditulis sekali akan terus berfungsi tanpa melibatkan model: cangkuk (hook) dalam .git/hooks, skrip postinstall dalam package.json, baris yang ditambah pada fail permulaan shell, atau baris tambahan dalam CLAUDE.md. Perintah seterusnya akan menjalankannya.
Pergerakan di dalam rangkaian anda. Ejen berjalan di tempat anda meletakkannya. Jika pelayan tersebut boleh mencapai pangkalan data pada loopback, servis pentadbir dalaman, servis metadata pembekal awan anda, atau hos lain pada rangkaian peribadi, maka apa sahaja yang mengawal ejen tersebut juga boleh melakukannya.
Mod auto-approve membuang semakan terakhir
Dalam mod lalai, Claude Code meminta pengesahan sebelum ia menjalankan sesuatu arahan atau menyunting fail. Gesaan tersebut merupakan semakan manusia yang menjadi penghalang antara setiap permukaan di atas dengan tindakan sebenar. Mod yang membuang gesaan tersebut akan membuang semakan itu.
Dokumentasi menyatakan dengan jelas tentang bypassPermissions: gunakannya hanya dalam persekitaran terasing seperti kontena atau VM di mana Claude Code tidak boleh menyebabkan kerosakan. Mod auto adalah lebih lembut, dan meluluskan panggilan alatan secara automatik dengan semakan keselamatan latar belakang yang mengesahkan tindakan selaras dengan permintaan anda. Semakan tersebut dapat mengesan banyak perkara. Ia masih merupakan pertimbangan model terhadap output model, jadi anggap ia sebagai penapis dan bukannya sebagai sempadan.
Seorang pentadbir boleh membuang kedua-duanya. Tetapkan permissions.disableBypassPermissionsMode atau permissions.disableAutoMode kepada "disable" dalam fail tetapan, dan letakkan fail tersebut dalam tetapan terurus supaya projek yang telah disemak keluar tidak boleh mengatasi tetapan tersebut. Panduan kami mengenai mod auto dan peraturan kebenaran Claude Code merangkumi tempat setiap peraturan berkuat kuasa.
Pertahanan, disusun mengikut faedah yang diperoleh
Tiada satu pun daripada ini merupakan penyelesaian muktamad. Setiap satunya sama ada mengehadkan apa yang dipegang oleh ejen atau mengehadkan apa yang boleh dilakukan oleh ejen tersebut.
- Mesin yang boleh anda musnahkan dan bina semula, supaya kompromi hanya memakan masa sejam dan bukannya menjadi satu insiden.
- Kredensial yang berasingan daripada milik anda, dihadkan kepada satu repositori, dan mempunyai tempoh hayat yang singkat.
- Tiada rahsia yang kekal lama dalam persekitaran yang diwarisi oleh arahan ejen.
- Penguatkuasaan sistem pengendalian pada trafik keluar rangkaian dan akses fail, yang terpakai kepada setiap proses yang dimulakan oleh ejen.
- Gesaan kelulusan dikekalkan untuk operasi tulis dan panggilan rangkaian.
- Hook sebagai benteng penentu untuk tindakan khusus yang boleh anda namakan.
- Membaca diff sebelum anda menggabungkannya (merge).
Urutan ini penting. Perkara 1 hingga 4 tetap berkesan walaupun model berada di bawah kawalan penuh penyerang. Perkara 5 hingga 7 bergantung kepada perhatian manusia, yang merupakan perkara yang pasti akan hilang semasa ejen berjalan dalam tempoh yang lama.
Letakkan ejen pada mesin yang boleh anda lupuskan
VPS yang menyimpan checkout dan satu token terhad adalah sasaran yang jauh lebih kecil berbanding komputer riba yang menyimpan kunci anda. Jalankan ejen sebagai pengguna tanpa keistimewaan (unprivileged user) sendiri, bukan sebagai akaun log masuk anda dan bukan sebagai root. Panduan kami mengenai VM pakai buang untuk ejen pengekodan dan pengguna dengan keistimewaan minimum pada VPS merangkumi persediaan ini, dan menjalankan Claude Code dengan selamat pada VPS merangkumi rutin hariannya.
Keluarkan rahsia daripada persekitaran
Pemboleh ubah persekitaran boleh dibaca oleh setiap proses anak, yang bermaksud setiap arahan yang dijalankan oleh ejen. Sandbox Claude Code boleh menyahset (unset) pemboleh ubah bernama sebelum setiap arahan dalam sandbox. Pada Linux, sandbox memerlukan dua pakej terlebih dahulu:
sudo apt-get install bubblewrap socatKemudian dalam ~/.claude/settings.json:
{
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["github.com", "*.npmjs.org"]
},
"credentials": {
"envVars": [
{ "name": "GITHUB_TOKEN", "mode": "deny" },
{ "name": "NPM_TOKEN", "mode": "deny" }
]
}
}
}Entri deny menyahset pemboleh ubah tersebut sebelum setiap arahan sandbox dijalankan, dan allowedDomains mengehadkan arahan sandbox kepada hos yang anda senaraikan. Blok credentials memerlukan Claude Code v2.1.187 atau lebih baharu, disemak Ogos 2026. Jalankan /sandbox dalam sesi untuk melihat lapisan mana yang aktif dan dependensi mana yang tiada. Menentukan rahsia mana yang perlu wujud pada kotak tersebut adalah bahagian yang lebih besar daripada tugas ini, dan menjauhkan rahsia daripada capaian ejen AI membincangkan perkara ini dengan lebih lanjut.
Sekat trafik keluar rangkaian pada sistem pengendalian
Peraturan firewall tidak peduli dengan keputusan model. Jalankan ejen sebagai pengguna agent khusus, kemudian jatuhkan (drop) apa yang dihantar oleh pengguna tersebut:
table inet agentcage {
chain output {
type filter hook output priority filter; policy accept;
meta skuid "agent" ct state established,related accept
meta skuid "agent" oif lo accept
meta skuid "agent" counter drop
}
}Ini meninggalkan pengguna agent dengan loopback sahaja, jadi trafiknya perlu melalui proksi yang anda jalankan pada kotak yang sama, dan proksi tersebut memegang senarai hos yang dibenarkan (allowlist). Dengan https_proxy menghala ke proksi tersebut, klien menghantar permintaan CONNECT dan proksi melakukan carian nama, jadi ejen tidak memerlukan DNS (domain name system) keluar sendiri. Semak kerja anda dengan sudo nft list ruleset dan perhatikan kaunter pada peraturan drop meningkat semasa ejen cuba mencapai sesuatu yang baharu.
Pastikan sesi SSH kedua dibuka semasa anda menggunakan perubahan firewall. Semak juga apa yang dilakukan oleh runtime kontena anda terhadap peraturan ini: Docker menulis chain-nya sendiri, dan port Docker yang diterbitkan memintas ufw menerangkan kejutan yang disebabkan oleh perkara itu.
Hook: pemeriksaan yang tidak boleh dipintas oleh model
Peraturan kebenaran dan hook dikuatkuasakan oleh Claude Code, bukan oleh model. Dokumentasi menyatakan perkara ini dengan jelas: arahan dalam prompt anda atau CLAUDE.md membentuk apa yang cuba dilakukan oleh Claude, dan ia tidak mengubah apa yang dibenarkan oleh Claude Code. Perbezaan itu adalah nilai keseluruhannya. Satu baris dalam CLAUDE.md yang berbunyi "jangan sekali-kali jalankan curl" hanyalah cadangan yang boleh dibantah oleh perenggan yang disuntik. Hook ialah proses yang mengembalikan kod keluar (exit code).
Daftarkan hook PreToolUse dalam .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/no-egress.sh"
}
]
}
]
}
}Hook menerima panggilan alat sebagai JSON pada input standard. Kod keluar 2 menyekat panggilan tersebut dan menunjukkan kepada Claude sebabnya daripada ralat standard. Kod keluar 0 membenarkan panggilan tersebut diteruskan melalui aliran kebenaran biasa.
#!/usr/bin/env bash
# PreToolUse: stdin holds the tool call, exit 2 blocks it.
cmd=$(jq -r '.tool_input.command // ""')
if printf '%s' "$cmd" | grep -qE '(^|[;&|]|\s)(curl|wget|nc|ncat)(\s|$)'; then
echo "Blocked: this repository does not allow outbound network commands." >&2
exit 2
fi
exit 0Sekarang bahagian yang jujur. Ini adalah senarai hitam (denylist) ke atas rentetan shell, dan senarai hitam ke atas rentetan shell boleh bocor. python3 -c membuka soket tanpa menggunakan perkataan curl. Sasaran make deploy menyembunyikan panggilan yang sama satu tahap lebih dalam. Tulis hook untuk kesilapan yang boleh anda namakan, dan letakkan sempadan yang anda benar-benar harapkan pada kernel atau pada rangkaian.
Peraturan penafian kebenaran (permission deny rules) membawa had padanan yang perlu diketahui. Peraturan penafian Read dan Edit meliputi alat fail Claude sendiri dan arahan fail yang dikenalinya dalam Bash, seperti cat, head, tail dan sed. Ia tidak meliputi skrip Python atau Node yang membuka fail itu sendiri. Peraturan dinilai dengan penafian didahulukan, kemudian tanya, kemudian benarkan, jadi peraturan penafian tidak boleh membawa pengecualian senarai benarkan (allowlist).
{
"permissions": {
"deny": [
"Read(.env)",
"Read(./secrets/**)",
"Bash(git push *)"
]
}
}Perhatikan apa yang keluar, dan baca diff
Satu larian ejen menghasilkan diff dan satu set panggilan rangkaian. Kedua-duanya perlu dilihat sebelum apa-apa digabungkan atau digunakan. Semakan keselamatan yang dihoskan sendiri ke atas diff menangkap kelas perubahan yang berbeza daripada imbasan manusia, dan mengetahui apa yang dihantar oleh ejen pengekodan keluar dari kotak memberitahu anda rupa trafik biasa, supaya permintaan yang ganjil akan kelihatan menonjol.
Perkara yang masih belum selesai
Pada masa ini, tiada pemisahan yang boleh dipercayai antara kandungan dan arahan. Setiap pertahanan yang dikeluarkan sama ada merupakan penapis dengan kadar kegagalan tertentu atau sekadar mengehadkan kesan serangan. Tiada apa-apa dalam tindanan (stack) teknologi yang menandakan sesuatu rentetan teks sebagai data yang tidak boleh dipatuhi sama sekali.
Penapis memang membantu, namun ia juga boleh gagal. Pengelas yang mampu menangkap kebanyakan percubaan suntikan (injection) perlu tepat pada setiap masa, manakala penyerang hanya perlu berjaya sekali sahaja. Asimetri inilah yang menyebabkan kadar kejayaan pertahanan yang diterbitkan hanyalah titik permulaan untuk percubaan seterusnya, bukannya satu jaminan.
Usaha yang paling menjanjikan terletak pada tahap reka bentuk, bukan pada tahap model. CaMeL, daripada Defeating Prompt Injections by Design (Debenedetti dan rakan-rakan, 2025), mengekstrak aliran kawalan dan aliran data daripada permintaan yang dipercayai terlebih dahulu, supaya data yang tidak dipercayai tidak boleh mengubah tindakan program, kemudian menguatkuasakan semakan keupayaan apabila alatan dipanggil. Angka dalam kertas kajian itu sendiri pada penanda aras AgentDojo menunjukkan kos yang perlu dibayar untuk perkara tersebut.
The data behind this chart
[
{
"label": "Undefended agent",
"tasks_solved_pct": 84
},
{
"label": "CaMeL",
"tasks_solved_pct": 77
}
]Ejen yang tidak dilindungi menyelesaikan 84 peratus tugasan. CaMeL menyelesaikan 77 peratus dengan jaminan keselamatan disertakan. Itu adalah angka yang diterbitkan dalam kertas kajian tersebut pada satu penanda aras dan bukannya ukuran bagi beban kerja anda. Jurang antara kedua-duanya secara kasarnya merupakan kos bagi jaminan sebenar pada hari ini.
Sehingga reka bentuk seperti itu dikeluarkan dalam alatan yang anda gunakan setiap hari, rancanglah untuk menghadapi kemungkinan ejen anda diceroboh pada bila-bila masa dan jadikan peristiwa tersebut sebagai sesuatu yang tidak memberi kesan besar. Itulah hujah utama bagi penggunaan mesin pakai buang, kelayakan (credentials) yang terhad skopnya, trafik keluar yang terkawal, dan tabiat menyemak perbezaan (diff) kod.
FAQ
Bolehkah saya menghentikan suntikan prompt (prompt injection) dengan memberitahu ejen untuk mengabaikan arahan dalam fail?
Tidak. Ayat tersebut hanyalah teks dalam tetingkap konteks yang sama dengan serangan, dan ia bersaing dengan teks penyerang pada tahap yang sama. Dokumentasi Claude Code menetapkan sempadan dengan jelas: arahan dalam prompt anda atau CLAUDE.md membentuk perkara yang cuba dilakukan oleh ejen, dan ia tidak mengubah perkara yang dibenarkan oleh alat tersebut. Anggap fail arahan sebagai pernyataan niat, dan letakkan sebarang perkara yang anda harapkan ke dalam peraturan kebenaran, cangkuk (hook) PreToolUse atau peraturan firewall.
Adakah suntikan prompt merupakan risiko sebenar jika ejen hanya menyentuh repositori saya sendiri?
Ya, kerana repositori anda penuh dengan teks yang bukan anda tulis. Fail README dependensi, URL fail kunci (lockfile), lekapan ujian (test fixtures), kod yang dibekalkan (vendored code) dan output daripada npm install semuanya tiba semasa tugasan biasa. Sebarang perkara yang ditarik masuk daripada penjejak isu atau tapak dokumentasi tiba dengan cara yang sama. Risiko meningkat mengikut jumlah bacaan ejen, dan ejen yang berguna membaca dengan banyak.
Adakah menjalankan ejen dalam bekas (container) menyelesaikan masalah ini?
Ia mengehadkan kerosakan, dan hanya jika anda turut mengeluarkan kelayakan (credentials). Bekas dengan ejen SSH anda yang diteruskan, kelayakan awan dalam persekitaran dan akses rangkaian tanpa sekatan memberikan penyerang hampir segala-galanya yang boleh diakses oleh hos. Perkara yang sebenarnya diperoleh daripada bekas ialah sistem fail yang boleh anda padam dan tempat yang bersih untuk menguatkuasakan peraturan keluar (egress rules). Padankan ia dengan token yang dihadkan kepada satu repositori sahaja.
Apakah perubahan tunggal yang paling mengurangkan risiko?
Alih keluar kelayakan jangka hayat panjang daripada persekitaran yang diwarisi oleh arahan ejen, kemudian berikan mesin tersebut polisi keluar (egress policy) lalai-tolak (default-deny). Bersama-sama, ia memecahkan syarat ketiga dalam trifecta maut: teks masih boleh merampas ejen, dan data yang dicapainya tidak mempunyai tempat yang berguna untuk pergi. Prompt kelulusan dan semakan diff juga membantu, dan ia bergantung pada manusia yang kekal berwaspada sepanjang proses yang panjang, itulah sebabnya ia diletakkan di bawah dua perubahan tersebut.