Ramka zabezpieczeń: weryfikacja danych wejściowych | Czynniki

Produkt/usługa Artykuł
Aplikacja internetowa
Baza danych
Internetowy interfejs API
Azure Document DB
WCF

Wyłączanie skryptów XSLT dla wszystkich przekształceń przy użyciu niezaufanych arkuszy stylów

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Zabezpieczenia XSLT, Xslt Ustawienia. Właściwość EnableScript
Kroki Język XSLT obsługuje wykonywanie skryptów wewnątrz arkuszy stylów przy użyciu <msxml:script> elementu . Dzięki temu funkcje niestandardowe mogą być używane w transformacji XSLT. Skrypt jest wykonywany w kontekście procesu wykonującego transformację. Skrypt XSLT musi być wyłączony, gdy w niezaufanym środowisku, aby zapobiec wykonywaniu niezaufanego kodu. Jeśli używasz platformy .NET: skrypty XSLT są domyślnie wyłączone. Należy jednak upewnić się, że nie została jawnie włączona za pośrednictwem XsltSettings.EnableScript właściwości .

Przykład

XsltSettings settings = new XsltSettings();
settings.EnableScript = true; // WRONG: THIS SHOULD BE SET TO false

Przykład

Jeśli używasz programu MSXML 6.0, wykonywanie skryptów XSLT jest domyślnie wyłączone; należy jednak upewnić się, że nie została jawnie włączona za pośrednictwem właściwości obiektu DOM XML AllowXsltScript.

doc.setProperty("AllowXsltScript", true); // WRONG: THIS SHOULD BE SET TO false

Przykład

Jeśli używasz programu MSXML 5 lub nowszego, skrypty XSLT są domyślnie włączone i musisz jawnie ją wyłączyć. Ustaw właściwość obiektu DOM XML AllowXsltScript na false.

doc.setProperty("AllowXsltScript", false); // CORRECT. Setting to false disables XSLT scripting.

Upewnij się, że każda strona, która może zawierać zawartość z możliwością kontrolowania przez użytkownika, zrezygnowała z automatycznego wąchania MIME

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Część V zabezpieczeń IE8 — kompleksowa ochrona
Kroki

Dla każdej strony, która może zawierać zawartość z możliwością sterowania przez użytkownika, należy użyć nagłówka X-Content-Type-Options:nosniffHTTP . Aby spełnić to wymaganie, możesz ustawić wymaganą stronę nagłówka według strony tylko dla tych stron, które mogą zawierać zawartość z możliwością kontrolowania przez użytkownika, lub można ustawić ją globalnie dla wszystkich stron w aplikacji.

Każdy typ pliku dostarczonego z serwera internetowego ma skojarzony typ MIME (nazywany również typem zawartości), który opisuje charakter zawartości (czyli obraz, tekst, aplikacja itp.)

Nagłówek X-Content-Type-Options to nagłówek HTTP, który umożliwia deweloperom określenie, że ich zawartość nie powinna być wyśmiewane przez protokół MIME. Ten nagłówek jest przeznaczony do eliminowania ataków MIME-Sniffing. Obsługa tego nagłówka została dodana w programie Internet Explorer 8 (IE8)

Tylko użytkownicy programu Internet Explorer 8 (IE8) skorzystają z opcji X-Content-Type-Options. Poprzednie wersje programu Internet Explorer nie obsługują obecnie nagłówka X-Content-Type-Options

Internet Explorer 8 (i nowsze) to jedyne główne przeglądarki, które implementują funkcję rezygnacji MIME-sniffing. Jeśli i kiedy inne główne przeglądarki (Firefox, Safari, Chrome) implementują podobne funkcje, to zalecenie zostanie zaktualizowane w celu uwzględnienia składni dla tych przeglądarek, jak również

Przykład

Aby włączyć wymagany nagłówek globalnie dla wszystkich stron w aplikacji, możesz wykonać jedną z następujących czynności:

  • Dodaj nagłówek w pliku web.config, jeśli aplikacja jest hostowana przez usługi Internet Information Services (IIS) 7
<system.webServer> 
  <httpProtocol> 
    <customHeaders> 
      <add name=""X-Content-Type-Options"" value=""nosniff""/>
    </customHeaders>
  </httpProtocol>
</system.webServer> 
  • Dodawanie nagłówka za pośrednictwem Application_BeginRequest globalnej
void Application_BeginRequest(object sender, EventArgs e)
{
  this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
} 
  • Implementowanie niestandardowego modułu HTTP
public class XContentTypeOptionsModule : IHttpModule 
  {
    #region IHttpModule Members 
    public void Dispose() 
    { 

    } 
    public void Init(HttpApplication context)
    { 
      context.PreSendRequestHeaders += newEventHandler(context_PreSendRequestHeaders); 
    } 
    #endregion 
    void context_PreSendRequestHeaders(object sender, EventArgs e) 
      { 
        HttpApplication application = sender as HttpApplication; 
        if (application == null) 
          return; 
        if (application.Response.Headers[""X-Content-Type-Options ""] != null) 
          return; 
        application.Response.Headers.Add(""X-Content-Type-Options "", ""nosniff""); 
      } 
  } 

  • Wymagany nagłówek można włączyć tylko dla określonych stron, dodając go do poszczególnych odpowiedzi:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff""; 

Wzmacnianie lub wyłączanie rozpoznawania jednostek XML

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Rozszerzenie jednostki XML, odmowa usługi XML i zabezpieczenia, omówienie zabezpieczeń MSXML, najlepsze rozwiązania dotyczące zabezpieczania kodu MSXML, odwołanie do protokołu NSXMLParserDelegate, rozwiązywanie odwołań zewnętrznych
Kroki

Chociaż nie jest powszechnie używany, istnieje funkcja XML, która umożliwia analizatorowi XML rozwinięcie jednostek makr z wartościami zdefiniowanymi w samym dokumencie lub ze źródeł zewnętrznych. Na przykład dokument może zdefiniować jednostkę "companyname" z wartością "Microsoft", tak aby za każdym razem, gdy tekst "&companyname;" pojawia się w dokumencie, jest automatycznie zastępowany tekstem Microsoft. Lub dokument może zdefiniować jednostkę "MSFTStock", która odwołuje się do zewnętrznej usługi internetowej w celu pobrania bieżącej wartości akcji firmy Microsoft.

