Скрипт-инъекции с использованием ASP.NET
Как это предотвратить?
1. В ASP.NET существует функция , предотвращающая скриптовые атаки. Просто установите атрибут ValidateRequest в "Истина" (True):
<%@ Page ... ValidateRequest="true" ... %>
ValidateRequest указывает на то, будет произведена валидация или нет. Если "Истина" - валидация запроса проверяет всю введенную информацию со списком потенциальных жёстко закодированных опасных значений. Если значения совпадут, то вызывается исключение HttpRequestValidationException, по умолчанию установленное в "Истина".
Это предоставляет некоторое преимущество: если ValidateRequest включено, пользователи не смогут выслать такую информацию, как:
‘<b>Important</b>’, ‘<xyz>’
2. В случае если мы хотим разрешить пользователям высылать информацию из текстовых полей, содержащую теги, ValidateRequest должно быть установлено в "Ложь". В этом случае существует другой полезный метод - класс HttpUtility с методом HtmlEncode. Этот метод заменяет буквенные символы специальным значением в HTML с переменными, которые отражают эти символы.
Пример. ‘<’ будет заменено на ‘<’
‘<b>Title</b>’ будет заменено на ‘<b>Title</b>’
3. В случае если мы хотим , чтобы пользователи вводили некоторые безопасные теги (‘<b>’, ‘ <i>’, ‘<u>’ ), которые впоследствии будут отображены соответственно их значению в HTML, нам понадобится проверять ввод кодом. Пример приведен ниже
. . .
using System.Text.RegularExpressions;
. . .
private string[] _dangerousTags = {"applet","body","embed","iframe","frame",
"script","frameset","html","style","layer","link","ilayer","meta","object","img"};
public static string ReplaceTag(string aText,
string aTagName, string aReplaceWith)
{
string result;
// проверяет на <dangerTag />
string pattern = @"<.*?" + aTagName + @".*?/>";
result = Regex.Replace(aText, pattern, aReplaceWith, RegexOptions.IgnoreCase);
// проверяет на <dangerTag> ... </dangerTag>
pattern = @"<.*?" + aTagName + @".*?>.*?</.*?" + aTagName + @".*?>";
result = Regex.Replace(result, pattern, aReplaceWith, RegexOptions.IgnoreCase);
return result;
}
. . .
public string YourFunction()
{
// непроверенный текст
string text = _yourEditorControl.Text;
for (int i = 0; i < _dangerousTags.Length; ++i)
text = ReplaceTag(text, _dangerousTags[i], "");
// проверили текст
}
Объяснение кода:
_dangerousTags является массивом, содержащим в себе все теги, которые должны быть исключены из текста (если таковые были найдены)
ReplaceTag проверяет текст на содержание тега aTagName, и каждый найденный тег (одиночный либо открывающий-закрывающий) заменяется на строку aReplaceWith.
YourFunction содержит текст, введенный пользователем, и когда мы проходим по нему, каждый найденный опасный тег заменяется на “”.
* в Regular Expressions мы использовали символ ‘?’ после каждого шаблона, поэтому мы не хотим чтобы алгоритм поиска был настолько "прожорливым" .
Пример. <script></script> A <script></script>, если бы данный алгоритм был "прожорливым", он бы выбрал весь текст (он начинается с <script> и заканчивается тегом </script>), тогда результат был бы пустой строкой.
В противном случае мы бы получили в результате 2 скриптовых тега и ‘A’ между ними, что по своей сути верно.
Аннотация
Данный материал раскрывает основы атак сриптовыми инъекциями при помощи ASP.NET. Используйте 2.1 и 2.2 при любой возможности, но если поставленные условия более специфические и запрос не может быть автоматически проверен, не забудьте проверить посланные значения.