Механизм безопасности: проверки входных данных | Снижение риска
Отключайте скрипты XSLT для всех операций преобразования, использующих ненадежные таблицы стилей
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Безопасность XSLT, XsltSettings.EnableScript Property (Свойство XsltSettings.EnableScript) |
Шаги | XSLT поддерживает использование скриптов в таблицах стилей с применением элемента <msxml:script> . Таким образом пользовательские функции можно задействовать в преобразовании XSLT. Сценарий выполняется в контексте процесса, выполняющего преобразование. При работе в ненадежной среде скрипт XSLT нужно отключить, чтобы предотвратить выполнение ненадежного кода. При использовании .NET скрипты XSLT отключены по умолчанию. Тем не менее необходимо убедиться, что они не были явно включены в свойстве XsltSettings.EnableScript . |
Пример
XsltSettings settings = new XsltSettings();
settings.EnableScript = true; // WRONG: THIS SHOULD BE SET TO false
Пример
При использовании MSXML 6.0 скрипты XSLT отключены по умолчанию. Тем не менее необходимо убедиться, что они не были явно включены в свойстве AllowXsltScript объекта XML модели DOM.
doc.setProperty("AllowXsltScript", true); // WRONG: THIS SHOULD BE SET TO false
Пример
Если вы используете MSXML версии 5 или более ранней, скрипты XSLT включены по умолчанию. Их необходимо явно отключать. Задайте для свойства AllowXsltScript объекта XML модели DOM значение false.
doc.setProperty("AllowXsltScript", false); // CORRECT. Setting to false disables XSLT scripting.
Убедитесь, что каждая страница, на которой может быть содержимое, управляемое пользователем, не использует автоматическое обнаружение типов MIME
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | IE8 Security Part V — Comprehensive Protection (Безопасность IE8, часть 5: комплексная защита) |
Шаги | Для каждой страницы, на которой может быть содержимое, управляемое пользователем, необходимо использовать HTTP-заголовок С каждым типом файлов, доставленных с веб-сервера, связан тип MIME (также называется content-type), описывающий характер содержимого (изображение, текст, приложение и т. д.). Заголовок X-Content-Type-Options — это HTTP-заголовок, используя который разработчики могут запретить определение типов MIME содержимого. Этот заголовок обеспечивает защиту от атак путем определения типов MIME. В Internet Explorer 8 (IE8) добавлена поддержка этого заголовка. Заголовком X-Content-Type-Options смогут воспользоваться только пользователи Internet Explorer 8 (IE8). В предыдущих версиях Internet Explorer не предусмотрена поддержка этого заголовка. Только в одном из основных браузеров Internet Explorer 8 (или более поздних версий) можно отключить обнаружение типов MIME. Когда подобная возможность будет реализована в других популярных браузерах (Firefox, Safari, Chrome), мы обновим эту рекомендацию и добавим синтаксис для соответствующих браузеров. |
Пример
Чтобы включить требуемый заголовок глобально для всех страниц в приложении, выполните одно из следующих действий.
- Добавьте заголовок в файл web.config, если приложение размещено в службах IIS 7.
<system.webServer>
<httpProtocol>
<customHeaders>
<add name=""X-Content-Type-Options"" value=""nosniff""/>
</customHeaders>
</httpProtocol>
</system.webServer>
- Добавьте заголовок с помощью глобальной функции Application_BeginRequest
void Application_BeginRequest(object sender, EventArgs e)
{
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
}
- Внедрите пользовательский 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"");
}
}
- Чтобы включить требуемый заголовок только для определенных страниц, добавьте его в отдельные ответы:
this.Response.Headers[""X-Content-Type-Options""] = ""nosniff"";
Усильте защиту для разрешения сущностей XML или отключите его
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | XML Entity Expansion (Расширения сущностей XML), XML Denial of Service Attacks and Defenses (XML: атаки типа "отказ в обслуживании" и способы защиты от них), Общие сведения о безопасности MSXML, Рекомендации по обеспечению безопасности кода MSXML, NSXMLParserDelegate Protocol Reference (Справочник по протоколу NSXMLParserDelegate), Разрешение внешних ресурсов |
Шаги | Существует редко используемая функция XML, благодаря которой средство синтаксического анализа XML расширяет макро-сущности за счет значений, определенных в документе, или из внешних источников. Например, документ может определить сущность "companyname" со значением "Майкрософт", чтобы каждый раз, когда текст "&companyname;" отображается в документе, он автоматически заменяется текстом Майкрософт. Или в документе может быть определена сущность MSFTStock, которая ссылается на внешнюю веб-службу, чтобы получить текущее значение акций Майкрософт. Затем в документе появится "&MSFTStock", он автоматически заменяется текущей ценой акций. Тем не менее этой возможностью можно злоупотребить, что приведет к атаке типа "отказ в обслуживании". Злоумышленник может вложить несколько сущностей, чтобы создать механизм экспоненциального расширения XML, занимающий весь объем памяти в системе. Злоумышленник также может создать внешнюю ссылку, которая выполняет потоковую передачу неограниченного количества данных или приводит к зависанию передачи потока. В результате всем командам необходимо полностью отключить внутреннее и/или внешнее разрешение сущностей XML, если приложение не использует эту функцию, или вручную ограничить объем памяти и количество времени, которые приложение может тратить на разрешение сущностей, если эта функция крайне необходима. Если приложению не требуется разрешение сущностей, отключите его. |
Пример
Для кода .NET Framework можно применять следующие подходы:
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);
Обратите внимание, что значение по умолчанию параметра ProhibitDtd
в параметре XmlReaderSettings
— true, но в параметре XmlTextReader
это значение false. При использовании XmlReaderSettings не нужно явно задавать для параметра ProhibitDtd значение true, но по соображениям безопасности это стоит сделать. Кроме того, обратите внимание, что по умолчанию класс XmlDocument поддерживает разрешение сущностей.
Пример
Чтобы отключить разрешение сущностей для объектов XmlDocument, используйте перезагрузку XmlDocument.Load(XmlReader)
метода Load и задайте соответствующие свойства в аргументе XmlReader, как показано в следующем коде:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);
Пример
Если в вашем приложении невозможно отключить разрешение сущностей, задайте для свойства XmlReaderSettings.MaxCharactersFromEntities значение в соответствии с требованиями приложения. Это ограничит воздействие потенциальных атак типа "отказ в обслуживании" с экспоненциальным расширением. В коде ниже приведен пример такого подхода.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
XmlReader reader = XmlReader.Create(stream, settings);
Пример
Если необходимо разрешать встроенные сущности, но не внешние сущности, задайте для свойства XmlReaderSettings.XmlResolver значение null. Например:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1000;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);
Обратите внимание, что в MSXML6 параметр ProhibitDTD имеет значение true (отключение обработки DTD) по умолчанию. Для кода Apple OSX или iOS можно использовать два средства синтаксического анализа XML: NSXMLParser и libXML2.
Приложения, использующие драйвер http.sys, выполняют проверку нормализации URL-адресов
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Н/П |
Шаги | При работе с любым приложением, использующим драйвер http.sys, следует придерживаться следующих правил:
|
Убедитесь, что при приеме файлов от пользователей обеспечиваются соответствующие меры безопасности.
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Unrestricted File Upload (Неограниченная передача файлов), File Signature Table (Таблица подписей файлов) |
Шаги | Переданные файлы представляют серьезную угрозу для приложений. Первый этап множества атак — это внедрение кода в атакуемую систему. Затем механизму атаки достаточно найти способ выполнения кода. За счет передачи файла злоумышленник выполняет первый этап. Неограниченная передача файлов приводит к самым разным последствиям: перехват системы, перегруженность файловой системы или базы данных, перенаправление атак на внутренние системы и просто искажение внешнего вида. Последствия зависят от того, что приложение делает с переданным файлом, и в особенности от того, где сохранился этот файл. На стороне сервера не предусмотрена проверка передаваемых файлов. Для отправки файлов нужно внедрять следующие меры безопасности:
|
Пример
Подробные сведения о проверке подписи формата файла см. в классе ниже:
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;
}
Убедитесь, что в веб-приложении для доступа к данным используются параметры типобезопасности
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Н/П |
Шаги | При использовании коллекции параметров SQL рассматривает входные данные как литеральное значение, а не как исполняемый код. Используя коллекцию параметров, можно принудительно ограничить тип и длину входных данных. Значения вне диапазона вызывают исключение. Если параметры типобезопасности SQL не используются, злоумышленники могут выполнить атаку путем внедрения кода в нефильтрованные входные данные. Используйте параметры типобезопасности при создании SQL-запросов, чтобы предотвратить возможные атаки путем внедрения кода SQL в нефильтрованные входные данные. Эти параметры можно использовать с хранимыми процедурами и динамическими инструкциями SQL. В базе данных параметры обрабатываются как литеральные значения, а не как исполняемый код. Кроме того, проверяется тип и длина параметров. |
Пример
В следующем коде показано, как использовать параметры типобезопасности с SqlParameterCollection при вызове хранимой процедуры.
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);
}
В предыдущем примере кода длина входного значения не должна превышать 11 знаков. Если тип и длина данных не соответствуют типу или длине, определенным в параметре, класс SqlParameter выдает исключение.
Используйте отдельные классы привязки моделей или списки привязки фильтров для устранения уязвимости массового назначения MVC
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Класс MetadataTypeAttribute, Public Key Security Vulnerability And Mitigation (Уязвимость системы безопасности в виде открытого ключа и способы ее устранения), Complete Guide to Mass Assignment in ASP.NET MVC (Полное руководство по массовому назначению в ASP.NET MVC), Getting Started with EF using MVC (Начало работы с EF с использованием MVC) |
Шаги |
|
Кодируйте ненадежные выходные веб-данные перед обработкой
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальные, веб-формы, MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | How to prevent Cross-site scripting in ASP.NET (Защита от использования межсайтовых сценариев в ASP.NET), Cross-site Scripting (Использование межсайтовых сценариев), XSS (Cross Site Scripting) Prevention Cheat Sheet (Памятка по защите от использования межсайтовых сценариев (XSS)) |
Шаги | Использование межсайтовых сценариев (обычно сокращается как XSS) — это атака, направленная на веб-службы либо приложение или компонент, использующие входные данные из Интернета. Используя межсайтовые сценарии, злоумышленник может выполнить сценарий в уязвимом веб-приложении на компьютере другого пользователя. Вредоносные сценарии можно использовать для хищения файлов cookie и выполнения мошеннических действий на компьютере атакуемого с помощью JavaScript. Чтобы обеспечить защиту от использования межсайтовых сценариев, следует проверять входные данные пользователя, их формат, а также кодировать их перед обработкой на веб-странице. Для проверки входных данных и кодирования выходных данных можно использовать библиотеку веб-защиты. Используйте один или несколько подходящих методов кодирования из библиотеки веб-защиты (защита от использования межсайтовых сценариев) для управляемого кода (C#, VB.net и так далее) в зависимости от контекста, в котором объявляются входные данные пользователя: |
Пример
* Encoder.HtmlEncode
* Encoder.HtmlAttributeEncode
* Encoder.JavaScriptEncode
* Encoder.UrlEncode
* Encoder.VisualBasicScriptEncode
* Encoder.XmlEncode
* Encoder.XmlAttributeEncode
* Encoder.CssEncode
* Encoder.LdapEncode
Проверяйте и фильтруйте входные данные по всем свойствам модели строкового типа
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальные, MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Adding Validation (Добавление проверки), Validating Model Data in an MVC Application (Проверка данных модели в приложении MVC), Основные принципы ваших приложений ASP.NET MVC |
Шаги | Перед использованием в приложении все входные параметры нужно проверять, чтобы убедиться, что приложение защищено от вредоносных входных данных. Проверьте входные значения с помощью проверок регулярных выражений на стороне сервера с помощью стратегии проверки разрешенного списка. Если передать в метод непроверенные входные данные или параметры, приложение подвергается риску атаки путем внедрения кода. Точки входа для веб-приложений также включают поля форм, строки запросов, файлы cookie, заголовки HTTP и параметры веб-службы. После привязки модели необходимо выполнить следующие проверки входных данных:
|
Очищайте поля форм, принимающие все знаки, например редактор форматированного текста
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Кодирование небезопасных входных данных, HTML Sanitizer (Библиотека HtmlSanitizer) |
Шаги | Определите все статические теги разметки, которые нужно использовать. Зачастую при форматировании используются только безопасные элементы HTML, такие как Прежде чем записывать данные, закодируйте их в HTML. Таким образом, любой вредоносный скрипт становится безопасным, так как он обрабатывается как текст, а не как исполняемый код.
Страница в ссылках отключает проверку запросов ASP.NET, задав атрибут HtmlSanitizer — это библиотека .NET для очистки фрагментов и документов HTML от конструкций, которые могут привести к атаке с использованием межсайтовых сценариев. Она использует AngleSharp для анализа и обработки HTML и CSS, а также для управления. HtmlSanitizer можно установить в виде пакета NuGet. Входные данные пользователя можно передать через соответствующие методы очистки HTML или CSS на стороне сервера. Обратите внимание, что очистка — это крайняя мера безопасности. Самые эффективные меры безопасности — это проверка входных данных и кодирование выходных данных. |
Не назначайте элементы модели DOM приемникам без встроенных возможностей кодирования
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Н/П |
Шаги | Многие функции JavaScript не выполняют кодирование по умолчанию. Назначение ненадежных входных данных элементам модели DOM через такие функции может привести к выполнению межсайтовых сценариев (XSS). |
Пример
Ниже приведены примеры ненадежных входных данных.
document.getElementByID("div1").innerHtml = value;
$("#userName").html(res.Name);
return $('<div/>').html(value)
$('body').append(resHTML);
Не используйте элемент innerHtml
. Вместо него используйте innerText
. Аналогичным образом вместо $("#elm").html()
используйте $("#elm").text()
.
Убедитесь, что операции перенаправления в приложении закрыты или выполняются безопасно
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | The OAuth 2.0 Authorization Framework — Open Redirectors (OAuth 2.0 Authorization Framework: открытые средства перенаправления) |
Шаги | Если приложение требует перенаправления в пользовательское расположение, необходимо ограничить возможные целевые расположения для перенаправления, задав предопределенный список безопасных сайтов или доменов. Все операции перенаправления в приложении должны быть закрытыми и безопасными. Для этого:
|
Внедрите проверку входных данных для всех параметров строкового типа, принимаемых методами контроллера
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальные, MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Validating Model Data in an MVC Application (Проверка данных модели в приложении MVC), Основные принципы ваших приложений ASP.NET MVC |
Шаги | Для методов, принимающих примитивные типы данных, а не модели в качестве аргументов, следует выполнять проверки входных данных с использованием регулярных выражений. Здесь следует использовать Regex.IsMatch с шаблоном допустимого регулярного выражения. Если входные данные не соответствуют указанному регулярному выражению, работа прекращается и отображается соответствующее предупреждение об ошибке проверки. |
Задайте верхний предел времени ожидания для обработки регулярных выражений во избежание атаки типа "отказ в обслуживании" из-за недопустимого регулярного выражения
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | Универсальные, веб-формы, MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Свойство DefaultRegexMatchTimeout |
Шаги | Чтобы при использовании недопустимых регулярных выражений, из-за чего вам пришлось вернуться на много шагов, появлялась ошибка типа "отказ в обслуживании", задайте глобальное время ожидания по умолчанию. Если обработка выполняется дольше заданного верхнего предела, будет выведено исключение времени ожидания. Если ничего не настраивать, время ожидания будет бесконечным. |
Пример
Например, если обработка занимает более 5 секунд, исключение RegexMatchTimeoutException вызывает следующая конфигурация:
<httpRuntime targetFramework="4.5" defaultRegexMatchTimeout="00:00:05" />
Не используйте метод Html.Raw в представлениях Razor
Заголовок | Сведения |
---|---|
Компонент | Веб-приложение |
Этап SDL | Сборка |
Применимые технологии | MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Н/П |
Этап | Веб-страницы ASP.NET (Razor) выполняют автоматическое кодирование HTML. Все строки, которые выводятся внедренными ограничителями кода (блоки @), автоматически преобразовываются в формат HTML. Однако при вызове метод HtmlHelper.Raw возвращает разметку без кодировки HTML. Если используется вспомогательный метод Html.Raw() , он обходит автоматическую защиту кодирования, обеспечиваемую Razor. |
Пример
Ниже приведены примеры ненадежных входных данных.
<div class="form-group">
@Html.Raw(Model.AccountConfirmText)
</div>
<div class="form-group">
@Html.Raw(Model.PaymentConfirmText)
</div>
</div>
Используйте метод Html.Raw()
только для отображения разметки. Этот метод помогает избежать неявного кодирования выходных данных. Используйте другие вспомогательные методы ASP.NET, например @Html.DisplayFor()
.
Не используйте динамические запросы в хранимых процедурах
Заголовок | Сведения |
---|---|
Компонент | База данных |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Н/П |
Шаги | В ходе атаки путем внедрения кода SQL используются уязвимости проверки входных данных для выполнения произвольных команд в базе данных. Это может произойти, когда приложение использует входные данные, чтобы создать динамические инструкции SQL для доступа к базе данных. Кроме того, такая атака может выполняться, если код использует хранимые процедуры, передающие строки с необработанными входными данными пользователя. В ходе атаки путем внедрения кода SQL злоумышленник может выполнять произвольные команды в базе данных. Все инструкции SQL (включая инструкции SQL в хранимых процедурах) нужно параметризовать. Параметризованные инструкции SQL без проблем принимают знаки, имеющие специальное значение в SQL (например, одинарная кавычка), так как они строго типизированы. |
Пример
Ниже приведен пример небезопасной динамической хранимой процедуры.
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
Пример
Ниже приведен пример той же хранимой процедуры, реализованной безопасным образом.
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
Убедитесь, что в методах веб-API выполнена проверка моделей
Заголовок | Сведения |
---|---|
Компонент | Веб-интерфейс API |
Этап SDL | Сборка |
Применимые технологии | MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Проверка модели в веб-API ASP.NET |
Шаги | Данные, которые клиент отправляет в веб-API, нужно обязательно проверить перед обработкой. В веб-API ASP.NET, которые принимают модели в качестве входных данных, используйте аннотации данных для моделей, чтобы задать правила проверки свойств модели. |
Пример
Это показано в следующем коде:
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; }
}
}
Пример
В методе действия контроллеров API достоверность модели должна быть проверена явно, как показано ниже.
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);
}
}
}
}
Внедрите проверку входных данных для всех параметров строкового типа, принимаемых методами веб-API
Заголовок | Сведения |
---|---|
Компонент | Веб-интерфейс API |
Этап SDL | Сборка |
Применимые технологии | Универсальные, MVC 5, MVC 6 |
Атрибуты | Н/П |
Ссылки | Validating Model Data in an MVC Application (Проверка данных модели в приложении MVC), Основные принципы ваших приложений ASP.NET MVC |
Шаги | Для методов, принимающих примитивные типы данных, а не модели в качестве аргументов, следует выполнять проверки входных данных с использованием регулярных выражений. Здесь следует использовать Regex.IsMatch с шаблоном допустимого регулярного выражения. Если входные данные не соответствуют указанному регулярному выражению, работа прекращается и отображается соответствующее предупреждение об ошибке проверки. |
Убедитесь, что в веб-API для доступа к данным используются параметры типобезопасности
Заголовок | Сведения |
---|---|
Компонент | Веб-интерфейс API |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Н/П |
Шаги | При использовании коллекции параметров SQL рассматривает входные данные как литеральное значение, а не как исполняемый код. Используя коллекцию параметров, можно принудительно ограничить тип и длину входных данных. Значения вне диапазона вызывают исключение. Если параметры типобезопасности SQL не используются, злоумышленники могут выполнить атаку путем внедрения кода в нефильтрованные входные данные. Используйте параметры типобезопасности при создании SQL-запросов, чтобы предотвратить возможные атаки путем внедрения кода SQL в нефильтрованные входные данные. Эти параметры можно использовать с хранимыми процедурами и динамическими инструкциями SQL. В базе данных параметры обрабатываются как литеральные значения, а не как исполняемый код. Кроме того, проверяется тип и длина параметров. |
Пример
В следующем коде показано, как использовать параметры типобезопасности с SqlParameterCollection при вызове хранимой процедуры.
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);
}
В предыдущем примере кода длина входного значения не должна превышать 11 знаков. Если тип и длина данных не соответствуют типу или длине, определенным в параметре, класс SqlParameter выдает исключение.
Использование параметризованных SQL-запросов для Azure Cosmos DB
Заголовок | Сведения |
---|---|
Компонент | Azure DocumentDB |
Этап SDL | Сборка |
Применимые технологии | Универсальный |
Атрибуты | Н/П |
Ссылки | Announcing SQL Parameterization in Azure Cosmos DB (Объявление о параметризации SQL в Azure Cosmos DB) |
Шаги | Несмотря на то что Azure Cosmos DB поддерживает исключительно запросы только на чтение, атака путем внедрения кода SQL по-прежнему возможна, если создавать запросы, объединяя их с входными данными пользователя. Пользователи могут получить доступ к данным, к которым они не должны обращаться, в одной коллекции, составляя вредоносные SQL-запросы. Используйте параметризованные SQL-запросы, если запросы создаются на основе входных данных пользователя. |
Проверка входных данных WCF путем привязки к схеме
Заголовок | Сведения |
---|---|
Компонент | WCF |
Этап SDL | Сборка |
Применимые технологии | Универсальные, .NET Framework 3 |
Атрибуты | Н/П |
Ссылки | MSDN |
Шаги | Отсутствие проверки приводит к разным атакам путем внедрения кода. Проверка сообщений представляет один этап защиты приложения WCF. При таком подходе сообщения проверяются с использованием схем защиты операций службы WCF от атак со стороны вредоносного клиента. Проверяйте все сообщения, полученные клиентом, чтобы защитить его от атаки вредоносной службы. При этом сообщения проверяются, когда операции используют контракты сообщений или данных. Такая возможность не обеспечивается при проверке параметров. Проверка сообщений предусматривает создание логики проверки в схемах, тем самым обеспечивая большую гибкость и ускоряя разработку. Схемы можно повторно использовать в разных приложениях в организации, создавая стандарты представления данных. Кроме того, путем проверки сообщений можно защитить операции, использующие более сложные типы данных, включая контракты, представляющие бизнес-логику. Чтобы выполнить проверку сообщений, сначала нужно создать схему, которая представляет операции службы и типы данных, используемые этими операциями. Затем создайте класс .NET, который реализует пользовательский инспектор клиентских сообщений и пользовательский инспектор сообщений диспетчера, для проверки сообщений, отправленных службе или полученных от службы. Далее необходимо реализовать поведение пользовательской конечной точки, чтобы включить проверку сообщений клиента и службы. Наконец, нужно реализовать пользовательский элемент конфигурации в классе, который позволяет использовать расширенное поведение пользовательской конечной точки в файле конфигурации службы или клиента. |
Проверка входных данных WCF с помощью инспекторов параметров
Заголовок | Сведения |
---|---|
Компонент | WCF |
Этап SDL | Сборка |
Применимые технологии | Универсальные, .NET Framework 3 |
Атрибуты | Н/П |
Ссылки | MSDN |
Шаги | Проверка входных данных представляет важный этап защиты приложения WCF. Следует проверять все параметры, используемые в операциях службы WCF, чтобы обеспечить защиту службы от атак вредоносного клиента. И наоборот, проверяйте все возвращенные значения, полученные клиентом, чтобы защитить его от атаки вредоносной службы. WCF предоставляет разные точки расширения, которые позволяют настроить поведение среды выполнения WCF за счет создания пользовательских расширений. Инспекторы сообщений и инспекторы параметров представляют собой два механизма расширения, обеспечивающие более высокий уровень контроля над данными, передаваемыми между клиентом и службой. Инспекторы параметров следует использовать для проверки входных данных, а инспекторы сообщений — только для проверки всех входящих и исходящих сообщений службы. Чтобы выполнить проверку входных данных, создайте класс .NET и внедрите пользовательский инспектор параметров для проверки параметров в операциях службы. Далее необходимо реализовать поведение пользовательской конечной точки, чтобы включить проверку в клиенте и службе. Наконец, нужно реализовать пользовательский элемент конфигурации в классе, который позволяет использовать расширенное поведение пользовательской конечной точки в файле конфигурации службы или клиента. |