Następnie za każdym razem, gdy "&MSFTStock;" pojawi się w dokumencie, zostanie on automatycznie zastąpiony bieżącą ceną akcji. Tę funkcję można jednak nadużywać w celu utworzenia warunków typu "odmowa usługi" (DoS). Osoba atakująca może zagnieżdżać wiele jednostek, aby utworzyć bombę XML rozszerzenia wykładniczego, która zużywa całą dostępną pamięć w systemie.

Alternatywnie może utworzyć zewnętrzne odwołanie, które przesyła strumieniowo nieskończoną ilość danych lub po prostu zawiesza się wątek. W związku z tym wszystkie zespoły muszą całkowicie wyłączyć wewnętrzne i/lub zewnętrzne rozpoznawanie jednostek XML, jeśli ich aplikacja nie używa, lub ręcznie ograniczyć ilość pamięci i czasu, który aplikacja może wykorzystać na potrzeby rozpoznawania jednostek, jeśli ta funkcja jest absolutnie niezbędna. Jeśli rozpoznawanie jednostek nie jest wymagane przez aplikację, wyłącz ją.

Przykład

W przypadku kodu programu .NET Framework można użyć następujących metod:

XmlTextReader reader = new XmlTextReader(stream);
reader.ProhibitDtd = true;

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);

// for .NET 4
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(stream, settings);

Należy pamiętać, że wartość domyślna w parametrze ProhibitDtd in XmlReaderSettings ma wartość true, ale w XmlTextReader niej wartość false. Jeśli używasz elementu XmlReader Ustawienia, nie musisz jawnie ustawiać wartości ProhibitDtd na wartość true, ale jest to zalecane ze względów bezpieczeństwa, które należy wykonać. Należy również pamiętać, że klasa XmlDocument domyślnie zezwala na rozpoznawanie jednostek.

Przykład

Aby wyłączyć rozpoznawanie jednostek dla elementu XmlDocuments, użyj XmlDocument.Load(XmlReader) przeciążenia metody Load i ustaw odpowiednie właściwości w argumencie XmlReader, aby wyłączyć rozpoznawanie, jak pokazano w poniższym kodzie:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);

Przykład

Jeśli wyłączenie rozpoznawania jednostek nie jest możliwe dla aplikacji, ustaw element XmlReader Ustawienia. Właściwość MaxCharactersFromEntities do rozsądnej wartości zgodnie z potrzebami aplikacji. Ograniczy to wpływ potencjalnych ataków dos rozszerzania wykładniczego. Poniższy kod zawiera przykład tego podejścia:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
XmlReader reader = XmlReader.Create(stream, settings);

Przykład

Jeśli musisz rozwiązać problemy z jednostkami wbudowanymi, ale nie musisz rozpoznawać jednostek zewnętrznych, ustaw element XmlReader Ustawienia. Właściwość XmlResolver ma wartość null. Na przykład:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);

Należy pamiętać, że w programie MSXML6 właściwość ProhibitDTD jest domyślnie ustawiona na wartość true (wyłączanie przetwarzania DTD). W przypadku kodu OSX/iOS firmy Apple można użyć dwóch analizatorów XML: NSXMLParser i libXML2.

Aplikacje korzystające z protokołu http.sys wykonują weryfikację kanoniczną adresów URL

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Nie dotyczy
Kroki

Każda aplikacja korzystająca z pliku http.sys powinna postępować zgodnie z następującymi wytycznymi:

  • Ogranicz długość adresu URL do nie więcej niż 16 384 znaków (ASCII lub Unicode). Jest to bezwzględna maksymalna długość adresu URL oparta na domyślnym ustawieniu Internet Information Services (IIS) 6. Strony internetowe powinny dążyć do długości krótszej niż ta, jeśli jest to możliwe
  • Użyj standardowych klas we/wy plików programu .NET Framework (takich jak FileStream), ponieważ będą one korzystać z reguł kanonizacji w programie .NET FX
  • Jawnie utwórz listę dozwolonych znanych nazw plików
  • Jawnie odrzuć znane typy plików nie będzie obsługiwać UrlScan odrzuca: exe, bat, cmd, com, htw, ida, idq, htr, idc, shtm[l], stm, printer, ini, pol, dat files
  • Przechwyć następujące wyjątki:
    • System.ArgumentException (w przypadku nazw urządzeń)
    • System.NotSupportedException (w przypadku strumieni danych)
    • System.IO.FileNotFoundException (w przypadku nieprawidłowych nazw plików z wyjątkiem)
    • System.IO.DirectoryNotFoundException (w przypadku nieprawidłowych dyrygów ucieczki)
  • Nie należy wywoływać interfejsów API we/wy pliku Win32. W nieprawidłowym adresie URL bezpiecznie zwróć użytkownikowi błąd 400 i zarejestruj prawdziwy błąd.

Upewnij się, że podczas akceptowania plików od użytkowników obowiązują odpowiednie kontrolki

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Nieograniczone przekazywanie plików, tabela podpisów plików
Kroki

Przekazane pliki stanowią znaczne ryzyko dla aplikacji.

Pierwszym krokiem w wielu atakach jest pobranie kodu do systemu do ataku. Następnie atak musi znaleźć tylko sposób na wykonanie kodu. Użycie przekazywania plików pomaga atakującemu wykonać pierwszy krok. Konsekwencje nieograniczonego przekazywania plików mogą się różnić, w tym całkowite przejęcie systemu, przeciążony system plików lub baza danych, przekazywanie ataków do systemów zaplecza i proste defacement.

Zależy to od tego, co aplikacja wykonuje z przekazanym plikiem, a zwłaszcza od miejsca przechowywania. Brak weryfikacji przekazywania plików po stronie serwera. W przypadku funkcji przekazywania plików należy zaimplementować następujące mechanizmy zabezpieczeń:

  • Sprawdzanie rozszerzenia pliku (należy zaakceptować tylko prawidłowy zestaw dozwolonych typów plików)
  • Maksymalny limit rozmiaru pliku
  • Nie należy przekazywać pliku do katalogu webroot; lokalizacja powinna być katalogiem na dysku niesystemowym
  • Należy przestrzegać konwencji nazewnictwa, tak aby przekazana nazwa pliku miała pewną losowość, aby zapobiec zastępowaniu plików
  • Przed zapisaniem na dysku plików należy przeskanować pliki antywirusowe
  • Upewnij się, że nazwa pliku i inne metadane (np. ścieżka pliku) są weryfikowane pod kątem złośliwych znaków
  • Należy sprawdzić podpis formatu pliku, aby uniemożliwić użytkownikowi przekazanie zamaskowanego pliku (np. przekazanie pliku exe przez zmianę rozszerzenia na txt)

