Анализ и парсинг запросов¶
Принципы анализа и парсинга запросов¶
Для качественного анализа запросов, Вебмониторэкс 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-common
action_ext
—ffc63abe.chunk.js.map
-
Исчезновение некоторых элементов после парсинга, для примера выше результат может быть таким:
action_name
—cb-common
action_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