Suntik SQL
Mengamankan aplikasi terhadap injeksi SQL > Perbaikan aplikasi

Injeksi SQL dapat dengan mudah diatasi dalam kebanyakan bahasa pemrograman yang menargetkan aplikasi web atau menawarkan fungsi. Dalam DBI di Perl, metode DBI::quote meloloskan karakter-karakter khusus (anggaplah variabel $sql menyimpan referensi ke sebuah objek DBI):
$kueri = $sql->prepare
  (
      "select * from pengguna where nama = "
    .
      $sql->quote($nama_pengguna)
  );
Namun begitu, secara umum ini bukan jalan yang terbaik dalam menghadapi masalah tersebut. DBI mengizinkan penggunaan placeholder, yang memperbolehkan Anda untuk mengikat data ke sebuah pernyataan secara terpisah dari pendefinisian pernyataan SQL tersebut. Untuk sistem basis data yang tidak secara asli mendukung placeholder, DBI menirukannya dengan menggunakan fungsi DBI::quote secara otomatis pada nilai-nilai. Banyak sistem basis data yang mendukung pengikatan nilai secara terpisah melalui API mereka; DBI akan menggunakan dukungan placeholder asli tersebut dalam hal ini. Sebagai contoh:
$kueri = $sql->prepare("select * from pengguna where nama = ?");
$kueri->execute($nama_pengguna);
Keuntungannya adalah Anda tidak perlu mengingat untuk menggunakan DBI::quote kepada setiap nilai. Nilai-nilai akan diikat secara terpisah, atau dikutip secara benar, tergantung pada dukungan yang ditawarkan oleh SMBD tertentu yang Anda gunakan. Anda kemudian terhindari dari masalah dasar injeksi SQL di mana nilai-nilai diinterpretasi sebagai SQL.
Bagi sistem basis data yang mendukung placeholder secara asli, sering kali ada keuntungan kinerja yang nyata untuk menggunakan placeholder, karena basis data dapat menyimpan cache dari sebuah perwakilan pernyataan yang terkompilasi dan menggunakannya secara berulang di antara pelaksanaan-pelaksanaan dengan nilai-nilai ikatan yang berbeda. Placeholder kadang-kadang juga disebut sebagai "variabel pengikat".
Dalam PHP, terdapat beberapa fungsi bawaan yang berbeda untuk digunakan pada SMBD-SMBD yang berbeda untuk meloloskan nilai-nilai yang cocok untuk diimbuhkan dalam pernyataan-pernyataan SQL harafiah. Untuk MySQL, yang serupa dengan ini adalah fungsi bawaan mysql_real_escape_string:
$hasil_kueri = mysql_query
  (
      "select * from pengguna where nama = '"
    .
      mysql_real_escape_string($nama_pengguna)
    .
      "'"
  );
Antarmuka asli untuk sebuah SMBD tertentu dapat juga menawarkan sebuah metode untuk melakukan pengikatan placeholder secara terpisah, misalnya mysql_stmt_bind_param Diarsipkan 2007-04-21 di Wayback Machine. atau oci_bind_by_name. Selain itu, sebuah pustaka abstraksi basis data dapat digunakan untuk menirukan placeholder dalam cara yang mirip dengan DBI dari Perl. Sebuah contoh dari beberapa pustaka yang ada ialah ADOdb.
Dalam bahasa pemrograman Java, yang serupa adalah kelas PreparedStatement.
Daripada
Connection con = (peroleh koneksi)
Statement stmt = con.createStatement();
ResultSet rset = stmt.executeQuery("SELECT * FROM pengguna WHERE nama = '" + userName + "';");
gunakan yang berikut
Connection con = (peroleh koneksi)
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM pengguna WHERE nama = ?");
pstmt.setString(1, namaPengguna);
ResultSet rset = pstmt.executeQuery();
Dalam bahasa pemrograman "C#" .NET atau Mono, yang serupa adalah objek-objek ADO.NET SqlCommand (untuk Microsoft SQL Server) atau OracleCommand (untuk server basis data Oracle). Contoh di bawah ini memperlihatkan bagaimana mencegah serangan injeksi menggunakan objek SqlCommand. Kode untuk penyedia ADO.NET lainnya sangat mirip, tetapi dapat sedikit berbeda tergantung pada implementasi khusus yang dibuat oleh vendor penyedia tersebut.
Daripada
using( SqlConnection con = (peroleh koneksi) ) {
  con.Open();
  using( SqlCommand cmd = new SqlCommand("SELECT * FROM pengguna WHERE nama = '" + namaPengguna + "'", con) ) {
    using( SqlDataReader rdr = cmd.ExecuteReader() ) {
      ...
    }
  }
}
gunakan yang berikut
using( SqlConnection con = (peroleh koneksi) ) {
  con.Open();
  using( SqlCommand cmd = new SqlCommand("SELECT * FROM users WHERE name = @namaPengguna", con) ) {
cmd.Parameters.AddWithValue("@namaPengguna", namaPengguna);
using( SqlDataReader rdr = cmd.ExecuteReader() ) {
      ...
    }
  }
}