FlawOpen

flawopen.com/SQL Injection/Stored procedure

Apakah stored procedure kebal terhadap SQL injection?

Halaman referensi
Jawaban singkat

Tidak — ini kesalahpahaman umum. Stored procedure hanya melindungi jika mengikat parameter di dalamnya. Jika procedure menggabungkan input menjadi string kueri lalu menjalankannya dengan EXEC atau sp_executesql, risikonya sama seperti penggabungan string pada aplikasi.

TIDAK AMAN — gabungkan nilai ke SQL dinamis
-- SQL Server T-SQL; dbo.Users.Id is NVARCHAR(50).
CREATE PROCEDURE dbo.GetUser
  @UserId NVARCHAR(50)
AS
BEGIN
  DECLARE @sql NVARCHAR(MAX) =
    N'SELECT Id FROM dbo.Users WHERE Id = N'''
      + @UserId + N'''';
  EXEC(@sql);
END;
AMAN — ikat parameter dengan sp_executesql
-- SQL Server T-SQL; same illustrative schema.
CREATE PROCEDURE dbo.GetUser
  @UserId NVARCHAR(50)
AS
BEGIN
  DECLARE @sql NVARCHAR(MAX) =
    N'SELECT Id FROM dbo.Users WHERE Id = @id';
  EXEC sys.sp_executesql
    @stmt = @sql,
    @params = N'@id NVARCHAR(50)',
    @id = @UserId;
END;

Mengapa kesalahpahaman ini umum

“Gunakan stored procedure” sering disebut sebagai solusi umum SQL injection. Ini benar jika procedure meneruskan nilai sebagai parameter terikat dalam kueri biasa. Jika procedure membuat SQL dinamis dengan EXEC lalu menggabungkan nilai tak tepercaya, risiko yang sama muncul kembali. Jika SQL dinamis diperlukan, ikat nilai dengan sp_executesql. Nama tabel atau kolom tidak dapat diikat sebagai nilai; petakan pilihan yang diizinkan ke identifier tetap melalui allowlist ketat.

Pertanyaan umum

Apakah sp_executesql bisa aman?

Bisa. sp_executesql mendukung parameter: deklarasikan parameter dan kirim nilainya secara terpisah (misalnya EXEC sp_executesql @sql, N'@id INT', @id = @UserId). Jangan gabungkan nilai ke @sql. Untuk nama tabel atau kolom dinamis, gunakan allowlist ketat karena identifier bukan parameter yang dapat diikat.

Referensi

Lihat juga SQL Injection (CWE-89): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Apakah TypeORM QueryBuilder aman dari SQL Injection? Django ORM SQL Injection: pola aman Injeksi SQL Doctrine ORM: kueri aman EF Core FromSqlRaw: SQL berparameter yang aman Injeksi SQL FastAPI: Yang Dicegah dan Tidak Dicegah Pydantic GORM Raw SQL: Cegah Injeksi SQL di Go