CA3001: SQL ekleme güvenlik açıkları için kodu gözden geçirme

Özellik Değer
Kural Kimliği CA3001
Başlık SQL ekleme güvenlik açıkları için inceleme kodu
Kategori Güvenlik
Hataya neden olan veya bozulmayan düzeltme Hataya neden olmayan
.NET 8'de varsayılan olarak etkin Hayır

Neden

Güvenilmeyen http isteği girişi bir SQL komutunun metnine ulaşır.

Varsayılan olarak, bu kural tüm kod tabanını analiz eder, ancak bu yapılandırılabilir.

Kural açıklaması

Güvenilmeyen giriş ve SQL komutlarıyla çalışırken SQL ekleme saldırılarına dikkat edin. SQL ekleme saldırısı kötü amaçlı SQL komutlarını yürüterek uygulamanızın güvenliğini ve bütünlüğünü tehlikeye atabilir. Tipik teknikler arasında değişmez değer dizelerini sınırlandırmak için tek tırnak işareti veya kesme işareti, açıklama için iki tire ve deyimin sonu için noktalı virgül kullanılır. Daha fazla bilgi için bkz . SQL Ekleme.

Bu kural, BIR SQL komutunun metnine ulaşan HTTP isteklerinden giriş bulmaya çalışır.

Not

Bu kural, derlemeler arasında verileri izleyemiyor. Örneğin, bir derleme HTTP isteği girişini okur ve sql komutunu yürüten başka bir derlemeye geçirirse, bu kural uyarı üretmez.

Not

Bu kuralın yöntem çağrıları arasında veri akışını ne kadar derin analiz edeceğine yönelik yapılandırılabilir bir sınır vardır. EditorConfig dosyasında sınırı yapılandırma hakkında bilgi için bkz . Çözümleyici Yapılandırması.

İhlalleri düzeltme

Güvenilir olmayan girişi içeren parametrelerle parametreli SQL komutlarını veya saklı yordamları kullanın.

Uyarıların ne zaman bastırılması gerekiyor?

Girişin her zaman bilinen bir güvenli karakter kümesine göre doğrulandığını biliyorsanız, bu kuraldan gelen bir uyarıyı gizlemeniz güvenlidir.

Uyarıyı gizleme

Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.

#pragma warning disable CA3001
// The code that's violating the rule is on this line.
#pragma warning restore CA3001

Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini noneolarak ayarlayın.

[*.{cs,vb}]
dotnet_diagnostic.CA3001.severity = none

Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.

Çözümlemek için kod yapılandırma

Bu kuralın kod tabanınızın hangi bölümlerinde çalıştırılacaklarını yapılandırmak için aşağıdaki seçenekleri kullanın.

Bu seçenekleri yalnızca bu kural, geçerli olduğu tüm kurallar veya bu kategorideki (Güvenlik) tüm kurallar için yapılandırabilirsiniz. Daha fazla bilgi için bkz . Kod kalitesi kuralı yapılandırma seçenekleri.

Belirli simgeleri hariç tutma

Türler ve yöntemler gibi belirli simgeleri analizden hariç tutabilirsiniz. Örneğin, kuralın adlı MyTypetürlerdeki herhangi bir kodda çalışmaması gerektiğini belirtmek için, projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyin:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Seçenek değerinde izin verilen simge adı biçimleri (ile |ayrılmış):

  • Yalnızca sembol adı (içeren tür veya ad alanı ne olursa olsun, ada sahip tüm simgeleri içerir).
  • Simgenin belge kimliği biçimindeki tam adlar. Her simge adı için yöntemlerT:, türler ve N: ad alanları gibi M: bir sembol türü ön eki gerekir.
  • .ctor oluşturucular ve .cctor statik oluşturucular için.

Örnekler:

Seçenek Değeri Özet
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType adlı MyTypetüm simgelerle eşleşir.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 veya MyType2adlı MyType1 tüm simgelerle eşleşir.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Belirtilen tam imza ile belirli bir yöntemi MyMethod eşleştirir.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Belirli yöntemlerle MyMethod1 ve MyMethod2 ilgili tam imzalarla eşleşir.

Belirli türleri ve türetilmiş türlerini dışlama

Belirli türleri ve türetilmiş türlerini analizden dışlayabilirsiniz. Örneğin, kuralın adlı MyType ve türetilmiş türleri içindeki hiçbir yöntemde çalışmaması gerektiğini belirtmek için, projenizdeki bir .editorconfig dosyasına aşağıdaki anahtar-değer çiftini ekleyin:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Seçenek değerinde izin verilen simge adı biçimleri (ile |ayrılmış):

  • Yalnızca tür adı (içeren tür veya ad alanına bakılmaksızın adı olan tüm türleri içerir).
  • Simgenin belge kimliği biçiminde, isteğe bağlı T: ön ek içeren tam adlar.