Przykład

Aby uzyskać szczegółowe informacje, zapoznaj się z klasą poniżej dotyczącą weryfikacji podpisu formatu pliku:

        private static Dictionary<string, List<byte[]>> fileSignature = new Dictionary<string, List<byte[]>>
                    {
                    { ".DOC", new List<byte[]> { new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 } } },
                    { ".DOCX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
                    { ".PDF", new List<byte[]> { new byte[] { 0x25, 0x50, 0x44, 0x46 } } },
                    { ".ZIP", new List<byte[]> 
                                            {
                                              new byte[] { 0x50, 0x4B, 0x03, 0x04 },
                                              new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x55 },
                                              new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
                                              new byte[] { 0x50, 0x4B, 0x05, 0x06 },
                                              new byte[] { 0x50, 0x4B, 0x07, 0x08 },
                                              new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 }
                                                }
                                            },
                    { ".PNG", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
                    { ".JPG", new List<byte[]>
                                    {
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
                                              new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 }
                                    }
                                    },
                    { ".JPEG", new List<byte[]>
                                        { 
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
                                            new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 }
                                        }
                                        },
                    { ".XLS", new List<byte[]>
                                            {
                                              new byte[] { 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 },
                                              new byte[] { 0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00 },
                                              new byte[] { 0xFD, 0xFF, 0xFF, 0xFF }
                                            }
                                            },
                    { ".XLSX", new List<byte[]> { new byte[] { 0x50, 0x4B, 0x03, 0x04 } } },
                    { ".GIF", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } }
                };

        public static bool IsValidFileExtension(string fileName, byte[] fileData, byte[] allowedChars)
        {
            if (string.IsNullOrEmpty(fileName) || fileData == null || fileData.Length == 0)
            {
                return false;
            }

            bool flag = false;
            string ext = Path.GetExtension(fileName);
            if (string.IsNullOrEmpty(ext))
            {
                return false;
            }

            ext = ext.ToUpperInvariant();

            if (ext.Equals(".TXT") || ext.Equals(".CSV") || ext.Equals(".PRN"))
            {
                foreach (byte b in fileData)
                {
                    if (b > 0x7F)
                    {
                        if (allowedChars != null)
                        {
                            if (!allowedChars.Contains(b))
                            {
                                return false;
                            }
                        }
                        else
                        {
                            return false;
                        }
                    }
                }

                return true;
            }

            if (!fileSignature.ContainsKey(ext))
            {
                return true;
            }

            List<byte[]> sig = fileSignature[ext];
            foreach (byte[] b in sig)
            {
                var curFileSig = new byte[b.Length];
                Array.Copy(fileData, curFileSig, b.Length);
                if (curFileSig.SequenceEqual(b))
                {
                    flag = true;
                    break;
                }
            }

            return flag;
        }

Upewnij się, że parametry bezpieczne dla typu są używane w aplikacji internetowej na potrzeby dostępu do danych

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Nie dotyczy
Kroki

Jeśli używasz kolekcji Parameters, sql traktuje dane wejściowe jako wartość literału, a nie jako kod wykonywalny. Kolekcja Parameters może służyć do wymuszania ograniczeń dotyczących typu i długości danych wejściowych. Wartości poza zakresem wyzwalają wyjątek. Jeśli nie są używane bezpieczne parametry SQL typu, osoby atakujące mogą wykonywać ataki iniekcyjne osadzone w niefiltrowanych danych wejściowych.

Użyj bezpiecznych parametrów typu podczas konstruowania zapytań SQL, aby uniknąć możliwych ataków polegających na wstrzyknięciu kodu SQL, które mogą wystąpić w przypadku niefiltrowanych danych wejściowych. Można używać bezpiecznych parametrów typu z procedurami składowanymi i dynamicznymi instrukcjami SQL. Parametry są traktowane jako wartości literału przez bazę danych, a nie jako kod wykonywalny. Parametry są również sprawdzane pod kątem typu i długości.

Przykład

Poniższy kod pokazuje, jak używać bezpiecznych parametrów typu z kolekcją SqlParameterCollection podczas wywoływania procedury składowanej.

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

using (SqlConnection connection = new SqlConnection(connectionString))
{ 
DataSet userDataset = new DataSet(); 
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection); 
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure; 
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11); 
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text; 
myCommand.Fill(userDataset);
}  

W poprzednim przykładzie kodu wartość wejściowa nie może być dłuższa niż 11 znaków. Jeśli dane nie są zgodne z typem lub długością zdefiniowaną przez parametr, klasa SqlParameter zgłasza wyjątek.

