>
>
Аннотирование C# кода в формате JSON


Аннотирование C# кода в формате JSON

Примечание. На данный момент в C# анализаторе поддержаны только аннотации для taint-анализа. В будущем также будут поддержаны аннотации общего назначения.

Способы подключения файла c аннотациями

Подробнее о способе подключения файла аннотаций вы можете узнать в этой документации.

Структура файла с аннотациями

Содержимое файла — JSON-объект, состоящий из трёх обязательных полей: language, version и annotations.

Поле language должно иметь значение 'csharp'. Поле version принимает значение целого типа и задаёт версию механизма. В зависимости от значения файл с разметкой может обрабатываться по-разному. На данный момент поддерживается только одно значение — 1.

Поле annotations — массив объектов "аннотация":

{
  "language": "csharp",
  "version": 1,
  "annotations":
  [
    {
      ...
    },
    {
      ...
    }
  ]
}

Аннотации могут быть трёх типов:

  • аннотации методов;
  • аннотации конструкторов;
  • аннотации свойств.

Аннотации для taint-анализа

В анализаторе существует ряд аннотаций для taint-анализа. С их помощью можно размечать источники и приёмники заражения. Также существует возможность помечать методы/конструкторы, которые производят валидацию taint-данных. Таким образом, если taint-данные прошли валидацию, то при их попадании в приёмник предупреждения анализатора не будет.

За каждый из видов уязвимостей отвечает отдельное диагностическое правило. На данный момент в анализаторе представлены следующие taint-диагностики:

  • V5608 — SQL injection;
  • V5609 — Path traversal vulnerability;
  • V5610 — XSS vulnerability;
  • V5611 — Insecure deserialization vulnerability;
  • V5614 — XXE vulnerability;
  • V5615 — XEE vulnerability;
  • V5616 — Command injection;
  • V5618 — Server-side request forgery;
  • V5619 — Log injection;
  • V5620 — LDAP injection;
  • V5622 — XPath injection;
  • V5623 — Open redirect vulnerability;
  • V5624 — Configuration vulnerability;
  • V5626 — ReDoS vulnerability;
  • V5627 — NoSQL injection;
  • V5628 — Zip Slip vulnerability.

Принцип работы taint-аннотаций

Для каждого из диагностических правил существуют специальные аннотации, которые позволяют разметить приёмники и методы/конструкторы, производящие валидацию.

Что касается источников taint-данных, то они являются общими для всех диагностик. Такие данные также можно разметить с помощью аннотаций.

Примечание. Атрибуты для разметки taint-аннотаций описаны в следующих разделах.

Стоит отметить, что, помимо пользовательских аннотаций, в анализаторе уже имеется ряд taint-аннотаций для различных библиотек. Например, при передаче результата выполнения метода System.Console.ReadLine в конструктор System.Data.SqlClient.SqlCommand возможно возникновение SQL injection. В анализаторе есть аннотации, которые говорят, что System.Console.ReadLine — источник taint-данных, а System.Data.SqlClient.SqlCommand — приёмник, при попадании в который taint-данных может возникнуть SQL injection.

Таким образом, размечая источники taint-данных, анализатор будет учитывать их для уже существующих приёмников и наоборот. Если добавить аннотацию приёмника, то анализатор будет выдавать предупреждение при попадании в него уже размеченных источников taint-данных (например, System.Console.ReadLine).

Аннотации методов

Примечание. Объект аннотации метода должен содержать хотя бы одно опциональное поле.

Объект аннотации метода состоит из следующих полей:

Поле "type"

Обязательное поле. Принимает строку со значением method.

Поле "namespace_name"

Обязательное поле. Принимает строку с именем пространства имён, которое содержит метод.

Поле "type_name"

Обязательное поле. Принимает строку с именем класса, в котором определён метод.

Поле "method_name"

Обязательное поле. Принимает строку с именем метода.

Поле "attributes"

Опциональное поле. Массив строк, который задаёт свойства сущности.

Возможные атрибуты метода

#

Название атрибута

Описание атрибута

1

not_apply_to_child_class

Аннотация не будет применяться при вызове проаннотированного метода у объекта дочернего класса.

2

caller_is_xml_parser

Объект, вызывающий метод, является XML-парсером, который может быть уязвим (V5614, V5615).

Поле "params"

Опциональное поле. Данное поле описано в разделе "Аннотации параметров".

