FlawOpen

flawopen.com/Injeksi SQL di Go/GORM Raw SQL dan injeksi SQL

Apakah GORM Raw() aman dari injeksi SQL? Pengikatan parameter di Go

CWE-89: SQL InjectionHalaman referensi
Jawaban singkat

Bayangkan placeholder sebagai amplop tertutup untuk sebuah nilai: driver database mengirim nilai secara terpisah dari instruksi SQL. GORM Raw() dapat mengikat nilai dengan aman jika placeholder tetap berada di kueri dan nilainya diberikan sebagai argumen. Memformat input pengguna ke string SQL mencampur amplop dengan instruksi dan dapat mengubah kueri.

RENTAN
// Teks yang dikendalikan pengguna menjadi sintaks SQL
db.Raw(fmt.Sprintf(
  "SELECT * FROM users WHERE id = %s",
  userID,
)).Scan(&user)
AMAN
// Driver mengikat userID sebagai nilai
db.Raw(
  "SELECT * FROM users WHERE id = ?",
  userID,
).Scan(&user)

Aturan aman GORM Raw SQL dan pengikatan parameter

GORM dan Go database/sql mengikat nilai saat placeholder tetap berada di SQL dan argumen dikirim terpisah, misalnya db.Where("name = ?", userInput) atau db.Raw("SELECT ... WHERE id = ?", userID). Placeholder mewakili nilai, bukan sintaks SQL: nama tabel, kolom, arah pengurutan, dan operator tidak dapat diamankan dengan pengikatan nilai. Pilih identifier dinamis dari allowlist tetap. Metode seperti Order, Select, Table, dan Raw dapat rentan jika input pengguna digabungkan ke fragmen SQL.

Cara memeriksa codebase

rg -n --glob '*.go' '\.(Raw|Exec|Order|Select|Table)\s*\(' . rg -n --glob '*.go' 'fmt\.(Sprintf|Sprint)' .

FAQ GORM Raw SQL dan pengikatan parameter

Apakah metode kueri berantai GORM selalu aman?

Tidak. Kondisi yang mengirim nilai secara terpisah, seperti Where("name = ?", input), memakai pengikatan parameter. Menggabungkan input ke string kondisi atau memberikannya sebagai sintaks SQL mentah tetap dapat menyuntikkan kueri. Beberapa metode menerima identifier atau fragmen SQL yang tidak di-escape; tinjau argumennya dan gunakan allowlist untuk struktur dinamis.

Bisakah placeholder mengikat nama tabel atau kolom?

Tidak. Placeholder mewakili nilai data. Untuk identifier atau arah pengurutan dinamis, pilih opsi tetap yang ditentukan aplikasi dan masukkan hanya konstanta tervalidasi ke struktur SQL.

Sumber resmi dan referensi

Lihat juga SQL Injection (CWE-89): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Apakah Escape Tanda Kutip Cukup untuk Mencegah SQL Injection? Apakah memakai ORM cukup untuk mencegah SQL Injection? Apakah Knex.js aman dari SQL Injection? MyBatis ${} vs #{}: mencegah SQL Injection MySQLi vs PDO: prepared statement yang aman Apakah NHibernate aman dari SQL Injection?