Użyj oddzielnych klas powiązań modelu lub list filtrów powiązań, aby zapobiec lukom w zabezpieczeniach w przypadku masowego przypisywania MVC

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja Atrybuty metadanych, luka w zabezpieczeniach klucza publicznego i środki zaradcze, kompletny przewodnik po masowym przypisywaniu w ASP.NET MVC, wprowadzenie do platformy EF przy użyciu wzorca MVC
Kroki
  • Kiedy należy szukać luk w zabezpieczeniach dotyczących nadmiernego publikowania? - W przypadku nadmiernego publikowania luk w zabezpieczeniach mogą wystąpić dowolne miejsce powiązania klas modeli z danych wejściowych użytkownika. Struktury, takie jak MVC, mogą reprezentować dane użytkownika w niestandardowych klasach .NET, w tym zwykłych starych obiektów CLR (POC). MvC automatycznie wypełnia te klasy modeli danymi z żądania, zapewniając wygodną reprezentację do obsługi danych wejściowych użytkownika. Jeśli te klasy obejmują właściwości, które nie powinny być ustawiane przez użytkownika, aplikacja może być podatna na ataki nadmiernego delegowania, które umożliwiają użytkownikowi kontrolę nad danymi, których aplikacja nigdy nie zamierza. Podobnie jak powiązanie modelu MVC, technologie dostępu do bazy danych, takie jak mapery obiektowe/relacyjne, takie jak Entity Framework, często obsługują również używanie obiektów POCO do reprezentowania danych bazy danych. Te klasy modelu danych zapewniają taką samą wygodę w radzeniu sobie z danymi bazy danych, co MVC w radzeniu sobie z danymi wejściowymi użytkownika. Ponieważ zarówno MVC, jak i baza danych obsługują podobne modele, takie jak obiekty POCO, wydaje się łatwe do ponownego użycia tych samych klas w obu celach. Ta praktyka nie zachowuje separacji problemów i jest to jeden wspólny obszar, w którym niezamierzone właściwości są narażone na powiązanie modelu, co umożliwia ataki polegające na nadmiernym delegowaniu.
  • Dlaczego nie należy używać niefiltrowanych klas modelu bazy danych jako parametrów do akcji MVC? - Ponieważ powiązanie modelu MVC będzie wiązać wszystkie elementy w tej klasie. Nawet jeśli dane nie są wyświetlane w widoku, złośliwy użytkownik może wysłać żądanie HTTP z dołączonymi danymi, a MVC chętnie je powiąza, ponieważ twoja akcja informuje, że klasa bazy danych jest kształtem danych, które powinny zaakceptować dla danych wejściowych użytkownika.
  • Dlaczego należy zadbać o kształt używany do tworzenia powiązania modelu? - Użycie powiązania modelu ASP.NET MVC z nadmiernie szerokimi modelami uwidacznia aplikację w celu nadmiernego delegowania ataków. Nadmierne delegowanie może umożliwić osobom atakującym zmianę danych aplikacji poza przeznaczenie dewelopera, na przykład zastąpienie ceny elementu lub uprawnień zabezpieczeń dla konta. Aplikacje powinny używać modeli powiązań specyficznych dla akcji (lub określonych dozwolonych list filtrów właściwości), aby zapewnić jawną umowę dotyczącą niezaufanych danych wejściowych, które mają być dozwolone za pośrednictwem powiązania modelu.
  • Czy posiadanie oddzielnych modeli powiązań po prostu duplikuje kod? - Nie, jest to kwestia separacji obaw. Jeśli ponownie używasz modeli baz danych w metodach akcji, mówisz, że dowolna właściwość (lub właściwość podrzędna) w tej klasie może być ustawiana przez użytkownika w żądaniu HTTP. Jeśli to nie jest to, co chcesz zrobić MVC, potrzebujesz listy filtrów lub oddzielnego kształtu klasy, aby pokazać MVC, jakie dane mogą pochodzić z danych wejściowych użytkownika.
  • Jeśli mam oddzielne modele powiązań dla danych wejściowych użytkownika, czy muszę zduplikować wszystkie atrybuty adnotacji danych? - Niekoniecznie. Możesz użyć atrybutu MetadataTypeAttribute w klasie modelu bazy danych, aby połączyć się z metadanymi w klasie powiązania modelu. Należy pamiętać, że typ, do którego odwołuje się atrybut MetadataTypeAttribute, musi być podzbiorem typu odwołania (może mieć mniej właściwości, ale nie więcej).
  • Przenoszenie danych między modelami wejściowymi użytkownika a modelami baz danych jest żmudne. Czy mogę po prostu skopiować wszystkie właściwości przy użyciu odbicia? - Tak. Jedynymi właściwościami wyświetlanymi w modelach powiązań są te, które zostały uznane za bezpieczne dla danych wejściowych użytkownika. Nie ma powodu zabezpieczeń, który uniemożliwia użycie odbicia w celu skopiowania wszystkich właściwości, które istnieją wspólne między tymi dwoma modelami.
  • Co z [Bind(Exclude ="â €¬")]. Czy mogę użyć tego zamiast oddzielnych modeli powiązań? - Takie podejście nie jest zalecane. Użycie opcji [Bind(Exclude ="â €^")] oznacza, że każda nowa właściwość jest domyślnie powiązana. Po dodaniu nowej właściwości istnieje dodatkowy krok do zapamiętania, aby zachować bezpieczeństwo rzeczy, zamiast mieć projekt domyślnie bezpieczny. W zależności od tego, czy deweloper sprawdza tę listę za każdym razem, gdy dodawana jest właściwość, jest ryzykowna.
  • Czy narzędzie [Bind(Include ="â €^")] jest przydatne w przypadku operacji edycji? - L.p. [Bind(Include ="â €^")] jest odpowiednia tylko dla operacji w stylu INSERT (dodawanie nowych danych). W przypadku operacji typu UPDATE (zmiana istniejących danych) należy użyć innego podejścia, takiego jak posiadanie oddzielnych modeli powiązań lub przekazanie jawnej listy dozwolonych właściwości do modelu UpdateModel lub TryUpdateModel. Dodanie atrybutu [Bind(Include ="â €}")] w operacji Edycja oznacza, że mvC utworzy wystąpienie obiektu i ustawi tylko wymienione właściwości, pozostawiając wszystkie inne wartości domyślne. Gdy dane są utrwalane, całkowicie zastąpią istniejącą jednostkę, resetując wartości wszystkich pominiętych właściwości do ich wartości domyślnych. Jeśli na przykład właściwość Is Administracja została pominięta z atrybutu [Bind(Include ="â €}")] w operacji Edycji, każdy użytkownik, którego nazwa została edytowana za pośrednictwem tej akcji, zostanie zresetowany do wartości Is Administracja = false (każdy edytowany użytkownik utraci stan administratora). Jeśli chcesz zapobiec aktualizacjom niektórych właściwości, użyj jednego z innych podejść powyżej. Należy pamiętać, że niektóre wersje narzędzi MVC generują klasy kontrolerów za pomocą polecenia [Bind(Include ="â €^")] w akcjach Edycji i sugerują, że usunięcie właściwości z tej listy zapobiegnie atakom polegającym na nadmiernym delegowaniu. Jednak zgodnie z powyższym opisem takie podejście nie działa zgodnie z oczekiwaniami i zamiast tego spowoduje zresetowanie żadnych danych we pominiętych właściwościach do ich wartości domyślnych.
  • Czy w przypadku operacji tworzenia istnieją jakieś zastrzeżenia dotyczące używania elementu [Bind(Include ="â €^")] zamiast oddzielnych modeli powiązań? - Tak. Najpierw takie podejście nie działa w przypadku scenariuszy edycji, które wymagają obsługi dwóch oddzielnych metod ograniczania wszystkich nadmiernych luk w zabezpieczeniach. Po drugie, oddzielne modele powiązań wymuszają rozdzielenie obaw między kształtem używanym do wprowadzania danych przez użytkownika a kształtem używanym do trwałości, czego nie robi [Bind(Include ="â €}")]. Po trzecie należy pamiętać, że [Bind(Include ="â €^")] może obsługiwać tylko właściwości najwyższego poziomu; w atrybucie nie można zezwalać tylko na części właściwości podrzędnych (takich jak "Details.Name"). Na koniec, a być może najważniejsze, użycie polecenia [Bind(Include ="â €}")] dodaje dodatkowy krok, który należy zapamiętać za każdym razem, gdy klasa jest używana do powiązania modelu. Jeśli nowa metoda akcji wiąże się bezpośrednio z klasą danych i zapomina o dołączeniu atrybutu [Bind(Include ="â €™")] może być podatna na ataki nadmiernego delegowania, więc podejście [Bind(Include ="â €}")] jest domyślnie nieco mniej bezpieczne. Jeśli używasz polecenia [Bind(Include ="â €^")], zawsze pamiętaj, aby pamiętać, aby określić ją za każdym razem, gdy klasy danych będą wyświetlane jako parametry metody akcji.
  • Co z umieszczaniem atrybutu [Bind(Include ="â €}")] dla operacji tworzenia w samej klasie modelu? Czy takie podejście nie pozwala uniknąć konieczności zapamiętania umieszczenia atrybutu w każdej metodzie akcji? - Takie podejście działa w niektórych przypadkach. Użycie parametru [Bind(Include ="â €^")] w samym typie modelu (zamiast parametrów akcji korzystających z tej klasy) pozwala uniknąć konieczności uwzględnienia atrybutu [Bind(Include ="â €¬")] dla każdej metody akcji. Użycie atrybutu bezpośrednio w klasie skutecznie tworzy oddzielny obszar powierzchni tej klasy na potrzeby powiązania modelu. Jednak takie podejście umożliwia tylko jeden kształt powiązania modelu dla klasy modelu. Jeśli jedna metoda akcji musi zezwalać na powiązanie modelu pola (na przykład akcję tylko dla administratora, która aktualizuje role użytkowników) i inne akcje muszą uniemożliwić powiązanie modelu tego pola, takie podejście nie będzie działać. Każda klasa może mieć tylko jeden kształt powiązania modelu; Jeśli różne akcje wymagają różnych kształtów powiązania modelu, muszą reprezentować te oddzielne kształty przy użyciu oddzielnych klas powiązań modelu lub oddzielnych atrybutów [Bind(Include ="â €}")] dla metod akcji.
  • Co to są modele powiązań? Czy są one takie same jak modele wyświetlania? - Są to dwa powiązane pojęcia. Termin Model powiązania odnosi się do klasy modelu używanej na liście parametrów akcji (kształt przekazywany z powiązania modelu MVC z metodą akcji). Termin Model widoku odnosi się do klasy modelu przekazanej z metody akcji do widoku. Użycie modelu specyficznego dla widoku jest typowym podejściem do przekazywania danych z metody akcji do widoku. Często ten kształt jest również odpowiedni dla powiązania modelu, a model widoku terminu może służyć do odwoływania się do tego samego modelu używanego w obu miejscach. Mówiąc dokładniej, ta procedura mówi konkretnie o modelach powiązań, koncentrując się na kształcie przekazanym do działania, co ma znaczenie dla celów masowego przypisania.