Örnekler:

Seçenek Değeri Özet
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Adlı MyType tüm türleri ve türetilmiş türlerinin tümünü eşleştirir.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 veya MyType2 adlı MyType1 tüm türleri ve türetilmiş türlerinin tümünü eşleştirir.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Belirli bir türü MyType verilen tam adla ve türetilmiş tüm türleriyle eşleştirir.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Belirli türleri MyType1 ve MyType2 ilgili tam adlarla ve bunların türetilmiş tüm türleriyle eşleşir.

Sahte kod örnekleri

Ihlal

using System;
using System.Data;
using System.Data.SqlClient;

namespace TestNamespace
{
    public partial class WebForm : System.Web.UI.Page
    {
        public static string ConnectionString { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            string name = Request.Form["product_name"];
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand()
                {
                    CommandText = "SELECT ProductId FROM Products WHERE ProductName = '" + name + "'",
                    CommandType = CommandType.Text,
                };

                SqlDataReader reader = sqlCommand.ExecuteReader();
            }
        }
    }
}
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Linq

Namespace VulnerableWebApp
    Partial Public Class WebForm
        Inherits System.Web.UI.Page

        Public Property ConnectionString As String

        Protected Sub Page_Load(sender As Object, e As EventArgs)
            Dim name As String = Me.Request.Form("product_name")
            Using connection As SqlConnection = New SqlConnection(ConnectionString)
                Dim sqlCommand As SqlCommand = New SqlCommand With {.CommandText = "SELECT ProductId FROM Products WHERE ProductName = '" + name + "'",
                                                                    .CommandType = CommandType.Text}
                Dim reader As SqlDataReader = sqlCommand.ExecuteReader()
            End Using
        End Sub
    End Class
End Namespace

Parametreli çözüm

using System;
using System.Data;
using System.Data.SqlClient;

namespace TestNamespace
{
    public partial class WebForm : System.Web.UI.Page
    {
        public static string ConnectionString { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            string name = Request.Form["product_name"];
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand()
                {
                    CommandText = "SELECT ProductId FROM Products WHERE ProductName = @productName",
                    CommandType = CommandType.Text,
                };

                sqlCommand.Parameters.Add("@productName", SqlDbType.NVarChar, 128).Value = name;

                SqlDataReader reader = sqlCommand.ExecuteReader();
            }
        }
    }
}
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Linq

Namespace VulnerableWebApp
    Partial Public Class WebForm
        Inherits System.Web.UI.Page

        Public Property ConnectionString As String

        Protected Sub Page_Load(sender As Object, e As EventArgs)
            Dim name As String = Me.Request.Form("product_name")
            Using connection As SqlConnection = New SqlConnection(ConnectionString)
                Dim sqlCommand As SqlCommand = New SqlCommand With {.CommandText = "SELECT ProductId FROM Products WHERE ProductName = @productName",
                                                                    .CommandType = CommandType.Text}
                sqlCommand.Parameters.Add("@productName", SqlDbType.NVarChar, 128).Value = name
                Dim reader As SqlDataReader = sqlCommand.ExecuteReader()
            End Using
        End Sub
    End Class
End Namespace

Saklı yordam çözümü

using System;
using System.Data;
using System.Data.SqlClient;

namespace TestNamespace
{
    public partial class WebForm : System.Web.UI.Page
    {
        public static string ConnectionString { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            string name = Request.Form["product_name"];
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlCommand = new SqlCommand()
                {
                    CommandText = "sp_GetProductIdFromName",
                    CommandType = CommandType.StoredProcedure,
                };

                sqlCommand.Parameters.Add("@productName", SqlDbType.NVarChar, 128).Value = name;

                SqlDataReader reader = sqlCommand.ExecuteReader();
            }
        }
    }
}
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Linq

Namespace VulnerableWebApp
    Partial Public Class WebForm
        Inherits System.Web.UI.Page

        Public Property ConnectionString As String

        Protected Sub Page_Load(sender As Object, e As EventArgs)
            Dim name As String = Me.Request.Form("product_name")
            Using connection As SqlConnection = New SqlConnection(ConnectionString)
                Dim sqlCommand As SqlCommand = New SqlCommand With {.CommandText = "sp_GetProductIdFromName",
                                                                    .CommandType = CommandType.StoredProcedure}
                sqlCommand.Parameters.Add("@productName", SqlDbType.NVarChar, 128).Value = name
                Dim reader As SqlDataReader = sqlCommand.ExecuteReader()
            End Using
        End Sub
    End Class
End Namespace