Поле "returns"

Примечание. Объект аннотации возвращаемого значения должен либо содержать поля 'namespace_name' и ' type_name', либо оба поля должны отсутствовать (или иметь значение null). Если оба поля отсутствуют, то при выборе аннотации не будет учитываться тип возвращаемого значения.

Опциональное поле. Объект возвращаемого значения, состоит из следующих полей:

Поле "namespace_name"

Опциональное поле. Принимает строку с именем пространства имён, которое содержит тип возвращаемого значения метода.

Поле "type_name"

Опциональное поле. Принимает строку с именем класса, в котором определён тип возвращаемого значения метода.

Поле "attributes"

Опциональное поле. Массив строк, который задаёт свойства возвращаемого значения метода.

Возможные атрибуты возвращаемого значения

#

Название атрибута

Описание атрибута

1

not_apply_to_child_class

Аннотация не будет применяться для методов, тип возвращаемого значения которых является дочерним для проаннотированного типа.

2

always_taint

Метод возвращает taint-данные.

3

transfer_annotations_from_caller

Если вызывающий объект содержит аннотацию, она будет перенесена на возвращаемое значение метода.

Аннотации конструкторов

Примечание. Объект аннотации конструктора должен содержать хотя бы одно опциональное поле.

Объект аннотации конструктора состоит из следующих полей:

Поле "type"

Обязательное поле. Принимает строку со значением ctor.

Поле "namespace_name"

Обязательное поле. Принимает строку с именем пространства имён, которое содержит конструктор.

Поле "type_name"

Обязательное поле. Принимает строку с именем класса, в котором определён конструктор.

Поле "attributes"

Опциональное поле. Массив строк, который задаёт свойства сущности.

Возможные атрибуты конструкторов

#

Название атрибута

Описание атрибута

1

not_apply_to_child_class

Аннотация не будет применяться для дочерних реализаций проаннотированного конструктора.

2

create_taint_object

Созданный конструктором объект — taint.

Поле "params"

Опциональное поле. Данное поле описано в разделе "Аннотации параметров".

Аннотации свойств

Объект аннотации свойства состоит из следующих полей:

Поле "type"

Обязательное поле. Принимает строку со значением property.

Поле "namespace_name"

Обязательное поле. Принимает строку с именем пространства имён, которое содержит свойство.

Поле "type_name"

Обязательное поле. Принимает строку с именем класса, в котором определено свойство.

Поле "attributes"

Опциональное поле. Массив строк, который задаёт свойства сущности.

Возможные атрибуты свойств

Примечание. К каждому из атрибутов taint-приёмников прикреплена ссылка на соответствующую диагностику.

#

Название атрибута

Описание атрибута

1

not_apply_to_child_class

Аннотация не будет применяться при обращении к проаннотированному свойству у объекта дочернего класса.

2

transfer_annotation_to_return_value

Если на вызывающем объекте есть аннотация, то она будет перенесена на возвращаемое значение.

3

transfer_annotation_to_caller

Если свойству присваивается значение, то аннотации этого значения будут перенесены на вызывающий объект свойства.

4

return_taint

Свойство возвращает taint-данные.

5

sql_injection_target

Запись в это свойство заражённых данных приводит к SQL Injection (V5608).

6

path_traversal_target

Запись в это свойство заражённых данных приводит к Path Traversal (V5609).

7

xss_injection_target

Запись в это свойство заражённых данных приводит к XSS Injection (V5610).

8

insecure_deserialization_target

Запись в это свойство заражённых данных приводит к Insecure Deserialization (V5611).

9

command_injection_target

Запись в это свойство заражённых данных приводит к Command Injection (V5616).

10

ssrf_target

Запись в это свойство заражённых данных приводит к Server-Side Request Forgery (V5618).

11

log_injection_target

Запись в это свойство заражённых данных приводит к Log Injection (V5619).

12

ldapi_injection_target

Запись в это свойство заражённых данных приводит к LDAP Injection (V5620).

13

xpath_injection_target

Запись в это свойство заражённых данных приводит к XPath Injection (V5622).

14

open_redirect_target

Запись в это свойство заражённых данных приводит к Open Redirect (V5623).

15

configuration_attack_target

Запись в это свойство заражённых данных приводит к Configuration Attack (5624).

16

nosql_injection_target

