Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
| Özellik | Değer |
|---|---|
| Kural Kimliği | CA2100 |
| Başlık | SQL sorgularını güvenlik açıkları için inceleyin |
| Kategori | Güvenlik |
| Düzeltme bozucu veya bozucu olmayan bir etkisi olabilir | Kaydırmaz |
| .NET 10'da varsayılan olarak etkin | Hayır |
| Geçerli diller | C# ve Visual Basic |
Neden
Yöntem, yöntem için bir dize bağımsız değişkeninden oluşturulan bir dizeyi kullanarak System.Data.IDbCommand.CommandText özelliğini ayarlar.
Varsayılan olarak, bu kural tüm kod tabanını analiz eder, ancak bu yapılandırılabilir.
Kural açıklaması
Bu kural, derleme zamanında değeri belirlenemeyen herhangi bir dizenin kullanıcı girişi içerebileceğini varsayar. Kullanıcı girişinden oluşturulan bir SQL komut dizesi SQL ekleme saldırılarına karşı savunmasızdır. SQL enjeksiyon saldırısında, kötü niyetli bir kullanıcı, altta yatan veritabanına zarar vermek veya yetkisiz erişim elde etmek amacıyla sorgunun tasarımını değiştirerek giriş yapar. Tipik teknikler, SQL değişmez değer dizesi sınırlayıcısı olan tek bir tırnak işareti veya kesme işareti eklemeyi içerir; bir SQL açıklamasını gösteren iki tire; ve yeni bir komutun izlediğini gösteren noktalı virgül. Kullanıcı girişinin sorgunun bir parçası olması gerekiyorsa, saldırı riskini azaltmak için etkinlik sırasına göre listelenen aşağıdakilerden birini kullanın.
- Saklı yordam kullanın.
- Parametreli bir komut dizesi kullanın.
- Komut dizesini oluşturmadan önce hem tür hem de içerik için kullanıcı girişini doğrulayın.
Aşağıdaki .NET türleri, bir dize bağımsız değişkeni kullanarak CommandText özelliğini uygulayan veya özelliği ayarlayan oluşturucular sağlar.
- System.Data.Odbc.OdbcCommand ve System.Data.Odbc.OdbcDataAdapter
- System.Data.OleDb.OleDbCommand ve System.Data.OleDb.OleDbDataAdapter
- System.Data.OracleClient.OracleCommand ve System.Data.OracleClient.OracleDataAdapter
- System.Data.SqlClient.SqlCommand ve System.Data.SqlClient.SqlDataAdapter
Bazı durumlarda, bu kural derleme zamanında bir dizenin değerini belirleyemeyebilir, ancak bunu yapabilirsiniz. Böyle durumlarda, bu kural bu dizeleri SQL komutları olarak kullanırken hatalı pozitif sonuçlar üretir. Aşağıda bu tür bir dizenin bir örneği verilmiştir.
int x = 10;
string query = "SELECT TOP " + x.ToString() + " FROM Table";
Örtülü kullanıldığında ToString() için de aynı durum geçerlidir.
int x = 10;
string query = String.Format("SELECT TOP {0} FROM Table", x);
İhlalleri düzeltme
Bu kuralın ihlalini düzeltmek için parametreli sorgu kullanın.
Uyarıların ne zaman bastırılması gerekiyor?
Komut metni herhangi bir kullanıcı girişi içermiyorsa, bu kuraldan gelen bir uyarıyı engellemek 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 CA2100
// The code that's violating the rule is on this line.
#pragma warning restore CA2100
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.CA2100.severity = none
Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.
Analiz için kodu yapılandır
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.
Ayrıca, bu kural için aşağıdaki veri akışı analiziyle ilgili seçenekler geçerlidir:
- interprocedural_analysis_kind
- max_interprocedural_lambda_or_local_function_call_chain
- max_interprocedural_method_call_chain
- points_to_analysis_kind
- copy_analysis
- zayıf KDF algoritması için yeterli İterasyon Sayısı
Bu seçenekleri yalnızca bu kural için, uyguladıkları tüm kurallar için veya bu kategorideki tüm kurallar için (Güvenlik) yapılandırabilirsiniz. Daha fazla bilgi için bkz . Kod kalitesi kuralı yapılandırma seçenekleri.
Belirli simgeleri hariç tutma
excluded_symbol_names seçeneğini ayarlayarak 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
Not
XXXX
CAXXXX bölümünü geçerli kuralın kimliğiyle değiştirin.
Seçenek değerinde izin verilen simge adı biçimleri (ile |ayrılmış):
- Yalnızca sembol adı (tür veya ad alanı ne olursa olsun, ada sahip olan tüm sembolleri içerir).
- Simgenin tam adları, dokümantasyon kimliği biçiminde bulunur. Her simge adı, metotlar için
M:, türler içinT:, ve ad alanları içinN:gibi bir simge türü ön eki gerektirir. -
.ctoroluşturucular ve.cctorstatik 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 |
MyType1 veya MyType2 olarak adlandırılan 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öntemler MyMethod1 ve MyMethod2, ilgili tam nitelikli imzalarla eşleştirilir. |
Belirli türleri ve türetilmiş türlerini dışlama
excluded_type_names_with_derived_types seçeneğini ayarlayarak 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
Not
XXXX
CAXXXX bölümünü geçerli kuralın kimliğiyle değiştirin.
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).
- Tam nitelikli adlar, simgenin belge kimliği biçiminde ve isteğe bağlı bir
T:ön ek ile kullanılabilir.
Örnekler:
| Seçenek değeri | Özet |
|---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
MyType adlı tüm türleri ve onlardan türeyen türlerin tümünü eşleştirir. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
MyType1 veya MyType2 adlı tüm türleri ve bunlardan türetilmiş tüm türleri eşleştirir. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Belirli bir MyType türünü, verilen tam adla ve ona türetilmiş tüm türlerle 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 karşılık gelen tam adları ve bunların tüm türetilmiş türleriyle eşleştirir. |
Örnek
Aşağıdaki örnekte kuralı UnsafeQueryihlal eden bir yöntemi gösterilmektedir. Ayrıca parametreli SaferQuerybir komut dizesi kullanarak kuralı karşılayan bir yöntemi de gösterir.
Imports System.Data
Imports System.Data.OleDb
Imports System.Runtime.Versioning
Namespace ca2100
Public Class SqlQueries
<SupportedOSPlatform("windows")>
Function UnsafeQuery(connection As String,
name As String, password As String) As Object
Dim someConnection As New OleDbConnection(connection)
Dim someCommand As New OleDbCommand With {
.Connection = someConnection,
.CommandText = "SELECT AccountNumber FROM Users " &
"WHERE Username='" & name & "' AND Password='" & password & "'"
}
someConnection.Open()
Dim accountNumber As Object = someCommand.ExecuteScalar()
someConnection.Close()
Return accountNumber
End Function
<SupportedOSPlatform("windows")>
Function SaferQuery(connection As String,
name As String, password As String) As Object
Dim someConnection As New OleDbConnection(connection)
Dim someCommand As New OleDbCommand With {
.Connection = someConnection
}
someCommand.Parameters.AddWithValue(
"@username", OleDbType.Char).Value = name
someCommand.Parameters.AddWithValue(
"@password", OleDbType.Char).Value = password
someCommand.CommandText = "SELECT AccountNumber FROM Users " &
"WHERE Username=@username AND Password=@password"
someConnection.Open()
Dim accountNumber As Object = someCommand.ExecuteScalar()
someConnection.Close()
Return accountNumber
End Function
End Class
Class MaliciousCode
<SupportedOSPlatform("windows")>
Shared Sub Main2100(args As String())
Dim queries As New SqlQueries()
queries.UnsafeQuery(args(0), "' OR 1=1 --", "[PLACEHOLDER]")
' Resultant query (which is always true):
' SELECT AccountNumber FROM Users WHERE Username='' OR 1=1
queries.SaferQuery(args(0), "' OR 1=1 --", "[PLACEHOLDER]")
' Resultant query (notice the additional single quote character):
' SELECT AccountNumber FROM Users WHERE Username=''' OR 1=1 --'
' AND Password='[PLACEHOLDER]'
End Sub
End Class
End Namespace
[SupportedOSPlatform("Windows")]
public class OleDbQueries
{
public object UnsafeQuery(
string connection, string name, string password)
{
using OleDbConnection someConnection = new(connection);
using OleDbCommand someCommand = new();
someCommand.Connection = someConnection;
someCommand.CommandText = "SELECT AccountNumber FROM Users " +
"WHERE Username='" + name +
"' AND Password='" + password + "'";
someConnection.Open();
object accountNumber = someCommand.ExecuteScalar();
someConnection.Close();
return accountNumber;
}
public object SaferQuery(
string connection, string name, string password)
{
using OleDbConnection someConnection = new(connection);
using OleDbCommand someCommand = new();
someCommand.Connection = someConnection;
someCommand.Parameters.Add(
"@username", OleDbType.Char).Value = name;
someCommand.Parameters.Add(
"@password", OleDbType.Char).Value = password;
someCommand.CommandText = "SELECT AccountNumber FROM Users " +
"WHERE Username=@username AND Password=@password";
someConnection.Open();
object accountNumber = someCommand.ExecuteScalar();
someConnection.Close();
return accountNumber;
}
}
[SupportedOSPlatform("Windows")]
class MaliciousCode
{
static void Main2100(string[] args)
{
OleDbQueries queries = new();
queries.UnsafeQuery(args[0], "' OR 1=1 --", "[PLACEHOLDER]");
// Resultant query (which is always true):
// SELECT AccountNumber FROM Users WHERE Username='' OR 1=1
queries.SaferQuery(args[0], "' OR 1=1 --", "[PLACEHOLDER]");
// Resultant query (notice the additional single quote character):
// SELECT AccountNumber FROM Users WHERE Username=''' OR 1=1 --'
// AND Password='[PLACEHOLDER]'
}
}
Önemli
Microsoft, kullanılabilir en güvenli kimlik doğrulama akışını kullanmanızı önerir. Azure SQL'e bağlanıyorsanız önerilen kimlik doğrulama yöntemi Azure kaynakları için Yönetilen Kimlikler'dir.