flawopen.com/Referensi/Keamanan bot PR
Bot Review PR AI: Cegah SSRF via Prompt Injection
Bagaimana teks pull request tak tepercaya dapat memengaruhi tool AI dan cara membatasi izin bot serta akses jaringan.
Penjelasan mudah: asisten review dengan akses ke jaringan perusahaan
Pull request seperti paket yang dikirim ke tim review: isinya mungkin berguna, tetapi tidak menjadi kebijakan perusahaan. Jika bot review AI juga dapat mengambil URL sembarang dari jaringan privat, instruksi yang menyesatkan bisa memengaruhi tujuan yang diakses. Risikonya bergantung pada izin tool dan jaringan; membaca teks berbahaya saja tidak memberi akses jaringan.
Konsep inti dan istilah penting
- Input tak tepercaya:
- Judul, deskripsi, komentar, diff, dan konten tautan pada pull request kontributor.
- Prompt injection tidak langsung:
- Teks tak tepercaya memengaruhi agen karena dimasukkan ke konteks model.
- Batas SSRF:
- Tool pengambilan sisi server dapat menjangkau tujuan yang tidak dapat dicapai kontributor secara langsung.
- Kondisi dampak:
- Juga diperlukan layanan internal yang dapat dijangkau, kredensial yang tersedia, serta kontrol otorisasi atau egress yang lemah.
Mekanisme dan akar masalah
Bot review dapat menggabungkan teks yang dikendalikan kontributor dengan instruksi review tepercaya. Model dapat mengusulkan panggilan tool berdasarkan salah satunya. Prompt dan pemisah tidak mengotorisasi akses jaringan. SSRF hanya mungkin jika kode aplikasi menerima tujuan pilihan model dan tool berjaringan dapat menjangkaunya. Akses ke metadata cloud atau kredensial adalah dampak tambahan bersyarat, bukan hasil otomatis prompt injection.
Alur serangan bersyarat
Kontributor mengendalikan konten PR
Kontributor eksternal dapat memengaruhi judul, deskripsi, komentar, teks yang diubah, dan materi tertaut.
Agen membaca konten
Layanan memasukkan sebagian bidang tak tepercaya ke konteks model; hal ini dapat memengaruhi jawaban atau usulan tool.
Kemampuan tool menentukan jangkauan
Jika agen dapat mengambil URL sembarang, runner dapat menghubungi tujuan yang diizinkan jalur jaringan. Tanpa tool itu, jalur SSRF ini tidak ada.
Dampak bergantung pada penerapan
Data internal atau kredensial hanya terekspos jika layanan yang dapat dijangkau, pengaturan metadata, izin identitas, dan kontrol keluaran mengizinkannya.
Kode: dispatch tanpa pemeriksaan vs. akses baca berizin
# INERT DEMO: model-selected URL reaches a mock tool without policy checks
from dataclasses import dataclass
@dataclass
class ToolCall:
name: str
arguments: dict[str, str]
class MockFetch:
def __init__(self):
self.calls = []
def __call__(self, url: str) -> str:
self.calls.append(url)
return "fixture response"
def dispatch_unchecked(call: ToolCall, tools: dict):
# The mock records a string; it makes no network request.
return tools[call.name](**call.arguments)
mock_fetch = MockFetch()
call = ToolCall("fetch_url", {"url": "https://docs.example.invalid/"})
assert dispatch_unchecked(call, {"fetch_url": mock_fetch}) == "fixture response"
assert mock_fetch.calls == ["https://docs.example.invalid/"]
# SAFE DEMO: the agent receives only a read-only PR capability
from dataclasses import dataclass
@dataclass(frozen=True)
class ReviewContext:
repository: str
pull_request: int
@dataclass
class ToolCall:
name: str
arguments: dict[str, object]
READ_ONLY_TOOLS = {"read_pr_diff"}
def dispatch_review_call(call: ToolCall, context: ReviewContext, policy, tools):
if call.name not in READ_ONLY_TOOLS:
raise PermissionError("Tool is not available to this review")
expected = {"repository": context.repository,
"pull_request": context.pull_request}
if call.arguments != expected:
raise ValueError("Arguments must match the authorized review")
if not policy.can_read_pr(context.repository, context.pull_request):
raise PermissionError("Review principal cannot read this pull request")
# The injected read_pr_diff function is trusted app code, not model output.
return tools["read_pr_diff"](**expected)
Daftar periksa penguatan engineering
- Jangan menyebut skenario ini sebagai insiden bot PR yang telah dikonfirmasi. Halaman ini memodelkan risiko desain bersyarat.
- Jangan berikan tool pengambilan URL sembarang kepada reviewer yang hanya perlu memeriksa diff.
- Jika pratinjau tautan eksternal diperlukan, gunakan layanan egress khusus dengan allowlist tujuan, validasi DNS/IP saat koneksi, validasi ulang redirect, batas waktu dan ukuran yang ketat, serta tanpa kredensial implisit.
- Blokir akses runner ke jaringan privat dan metadata cloud pada lapisan jaringan. Nonaktifkan metadata bila beban kerja tidak membutuhkannya; jika perlu, wajibkan IMDSv2 dan validasi hop limit kontainer.
- Berikan bot identitas read-only yang dibatasi ke repositori. Jangan paparkan secret ke job PR tak tepercaya dan pisahkan alur kerja berhak tinggi dari eksekusi kode eksternal.
- Di GitHub Actions, utamakan `pull_request` dengan izin minimal untuk kode tak tepercaya. Perlakukan `pull_request_target` sebagai event berhak tinggi dan jangan jalankan kode fork dengan secret atau token tulisnya.
- Catat panggilan tool yang ditolak dan keputusan kebijakan tujuan tanpa menyimpan token, diff privat lengkap, atau isi respons sensitif.