Запись в это свойство заражённых данных приводит к NoSQL Injection (V5627).

17

redos_target

Запись в это свойство заражённых данных приводит к ReDoS (V5626).

18

zipslip_target

Запись в это свойство заражённых данных приводит к ZipSlip (V5628).

Аннотации параметров

Примечание 1. Объект аннотации параметра может находиться только внутри массива 'params', объекта аннотации метода или конструктора.

Примечание 2. Объект аннотации параметра должен либо содержать поля 'namespace_name' и 'type_name', либо оба поля должны отсутствовать (или иметь значение null).

Объект аннотации параметра состоит из следующих полей:

Поле "namespace_name"

Обязательное поле. Принимает строку с именем пространства имён, которое содержит тип параметра.

Поле "type_name"

Обязательное поле. Принимает строку с именем класса, в котором определён тип параметра.

Поле "attributes"

Опциональное поле. Массив строк, который задаёт свойства сущности.

Возможные атрибуты параметров

Примечание. К каждому из атрибутов taint-приёмников и taint-валидации прикреплена ссылка на соответствующую диагностику.

#

Название атрибута

Описание атрибута

1

ignore_current_and_next

При подборе соответствующей аннотации не будут учитываться текущий и следующие параметры (данная аннотация может быть только у последнего аргумента).

2

transfer_annotation_to_return_value

Если параметр содержит аннотацию, она будет перенесена на возвращаемое значение метода.

3

object_creation_infector

Заражение нового созданного объекта происходит через этот параметр (актуально только для конструкторов).

4

sql_injection_target

Передача в этот параметр заражённых данных приводит к SQL Injection (V5608).

5

sql_injection_validation

Вызов метода сбрасывает SQL Injection taint-статус для данного параметра (V5608).

6

path_traversal_target

Передача в этот параметр заражённых данных приводит к Path Traversal (V5609).

7

path_traversal_validation

Вызов метода сбрасывает Path Traversal taint-статус для данного параметра (V5609).

8

xss_injection_target

Передача в этот параметр заражённых данных приводит к XSS Injection (V5610).

9

xss_injection_validation

Вызов метода сбрасывает XSS Injection taint-статус для данного параметра (V5610).

10

insecure_deserialization_target

Передача в этот параметр заражённых данных приводит к Insecure Deserialization (V5611).

11

insecure_deserialization_validation

Вызов метода сбрасывает Insecure Deserialization taint-статус для данного параметра (V5611).

12

command_injection_target

Передача в этот параметр заражённых данных приводит к Command Injection (V5616).

13

command_injection_validation

Вызов метода сбрасывает Command Injection taint-статус для данного параметра (V5616).

14

xml_source_to_parse

Параметр - источник XML, который будет парситься. Это может быть сам XML-файл, путь до него, поток с XML-файлов, парсер, содержащий поток XML-файла, и т. п. (V5614, V5615).

15

transfer_xml_settings_to_return

Передаёт настройки XML-парсера из этого аргумента в возвращаемое значение. (V5614, V5615).

16

ssrf_target

Передача в этот параметр заражённых данных приводит к Server-Side Request Forgery (V5618).

17

ssrf_validation

Вызов метода сбрасывает Server-Side Request Forgery taint-статус для данного параметра (V5618).

18

log_injection_target

Передача в этот параметр заражённых данных приводит к Log Injection (V5619).

19

log_injection_validation

Вызов метода сбрасывает Log Injection taint-статус для данного параметра (V5619).

20

ldapi_injection_target

Передача в этот параметр заражённых данных приводит к LDAP Injection (V5620).

21

ldapi_injection_validation

Вызов метода сбрасывает LDAP Injection taint-статус для данного параметра (V5620).

22

xpath_injection_target

Передача в этот параметр заражённых данных приводит к XPath Injection (V5622).

23

xpath_injection_validation

Вызов метода сбрасывает XPath Injection taint-статус для данного параметра (V5622).

24

open_redirect_target

Передача в этот параметр заражённых данных приводит к Open Redirect (V5623).

25

open_redirect_validation

Вызов метода сбрасывает Open Redirect taint-статус для данного параметра (V5623).

26

configuration_attack_target

Передача в этот параметр заражённых данных приводит к Configuration Attack (5624).

27

configuration_attack_validation

Вызов метода сбрасывает Configuration Attack taint-статус для данного параметра (5624).