Kodowanie niezaufanych danych wyjściowych sieci Web przed renderowaniem

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Generic, Web Forms, MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja Jak zapobiegać skryptom między witrynami w ASP.NET, skryptach między witrynami, XSS (cross site Scripting) Prevention Cheat Sheet
Kroki Wykonywanie skryptów między witrynami (często skracanych jako XSS) jest wektorem ataku dla Usługi online lub dowolnej aplikacji/składnika, który korzysta z danych wejściowych z internetu. Luki w zabezpieczeniach XSS mogą umożliwić atakującemu wykonanie skryptu na maszynie innego użytkownika za pośrednictwem wrażliwej aplikacji internetowej. Złośliwe skrypty mogą służyć do kradzieży plików cookie i innego manipulowania maszyną ofiary za pośrednictwem języka JavaScript. Usługa XSS jest zapobiegana weryfikacji danych wejściowych użytkownika, zapewniając, że jest prawidłowo sformułowana i kodowana przed jego renderowaniem na stronie internetowej. Walidacja danych wejściowych i kodowanie danych wyjściowych można wykonać przy użyciu biblioteki ochrony sieci Web. W przypadku kodu zarządzanego (C#, VB.NET itp.) użyj co najmniej jednej odpowiedniej metody kodowania z biblioteki ochrony sieci Web (anti-XSS), w zależności od kontekstu, w którym manifestowane są dane wejściowe użytkownika:

Przykład

* Encoder.HtmlEncode 
* Encoder.HtmlAttributeEncode 
* Encoder.JavaScriptEncode 
* Encoder.UrlEncode
* Encoder.VisualBasicScriptEncode 
* Encoder.XmlEncode 
* Encoder.XmlAttributeEncode 
* Encoder.CssEncode 
* Encoder.LdapEncode 

Przeprowadzanie walidacji i filtrowania danych wejściowych we wszystkich właściwościach modelu typu ciągu

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Generic, MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja Dodawanie walidacji, walidacji danych modelu w aplikacji MVC, wytyczne dotyczące aplikacji ASP.NET MVC
Kroki

Przed użyciem wszystkich parametrów wejściowych w aplikacji należy upewnić się, że aplikacja jest zabezpieczona przed złośliwymi danymi wejściowymi użytkownika. Zweryfikuj wartości wejściowe przy użyciu walidacji wyrażeń regularnych po stronie serwera z dozwoloną strategią sprawdzania poprawności listy. Niezasanitowane dane wejściowe/parametry użytkownika przekazane do metod mogą powodować luki w zabezpieczeniach polegających na wstrzyknięciu kodu.

W przypadku aplikacji internetowych punkty wejścia mogą również zawierać pola formularza, ciągi zapytań, pliki cookie, nagłówki HTTP i parametry usługi internetowej.

Po powiązaniu modelu należy wykonać następujące kontrole weryfikacji danych wejściowych:

  • Właściwości modelu powinny być oznaczone adnotacją RegularExpression w celu akceptowania dozwolonych znaków i maksymalnej dopuszczalnej długości
  • Metody kontrolera powinny wykonywać ważność modelu ModelState

Należy zastosować oczyszczanie w polach formularzy, które akceptują wszystkie znaki, np. edytor tekstu sformatowanych

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Kodowanie niebezpiecznych danych wejściowych, sanitizer HTML
Kroki

Zidentyfikuj wszystkie statyczne tagi znaczników, których chcesz użyć. Powszechną praktyką jest ograniczenie formatowania do bezpiecznych elementów HTML, takich jak <b> (pogrubienie) i <i> (kursywa).

Przed zapisaniem danych zakoduj je w formacie HTML. Dzięki temu każdy złośliwy skrypt jest bezpieczny, powodując obsługę go jako tekstu, a nie jako kodu wykonywalnego.

  1. Wyłącz ASP.NET weryfikacji żądania przez dodanie atrybutu ValidateRequest="false" do dyrektywy @ Page
  2. Kodowanie danych wejściowych ciągu za pomocą metody HtmlEncode
  3. Użyj klasy StringBuilder i wywołaj metodę Replace, aby selektywnie usunąć kodowanie w elementach HTML, które chcesz zezwolić

Strona w odwołaniach wyłącza weryfikację żądania ASP.NET przez ustawienie .ValidateRequest="false" Kod html koduje dane wejściowe i selektywnie zezwala <b> na używanie <i> biblioteki .NET na potrzeby oczyszczania kodu HTML.

HtmlSanitizer to biblioteka platformy .NET służąca do czyszczenia fragmentów i dokumentów HTML z konstrukcji, które mogą prowadzić do ataków XSS. Używa elementu AngleSharp do analizowania, manipulowania i renderowania kodu HTML i CSS. Narzędzie HtmlSanitizer można zainstalować jako pakiet NuGet, a dane wejściowe użytkownika można przekazywać za pośrednictwem odpowiednich metod oczyszczania KODU HTML lub CSS, zgodnie z tym, które mają zastosowanie, po stronie serwera. Należy pamiętać, że oczyszczanie jako mechanizm kontroli zabezpieczeń należy traktować tylko jako ostatnią opcję.

Walidacja danych wejściowych i kodowanie danych wyjściowych są uznawane za lepsze mechanizmy kontroli zabezpieczeń.

Nie przypisuj elementów DOM do ujść, które nie mają wbudowanego kodowania

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Nie dotyczy
Kroki Wiele funkcji języka JavaScript domyślnie nie wykonuje kodowania. Podczas przypisywania niezaufanych danych wejściowych do elementów DOM za pośrednictwem takich funkcji może spowodować wykonanie skryptu między witrynami (XSS).

Przykład

Poniżej przedstawiono niezabezpieczone przykłady:

document.getElementByID("div1").innerHtml = value;
$("#userName").html(res.Name);
return $('<div/>').html(value)
$('body').append(resHTML);   

Nie używaj funkcji innerHtml; zamiast tego użyj polecenia innerText. Podobnie, zamiast $("#elm").html(), użyj polecenia $("#elm").text()

Zweryfikuj wszystkie przekierowania w aplikacji są zamknięte lub wykonane bezpiecznie

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Struktura autoryzacji OAuth 2.0 — open redirectors
Kroki

Projekt aplikacji wymagający przekierowania do lokalizacji dostarczonej przez użytkownika musi ograniczyć możliwe elementy docelowe przekierowania do wstępnie zdefiniowanej "bezpiecznej" listy witryn lub domen. Wszystkie przekierowania w aplikacji muszą być zamknięte/bezpieczne.

Czynność:

  • Identyfikowanie wszystkich przekierowań
  • Zaimplementuj odpowiednie środki zaradcze dla każdego przekierowania. Odpowiednie środki zaradcze obejmują listę dozwolonych przekierowań lub potwierdzenie użytkownika. Jeśli witryna internetowa lub usługa z otwartą luką w zabezpieczeniach przekierowania korzysta z dostawców tożsamości Facebook/OAuth/OpenID, osoba atakująca może ukraść token logowania użytkownika i personifikować tego użytkownika. Jest to nieodłączne ryzyko podczas korzystania z protokołu OAuth, który jest udokumentowany w dokumencie RFC 6749 "OAuth 2.0 Authorization Framework", Sekcja 10.15 "Otwarte przekierowania" Podobnie poświadczenia użytkowników mogą zostać naruszone przez ataki wyłudzania informacji przy użyciu otwartych przekierowań

Implementowanie walidacji danych wejściowych dla wszystkich parametrów typu ciągu akceptowanych przez metody kontrolera

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Generic, MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja Weryfikowanie danych modelu w aplikacji MVC, wytyczne dotyczące aplikacji ASP.NET MVC
Kroki W przypadku metod, które po prostu akceptują typ danych pierwotnych, a nie modele jako argument, należy przeprowadzić walidację danych wejściowych przy użyciu wyrażenia regularnego. Tutaj element Regex.IsMatch powinien być używany z prawidłowym wzorcem wyrażeń regularnych. Jeśli dane wejściowe nie są zgodne z określonym wyrażeniem regularnym, kontrolka nie powinna kontynuować działania i powinno zostać wyświetlone odpowiednie ostrzeżenie dotyczące niepowodzenia walidacji.

Ustaw limit czasu górnego limitu dla przetwarzania wyrażeń regularnych, aby zapobiec usłudze DoS z powodu nieprawidłowych wyrażeń regularnych

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie Generic, Web Forms, MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja DefaultRegexMatchTimeout, właściwość
Kroki Aby zapewnić ataki typu "odmowa usługi" na źle utworzone wyrażenia regularne, które powodują wiele wycofywania, ustaw globalny limit czasu domyślnego. Jeśli czas przetwarzania trwa dłużej niż zdefiniowany górny limit, zgłasza wyjątek limitu czasu. Jeśli nic nie zostanie skonfigurowane, limit czasu będzie nieskończony.

Przykład

Na przykład następująca konfiguracja zgłosi wyjątek RegexMatchTimeoutException, jeśli przetwarzanie trwa dłużej niż 5 sekund:

<httpRuntime targetFramework="4.5" defaultRegexMatchTimeout="00:00:05" />

Unikaj używania pliku Html.Raw w widokach Razor

Tytuł Szczegóły
Składnik Aplikacja internetowa
Faza SDL Tworzenie
Odpowiednie technologie MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja Nie dotyczy
Krok ASP.NET WebPages (Razor) wykonują automatyczne kodowanie HTML. Wszystkie ciągi drukowane przez osadzone nuggets kodu (bloki@) są automatycznie zakodowane w formacie HTML. Jednak po HtmlHelper.Raw wywołaniu metody zwraca znaczniki, które nie są kodowane w formacie HTML. Jeśli Html.Raw() jest używana metoda pomocnika, pomija automatyczną ochronę kodowania zapewnianą przez razor.

Przykład

Oto niezabezpieczony przykład:

<div class="form-group">
            @Html.Raw(Model.AccountConfirmText)
        </div>
        <div class="form-group">
            @Html.Raw(Model.PaymentConfirmText)
        </div>
</div>

Nie używaj Html.Raw() , chyba że musisz wyświetlić znaczniki. Ta metoda nie wykonuje kodowania danych wyjściowych niejawnie. Użyj innych pomocników ASP.NET, np. @Html.DisplayFor()

Nie używaj zapytań dynamicznych w procedurach składowanych

Tytuł Szczegóły
Składnik Baza danych
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Nie dotyczy
Kroki

Atak polegający na wstrzyknięciu kodu SQL wykorzystuje luki w zabezpieczeniach w walidacji danych wejściowych w celu uruchamiania dowolnych poleceń w bazie danych. Może wystąpić, gdy aplikacja używa danych wejściowych do konstruowania dynamicznych instrukcji SQL w celu uzyskania dostępu do bazy danych. Może się to również zdarzyć, jeśli kod używa procedur składowanych, które są przekazywane ciągi zawierające nieprzetworzone dane wejściowe użytkownika. Za pomocą ataku polegający na wstrzyknięciu kodu SQL osoba atakująca może wykonywać dowolne polecenia w bazie danych. Wszystkie instrukcje SQL (w tym instrukcje SQL w procedurach składowanych) muszą być sparametryzowane. Sparametryzowane instrukcje SQL będą akceptować znaki, które mają specjalne znaczenie dla języka SQL (na przykład pojedynczy cudzysłów), ponieważ są silnie typizowane.

Przykład

Oto przykład niezabezpieczonej dynamicznej procedury składowanej:

CREATE PROCEDURE [dbo].[uspGetProductsByCriteria]
(
  @productName nvarchar(200) = NULL,
  @startPrice float = NULL,
  @endPrice float = NULL
)
AS
 BEGIN
  DECLARE @sql nvarchar(max)
  SELECT @sql = ' SELECT ProductID, ProductName, Description, UnitPrice, ImagePath' +
       ' FROM dbo.Products WHERE 1 = 1 '
       PRINT @sql
  IF @productName IS NOT NULL
     SELECT @sql = @sql + ' AND ProductName LIKE ''%' + @productName + '%'''
  IF @startPrice IS NOT NULL
     SELECT @sql = @sql + ' AND UnitPrice > ''' + CONVERT(VARCHAR(10),@startPrice) + ''''
  IF @endPrice IS NOT NULL
     SELECT @sql = @sql + ' AND UnitPrice < ''' + CONVERT(VARCHAR(10),@endPrice) + ''''

  PRINT @sql
  EXEC(@sql)
 END

Przykład

Poniżej przedstawiono tę samą procedurę składowaną zaimplementowaną bezpiecznie:

CREATE PROCEDURE [dbo].[uspGetProductsByCriteriaSecure]
(
             @productName nvarchar(200) = NULL,
             @startPrice float = NULL,
             @endPrice float = NULL
)
AS
       BEGIN
             SELECT ProductID, ProductName, Description, UnitPrice, ImagePath
             FROM dbo.Products where
             (@productName IS NULL or ProductName like '%'+ @productName +'%')
             AND
             (@startPrice IS NULL or UnitPrice > @startPrice)
             AND
             (@endPrice IS NULL or UnitPrice < @endPrice)         
       END

Upewnij się, że walidacja modelu jest wykonywana w metodach internetowego interfejsu API

Tytuł Szczegóły
Składnik Internetowy interfejs API
Faza SDL Tworzenie
Odpowiednie technologie MVC5, MVC6
Atrybuty Nie dotyczy
Dokumentacja Walidacja modelu w internetowym interfejsie API ASP.NET
Kroki Gdy klient wysyła dane do internetowego interfejsu API, przed wykonaniem jakiegokolwiek przetwarzania jest wymagany do zweryfikowania danych. W przypadku ASP.NET internetowych interfejsów API, które akceptują modele jako dane wejściowe, użyj adnotacji danych w modelach, aby ustawić reguły sprawdzania poprawności właściwości modelu.

Przykład

Poniższy kod pokazuje to samo:

using System.ComponentModel.DataAnnotations;

namespace MyApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        [Required]
        [RegularExpression(@"^[a-zA-Z0-9]*$", ErrorMessage="Only alphanumeric characters are allowed.")]
        public string Name { get; set; }
        public decimal Price { get; set; }
        [Range(0, 999)]
        public double Weight { get; set; }
    }
}

Przykład

W metodzie akcji kontrolerów interfejsu API ważność modelu musi być jawnie sprawdzona, jak pokazano poniżej:

namespace MyApi.Controllers
{
    public class ProductsController : ApiController
    {
        public HttpResponseMessage Post(Product product)
        {
            if (ModelState.IsValid)
            {
                // Do something with the product (not shown).

                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
            }
        }
    }
}

Implementowanie walidacji danych wejściowych dla wszystkich parametrów typu ciągu akceptowanych przez metody internetowego interfejsu API

Tytuł Szczegóły
Składnik Internetowy interfejs API
Faza SDL Tworzenie
Odpowiednie technologie Generic, MVC 5, MVC 6
Atrybuty Nie dotyczy
Dokumentacja Weryfikowanie danych modelu w aplikacji MVC, wytyczne dotyczące aplikacji ASP.NET MVC
Kroki W przypadku metod, które po prostu akceptują typ danych pierwotnych, a nie modele jako argument, należy przeprowadzić walidację danych wejściowych przy użyciu wyrażenia regularnego. Tutaj element Regex.IsMatch powinien być używany z prawidłowym wzorcem wyrażeń regularnych. Jeśli dane wejściowe nie są zgodne z określonym wyrażeniem regularnym, kontrolka nie powinna kontynuować działania i powinno zostać wyświetlone odpowiednie ostrzeżenie dotyczące niepowodzenia walidacji.

Upewnij się, że parametry bezpieczne dla typu są używane w internetowym interfejsie API na potrzeby dostępu do danych

Tytuł Szczegóły
Składnik Internetowy interfejs API
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Nie dotyczy
Kroki

Jeśli używasz kolekcji Parameters, sql traktuje dane wejściowe jako wartość literału, a nie jako kod wykonywalny. Kolekcja Parameters może służyć do wymuszania ograniczeń dotyczących typu i długości danych wejściowych. Wartości poza zakresem wyzwalają wyjątek. Jeśli nie są używane bezpieczne parametry SQL typu, osoby atakujące mogą wykonywać ataki iniekcyjne osadzone w niefiltrowanych danych wejściowych.

Użyj bezpiecznych parametrów typu podczas konstruowania zapytań SQL, aby uniknąć możliwych ataków polegających na wstrzyknięciu kodu SQL, które mogą wystąpić w przypadku niefiltrowanych danych wejściowych. Można używać bezpiecznych parametrów typu z procedurami składowanymi i dynamicznymi instrukcjami SQL. Parametry są traktowane jako wartości literału przez bazę danych, a nie jako kod wykonywalny. Parametry są również sprawdzane pod kątem typu i długości.

Przykład

Poniższy kod pokazuje, jak używać bezpiecznych parametrów typu z kolekcją SqlParameterCollection podczas wywoływania procedury składowanej.

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

using (SqlConnection connection = new SqlConnection(connectionString))
{ 
DataSet userDataset = new DataSet(); 
SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection); 
myCommand.SelectCommand.CommandType = CommandType.StoredProcedure; 
myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11); 
myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text; 
myCommand.Fill(userDataset);
}  

W poprzednim przykładzie kodu wartość wejściowa nie może być dłuższa niż 11 znaków. Jeśli dane nie są zgodne z typem lub długością zdefiniowaną przez parametr, klasa SqlParameter zgłasza wyjątek.

Używanie sparametryzowanych zapytań SQL dla usługi Azure Cosmos DB

Tytuł Szczegóły
Składnik Azure Document DB
Faza SDL Tworzenie
Odpowiednie technologie Ogólna
Atrybuty Nie dotyczy
Dokumentacja Ogłoszenie parametryzacji SQL w usłudze Azure Cosmos DB
Kroki Mimo że usługa Azure Cosmos DB obsługuje tylko zapytania tylko do odczytu, iniekcja SQL jest nadal możliwa, jeśli zapytania są tworzone przez łączenie z danymi wejściowymi użytkownika. Być może użytkownik może uzyskać dostęp do danych, do których nie powinien uzyskiwać dostępu w ramach tej samej kolekcji, tworząc złośliwe zapytania SQL. Użyj sparametryzowanych zapytań SQL, jeśli zapytania są konstruowane na podstawie danych wejściowych użytkownika.

Walidacja danych wejściowych programu WCF za pośrednictwem powiązania schematu

Tytuł Szczegóły
Składnik WCF
Faza SDL Tworzenie
Odpowiednie technologie Ogólne, NET Framework 3
Atrybuty Nie dotyczy
Dokumentacja MSDN
Kroki

Brak weryfikacji prowadzi do ataków polegających na wstrzyknięciu iniekcji różnych typów.

Weryfikacja komunikatu reprezentuje jedną linię obrony w ochronie aplikacji WCF. Dzięki temu podejściu można weryfikować komunikaty przy użyciu schematów w celu ochrony operacji usługi WCF przed atakiem złośliwego klienta. Zweryfikuj wszystkie komunikaty odebrane przez klienta, aby chronić klienta przed atakiem przez złośliwą usługę. Walidacja komunikatów umożliwia weryfikowanie komunikatów, gdy operacje używają kontraktów komunikatów lub kontraktów danych, których nie można wykonać przy użyciu walidacji parametrów. Walidacja komunikatów umożliwia tworzenie logiki walidacji wewnątrz schematów, co zapewnia większą elastyczność i skrócenie czasu programowania. Schematy można używać ponownie w różnych aplikacjach wewnątrz organizacji, tworząc standardy reprezentacji danych. Ponadto walidacja komunikatów umożliwia ochronę operacji, gdy używają bardziej złożonych typów danych obejmujących kontrakty reprezentujące logikę biznesową.

Aby przeprowadzić walidację komunikatów, należy najpierw utworzyć schemat reprezentujący operacje usługi i typy danych używane przez te operacje. Następnie utworzysz klasę .NET, która implementuje niestandardowego inspektora komunikatów klienta i niestandardowego inspektora komunikatów dyspozytora w celu zweryfikowania komunikatów wysłanych/odebranych do/z usługi. Następnie zaimplementujesz niestandardowe zachowanie punktu końcowego, aby włączyć walidację komunikatów zarówno na kliencie, jak i w usłudze. Na koniec zaimplementujesz niestandardowy element konfiguracji w klasie, który umożliwia uwidocznienie rozszerzonego niestandardowego zachowania punktu końcowego w pliku konfiguracji usługi lub klienta"

WCF — walidacja danych wejściowych za pośrednictwem inspektorów parametrów

Tytuł Szczegóły
Składnik WCF
Faza SDL Tworzenie
Odpowiednie technologie Ogólne, NET Framework 3
Atrybuty Nie dotyczy
Dokumentacja MSDN
Kroki

Walidacja danych wejściowych i danych reprezentuje jedną ważną linię obrony w ochronie aplikacji WCF. Należy zweryfikować wszystkie parametry uwidocznione w operacjach usługi WCF, aby chronić usługę przed atakiem złośliwego klienta. Z drugiej strony należy również zweryfikować wszystkie zwrócone wartości odebrane przez klienta, aby chronić klienta przed atakiem przez złośliwą usługę

Program WCF udostępnia różne punkty rozszerzalności, które umożliwiają dostosowanie zachowania środowiska uruchomieniowego WCF przez utworzenie niestandardowych rozszerzeń. Inspektorzy komunikatów i inspektorzy parametrów to dwa mechanizmy rozszerzalności używane do uzyskiwania większej kontroli nad przekazywaniem danych między klientem a usługą. Należy użyć inspektorów parametrów do weryfikacji danych wejściowych i używać inspektorów komunikatów tylko wtedy, gdy trzeba sprawdzić cały komunikat przepływujący do i z usługi.

Aby przeprowadzić walidację danych wejściowych, utworzysz klasę platformy .NET i zaimplementujesz niestandardowy inspektor parametrów w celu zweryfikowania parametrów dotyczących operacji w usłudze. Następnie zaimplementujesz niestandardowe zachowanie punktu końcowego, aby włączyć walidację zarówno na kliencie, jak i w usłudze. Na koniec zaimplementujesz niestandardowy element konfiguracji w klasie, który umożliwia uwidocznienie rozszerzonego niestandardowego zachowania punktu końcowego w pliku konfiguracji usługi lub klienta