Анализ и парсинг запросов¶
Принципы анализа и парсинга запросов¶
Для качественного анализа запросов, Вебмониторэкс WAF следует принципам:
-
Работа с теми же данными, которые обрабатывает защищаемое приложение. Например:
Если приложение предоставляет JSON API, параметры запроса к приложению будут закодированы в формате JSON. Чтобы получить значения параметров, Вебмониторэкс WAF применяет к запросу парсер JSON. В более сложных случаях, данные могут быть закодированы несколько раз, например: JSON в BASE64 в JSON. Тогда к запросу применяется несколько парсеров.
-
Анализ контекста обработки данных. Например:
Параметр
nameпередается в запросах на создание пользователя и на создание товара, при этом параметр обрабатывается двумя разными способами. Чтобы определить способ анализа подобного параметра, Вебмониторэкс WAF может использовать URL, на который отправлен запрос, или другие параметры.
Определение и парсинг частей запроса¶
Начиная с верхнего уровня HTTP‑запроса, WAF‑нода последовательно применяет к каждой части запроса все подходящие парсеры. Набор парсеров зависит от характера данных и результатов предыдущего обучения системы.
Результатом применения парсера является дополнительный набор параметров, которые необходимо анализировать аналогичным образом. На выходе могут получиться данные сложной структуры, например: массив, ассоциативный массив или JSON.
Теги для парсеров
Каждому парсеру присвоен идентификатор (тег). Например: header для парсера заголовков запроса. Набор тегов, использованных при анализе запроса, отображается в Консоли управления Вебмониторэкс в информации о событии. Эти данные позволяют определить, в какой части запроса обнаружена атака и какие парсеры были применены.
Например, если признаки атаки были обнаружены в заголовке SOAPACTION:
URL¶
Каждый HTTP‑запрос содержит URL. Для поиска атак, WAF‑нода анализирует исходное значение URL целиком и отдельные компоненты URL: path, action_name, action_ext, query.
Парсеру URL соответствуют теги:
-
uri для полного URL запроса без адреса домена (например,
/blogs/123/index.php?q=aaaдля запроса, отправленного на адресhttp://example.com/blogs/123/index.php?q=aaa). -
path для массива с частями URL, разделенными
/, кроме последней. Если URL состоит только из одной части, массив будет пустым. -
action_name для последней части URL после
/и до первой точки (.). Всегда присутствует в запросе, даже если значение — пустая строка. -
action_ext для последней части URL после
/после первой точки (.). Может отсутствовать в запросе.Граница между action_name и action_ext при нескольких точках
Если в последней части URL после
/есть несколько точек (.), могут возникнуть проблемы при определении границы между action_name и action_ext , такие как:-
Установка границы по первой точке, например:
/modern/static/js/cb-common.ffc63abe.chunk.js.map→- ...
action_name—cb-commonaction_ext—ffc63abe.chunk.js.map
-
Исчезновение некоторых элементов после парсинга, для примера выше результат может быть таким:
action_name—cb-commonaction_ext—ffc63abe
Чтобы исправить ошибки, вручную отредактируйте элементы action_name и action_ext в расширенной форме конструктора URI.
-
-
query для параметров URL после
?.
Например, запрос /blogs/123/index.php?q=aaa содержит параметры:
-
[uri]—/blogs/123/index.php?q=aaa -
[path, 0]—blogs -
[path, 1]—123 -
[action_name]—index -
[action_ext]—php -
[query, 'q']—aaa
Параметры URL¶
Параметры URL передаются после символа ? в формате ключ=значение. Парсеру соответствует тег query.
| Пример запроса | Параметры URL и значения |
|---|---|
/?q=some+text&check=yes |
|
/?p1[x]=1&p1[y]=2&p2[]=aaa&p2[]=bbb |
|
/?p3=1&p3=2 |
|
Заголовки¶
В HTTP‑запросе и некоторых других форматах (например, multipart) могут встречаться заголовки. Парсеру соответствует тег header. Все названия заголовков приводятся к верхнему регистру.
Пример:
GET / HTTP/1.1
Host: example.com
X-Test: aaa
X-Test: bbb
-
[header, 'HOST']—example.com -
[header, 'X-TEST', array, 0]—aaa -
[header, 'X-TEST', array, 1]—aaa -
[header, 'X-TEST', pollution]—aaa,bbb
Метаданные¶
Парсеру метаданных HTTP‑запроса соответствуют теги:
-
post для тела HTTP‑запроса
-
method для метода HTTP‑запроса:
GET,POST,PUT,DELETE -
proto для версии HTTP‑протокола
-
scheme: http/https
-
application для ID приложения
Дополнительные парсеры¶
Части запроса могут требовать дополнительного парсинга. Например, если данные закодированы по стандарту Base64 или представлены в формате массива. Тогда к частям запроса применяются дополнительные парсеры, которым соответствуют теги ниже.
base64¶
Декодирует данные в кодировке Base64. Применяется к любой части запроса.
gzip¶
Декодирует данные в кодировке GZIP. Применяется к любой части запроса.
htmljs¶
Конвертирует символы HTML и JS в текстовый формат. Применяется к любой части запроса.
Пример: "aaa" конвертируется в "aaa".
json_doc¶
Парсит данные, представленные в формате JSON. Применяется к любой части запроса.
Фильтры:
-
json_array или array — значение элемента массива
-
json_obj или hash — значение ключа ассоциативного массива (
ключ:значение)
Пример:
{"p1":"value","p2":["v1","v2"],"p3":{"somekey":"somevalue"}}
-
[..., json_doc, hash, 'p1']—value -
[..., json_doc, hash, 'p2', array, 0]—v1 -
[..., json_doc, hash, 'p2', array, 1]—v2 -
[..., json_doc, hash, 'p3', hash, 'somekey']—somevalue
xml¶
Парсит данные в формате XML. Применяется к любой части запроса.
Фильтры:
-
xml_comment — массив с комментариями в теле XML документа
-
xml_dtd — адрес используемой внешней DTD-схемы
-
xml_dtd_entity — массив с определенными в документе DTD Entity
-
xml_pi — массив инструкций для обработки
-
xml_tag или hash — ассоциативный массив тэгов
-
xml_tag_array или array — массив значений тэга
- xml_attr — ассоциативный массив атрибутов, может использоваться только после xml_tag
Для XML‑парсера нет разницы между содержимым тэга и первым элементом в массиве значений для тэга. То есть, параметры [..., xml, xml_tag, 't1'] и [..., xml, xml_tag, 't1', array, 0] идентичны и взаимозаменяемы.
Пример:
<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "aaaa">]>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<!-- test -->
<methodCall>
<methodName>&xxe;</methodName>
<methodArgs check="true">123</methodArgs>
<methodArgs>234</methodArgs>
</methodCall>
-
[..., xml, xml_dtd_entity, 0]— name =xxe, value =aaaa -
[..., xml, xml_pi, 0]— name =xml-stylesheet, value =type="text/xsl" href="style.xsl" -
[..., xml, xml_comment, 0]—test -
[..., xml, xml_tag, 'methodCall', xml_tag, 'methodName']—aaaa -
[..., xml, xml_tag, 'methodCall', xml_tag, 'methodArgs']—123 -
[..., xml, xml_tag, 'methodCall', xml_tag, 'methodArgs', xml_attr, 'check']—true -
[..., xml, xml_tag, 'methodCall', xml_tag, 'methodArgs', array, 1]—234
array¶
Парсит массивы данных. Применяется к любой части запроса.
Пример:
/?p1[x]=1&p1[y]=2&p2[]=aaa&p2[]=bbb
-
[query, 'p2', array, 0]—aaa -
[query, 'p2', array, 1]—bbb
hash¶
Парсит ассоциативные массивы данных (ключ:значение). Применяется к любой части запроса.
Пример:
/?p1[x]=1&p1[y]=2&p2[]=aaa&p2[]=bbb
-
[query, 'p1', hash, 'x']—1 -
[query, 'p1', hash, 'y']—2
pollution¶
Объединяет несколько значений одного параметра в массив. Применяется к любой части запроса в первоначальном виде или после декодирования.
Пример:
/?p3=1&p3=2
[query, 'p3', pollution]—1,2
percent¶
Декодирует символы URL. Применяется только к компоненту URL — uri.
cookie¶
Парсит cookie-параметры запроса. Применяется только к заголовкам запроса.
Пример:
GET / HTTP/1.1
Cookie: a=1; b=2
-
[header, 'COOKIE', cookie, 'a']=1; -
[header, 'COOKIE', cookie, 'b']=2.
form_urlencoded¶
Парсит тело запроса, переданное в формате application/x-www-form-urlencoded. Применяется только к телу запроса.
Пример:
p1=1&p2[a]=2&p2[b]=3&p3[]=4&p3[]=5&p4=6&p4=7
-
[post, form_urlencoded, 'p1']—1 -
[post, form_urlencoded, 'p2', hash, 'a']—2 -
[post, form_urlencoded, 'p2', hash, 'b']—3 -
[post, form_urlencoded, 'p3', array, 0]—4 -
[post, form_urlencoded, 'p3', array, 1]—5 -
[post, form_urlencoded, 'p4', array, 0]—6 -
[post, form_urlencoded, 'p4', array, 1]—7 -
[post, form_urlencoded, 'p4', pollution]—6,7
grpc¶
Парсит параметры запроса к API по протоколу gRPC. Применяется только к телу запроса.
Поддерживает фильтр protobuf для данных в формате Protocol Buffers.
multipart¶
Парсит тело запроса, переданное в формате multipart. Применяется только к телу запроса.
Поддерживает фильтр header для заголовков в теле запроса.
Пример:
p1=1&p2[a]=2&p2[b]=3&p3[]=4&p3[]=5&p4=6&p4=7
-
[post, multipart, 'p1']—1 -
[post, multipart, 'p2', hash, 'a']—2 -
[post, multipart, 'p2', hash, 'b']—3 -
[post, multipart, 'p3', array, 0]—4 -
[post, multipart, 'p3', array, 1]—5 -
[post, multipart, 'p4', array, 0]—6 -
[post, multipart, 'p4', array, 1]—7 -
[post, multipart, 'p4', pollution]—6,7
Если в заголовке Content-Disposition указано имя файла, то считается, что в этом параметре загружается файл, и параметр будет выглядеть следующим образом:
[post, multipart, 'someparam', file]— содержимое файла
viewstate¶
Предназначен для анализа состояния сессии, технологии, которая используется в Microsoft ASP.Net. Применяется только к телу запроса.
Фильтры:
-
viewstate_array — массив
-
viewstate_pair — массив
-
viewstate_triplet — массив
-
viewstate_dict — ассоциативный массив
-
viewstate_dict_key — строка
-
viewstate_dict_value — строка
-
viewstate_sparse_array — ассоциативный массив
Нормы¶
Нормы применяются к парсерам для array и keys типов данных. Нормы используются для определения границ анализа данных. Значение нормы указывается в названии парсера. Например: hash_all, hash_name.
Если норма не указана в явном виде, парсеру передается идентификатор сущности для обработки. Например: после hash передается название объекта JSON или другой идентификатор.
all¶
Используется для получения значений всех элементов, параметров или объектов. Например:
-
query_all для значений всех параметров URL
-
header_all для значений всех заголовков
-
array_all для значений всех элементов массива
-
hash_all для значений всех объектов JSON или атрибутов XML
name¶
Используется для получения названий всех элементов, параметров или объектов. Например:
-
query_name для названий всех параметров URL
-
header_name для названий всех заголовков
-
hash_name для названий всех объектов JSON или атрибутов XML