28

nosql_injection_target

Передача в этот параметр заражённых данных приводит к NoSQL Injection (V5627).

29

nosql_injection_validation

Вызов метода сбрасывает NoSQL Injection taint-статус для данного параметра (V5627).

30

redos_target

Строка, которая разбирается с помощью регулярного выражения. Передача в этот параметр заражённых данных приводит к ReDoS, если регулярное выражение небезопасно (V5626).

31

redos_validation

Вызов метода сбрасывает ReDoS taint-статус для данного параметра (V5626).

32

zipslip_target

Строка, которая может быть использована как путь для извлечения файла из архива. Передача в этот параметр заражённых данных приводит к ZipSlip (V5628).

33

zipslip_validation

Вызов метода сбрасывает ZipSlip taint-статус для данного параметра (V5628).

34

regex

Параметр является регулярным выражением.

Игнорирование типа параметра

Чтобы проигнорировать тип параметра, не нужно указывать поля 'namespace_name' и 'type_name' или нужно записать в оба поля null.

Схема JSON

Схема JSON поставляется в дистрибутиве или доступна по ссылке.

Примеры

Аннотация метода

Рассмотрим метод:

namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput()
    {
      ....
    }
  }
}

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint-данные. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:

{
  "version": 1,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}

Аннотация конструктора

Рассмотрим конструктор:

namespace MyNamespace
{
  public class MyClass
  {
    public MyClass()
    {
      ....
    }
  }
}

Допустим, данный конструктор создаёт объект, который может содержать taint-данные. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:

{
  "version": 1,
  "language": "csharp",
  "annotations": [
    {
      "type": "ctor",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "attributes": [ "create_taint_object" ]
    }
  ]
}

Аннотация свойства

Рассмотрим свойство:

namespace MyNamespace
{
  public class MyClass
  {
    public string UserInput 
    {
      get
      {
        ....
      }
    }
  }
}

Допустим, данное свойство возвращает пользовательский ввод, который может содержать taint-данные. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:

{
  "version": 1,
  "language": "csharp",
  "annotations": [
    {
      "type": "property",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "property_name": "UserInput",
      "attributes": [ "return_taint" ]
    }
  ]
}

Аннотация метода/конструктора, тип параметра которых неважен

Примечание. В качестве примера используется аннотация метода. Игнорирование типа параметров конструктора производится аналогичным образом (не указывать 'type_name' и 'namespace_name' у аннотации параметра).

Рассмотрим две перегрузки метода 'GetUserInput':

namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput(string str)
    {
      ....
    }

    public string GetUserInput(int index)
    {
      ....
    }
  }
}

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint-данные, вне зависимости от типа параметра. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:

{
  "version": 1,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "params": [
        { }
      ],
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}

В данном случае для первого параметра нет аннотаций. Также при подборе аннотации метода неважно, какой тип будет иметь первый параметр. Поэтому аннотация параметра представлена пустым объектом.

Аннотация метода/конструктора, игнорируя некоторые параметры

Примечание. В качестве примера используется аннотация метода. Игнорирование параметров конструктора производится аналогичным образом (с помощью аннотации 'ignore_current_and_next').

Рассмотрим две перегрузки метода 'GetUserInput':

namespace MyNamespace
{
  public class MyClass
  {
    public string GetUserInput(string str)
    {
      ....
    }

    public string GetUserInput(string str, bool flag1, bool flag2)
    {
      ....
    }
  }
}

Допустим, данный метод возвращает пользовательский ввод, который может содержать taint-данные, если использована перегрузка с одним или более параметрами. Также, если в первый параметр передать taint-данные, возникнет SQL injection. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:

{
  "version": 1,
  "language": "csharp",
  "annotations": [
    {
      "type": "method",
      "namespace_name": "MyNamespace",
      "type_name": "MyClass",
      "method_name": "GetUserInput",
      "params": [
        {
          "namespace_name": "System",
          "type_name": "String",
          "attributes": [ "sql_injection_target" ]
        },
        {
          "attributes": [ "ignore_current_and_next" ]
        }
      ],
      "returns": {
        "attributes": [ "always_taint" ]
      }
    }
  ]
}

Для второго параметра есть аннотация 'ignore_current_and_next'. Она позволяет игнорировать количество параметров (включая проаннотированный параметр) при обработке аннотации.