Аннотирование Java кода в формате JSON
Способы подключения файла c аннотациями
Подробнее о способе подключения файла аннотаций вы можете узнать в этой документации.
Структура файла с аннотациями
Содержимое файла — JSON-объект, состоящий из трёх обязательных полей: language, version и annotations.
Поле language должно иметь значение java. Поле version принимает значение целого типа и задаёт версию механизма. В зависимости от значения файл с разметкой может обрабатываться по-разному. На данный момент поддерживается только одно значение — 1.
Поле annotations — массив объектов "аннотация":
{
"language": "java",
"version": 1,
"annotations":
[
{
...
},
{
...
}
]
}
На данный момент существуют аннотации методов и конструкторов.
Аннотации для taint-анализа
В анализаторе существует ряд аннотаций для taint-анализа. С их помощью можно размечать источники и приёмники заражения. Также существует возможность помечать методы/конструкторы, которые производят валидацию taint-данных. Таким образом, если taint-данные прошли валидацию, то при их попадании в приёмник предупреждения анализатора не будет.
За каждый из видов уязвимостей отвечает отдельное диагностическое правило. На данный момент в анализаторе представлены следующие taint-диагностики:
- V5309 — SQL injection;
- V5310 — OS command injection;
- V5311 — OS argument injection;
- V5312 — XPath injection;
- V5319 — Log injection;
- V5320 — Configuration injection;
- V5321 — LDAP injection;
- V5322 — Reflection injection;
- V5323 — Potentially tainted data is used to define CORS policy;
- V5327 — Regex injection;
- V5330 — XSS injection;
- V5332 — Path traversal vulnerability.
Принцип работы taint-аннотаций
Для каждого из диагностических правил существуют специальные аннотации, которые позволяют разметить приёмники и методы/конструкторы, производящие валидацию.
Что касается источников taint-данных, то они являются общими для всех диагностик. Такие данные также можно разметить с помощью аннотаций.
Примечание. Атрибуты для разметки taint-аннотаций описаны в следующих разделах.
Стоит отметить, что, помимо пользовательских аннотаций, в анализаторе уже имеется ряд taint-аннотаций для различных библиотек. Например, при передаче результата выполнения метода Console.readLine в метод Statement.execute возможно возникновение SQL injection. В анализаторе есть аннотации, которые говорят, что Console.readLine — источник taint-данных, а Statement.execute — приёмник, при попадании в который taint-данных может возникнуть SQL injection.
Таким образом, размечая источники taint-данных, анализатор будет учитывать их для уже существующих приёмников и наоборот. Если добавить аннотацию приёмника, то анализатор будет выдавать предупреждение при попадании в него уже размеченных источников taint-данных (например, Console.readLine).
Аннотации методов
Примечание. Объект аннотации метода должен содержать хотя бы одно опциональное поле.
Объект аннотации метода состоит из следующих полей:
Поле "type"
Обязательное поле. Принимает строку со значением method.
Поле "package"
Обязательное поле. Принимает строку с именем пространства имён, которое содержит метод.
Поле "type_name"
Обязательное поле. Принимает строку с именем класса, в котором определён метод.
Поле "method_name"
Обязательное поле. Принимает строку с именем метода.
Примечание. Для аннотирования конструктора необходимо использовать <init>.
Поле "attributes"
Опциональное поле. Массив строк, который задаёт свойства сущности.
Возможные атрибуты метода
|
# |
Название атрибута |
Описание атрибута |
|---|---|---|
|
1 |
sql_injection_sink |
Передача заражённых данных в параметры этого метода приводит к SQL Injection |
|
2 |
os_command_injection_sink |
Передача заражённых данных в параметры этого метода приводит к OS Command Injection |
|
3 |
xpath_injection_sink |
Передача заражённых данных в параметры этого метода приводит к XPath Injection |
|
4 |
configuration_injection_sink |
Передача заражённых данных в параметры этого метода приводит к Configuration Injection |
|
5 |
ldap_injection_sink |
Передача заражённых данных в параметры этого метода приводит к LDAP Injection |
|
6 |
reflection_injection_sink |
Передача заражённых данных в параметры этого метода приводит к Reflection Injection |
|
7 |
regex_sink |
Передача заражённых данных в параметры этого метода приводит к Regex Injection |
|
8 |
xss_injection_sink |
Передача заражённых данных в параметры этого метода приводит к XSS Injection |
|
9 |
path_traversal_sink |
Передача заражённых данных в параметры этого метода приводит к Path Traversal Vulnerability |
Поле "params"
Опциональное поле.
Аннотирование параметров необходимо для определения нужного для разметки метода. Отсутствие данного поля означает отсутствие любое количество параметров любых типов. Пустой массив параметров ([ ]) означает отсутствие параметров.
Объект аннотации параметра состоит из следующих полей:
Поле "package"
Обязательное поле. Принимает строку с именем пакета, которое содержит тип параметра.
Поле "type_name"
Обязательное поле. Принимает строку с именем класса, в котором определён тип параметра.
Поле "returns"
Опциональное поле. Объект возвращаемого значения, состоит из единственного поля:
Поле "attributes"
Опциональное поле. Массив строк, который задаёт свойства возвращаемого значения метода.
Возможные атрибуты возвращаемого значения
|
# |
Название атрибута |
Описание атрибута |
|---|---|---|
|
1 |
common_source |
Возвращаемое значение является источником заражённых данных |
|
2 |
web_source |
Возвращаемое значение является веб источником заражённых данных |
|
3 |
potential_sql_sanitization |
Возвращаемое значение является санитизированным т SQL Injection |
|
4 |
potential_os_command_sanitization |
Возвращаемое значение является санитизированным от OS Command Injection |
|
5 |
potential_xpath_sanitization |
Возвращаемое значение является санитизированным от XPath Injection |
|
6 |
potential_log_sanitizaton |
Возвращаемое значение является санитизированным от Log Injection |
|
7 |
potential_configuration_sanitization |
Возвращаемое значение является санитизированным от Configuration Injection |
|
8 |
potential_ldap_sanitization |
Возвращаемое значение является санитизированным от LDAP Injection |
|
9 |
potential_reflection_sanitization |
Возвращаемое значение является санитизированным от Reflection Injection |
|
10 |
regex_sanitization |
Возвращаемое значение является санитизированным от Regex Injection |
|
11 |
xss_input_sanitization |
Возвращаемое значение является санитизированным от XSS Injection |
|
12 |
potential_path_traversal_sanitization |
Возвращаемое значение является санитизированным от Path Traversal Vulnerability |
Схема JSON
Схема JSON поставляется в дистрибутиве или доступна по ссылке.
Примеры
Аннотация метода
Рассмотрим метод:
package com.example;
public class MyClass {
public string getUserInput() {
....
}
}
Допустим, данный метод возвращает пользовательский ввод, который может содержать taint-данные. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:
{
"version": 1,
"language": "java",
"annotations": [
{
"type": "method",
"package_name": "com.example",
"type_name": "MyClass",
"method_name": "getUserInput",
"returns": {
"attributes": [ "common_source" ]
}
}
]
}
Аннотация метода/конструктора, тип параметра которых неважен
Рассмотрим две перегрузки метода getUserInput:
package com.example;
public class MyClass {
public string getUserInput(string str) {
....
}
public string getUserInput(int index) {
....
}
}
Допустим, вне зависимости от типа параметра данный метод возвращает пользовательский ввод, который может содержать taint-данные. Аннотация, которая позволит анализатору понять это, будет выглядеть следующим образом:
{
"version": 1,
"language": "java",
"annotations": [
{
"type": "method",
"namespace_name": "com.example",
"type_name": "MyClass",
"method_name": "getUserInput",
"returns": {
"attributes": [ "common_source " ]
}
}
]
}
В данном случае для первого параметра нет аннотаций. Также при подборе аннотации метода неважно, какой тип будет иметь первый параметр, поэтому его аннотация представлена пустым объектом.
Аннотация метода/конструктора с конкретными параметрами
Рассмотрим методы с различными параметрами:
package org.example;
public class Sink {
public void sink(String input) {
....
}
public void sink(String input, String sanitization) {
....
}
}
Если мы считаем, что стоком является лишь первая версия метода, то её аннотация будет выглядеть следующим образом:
{
"language": "java",
"version": 1,
"annotations": [
{
"type": "method",
"package": "org.example",
"type_name": "Sink",
"method_name": "sink",
"params": [
{
"package": "java.lang",
"type_name": "String"
}
],
"attributes": [
"sql_injection_sink"
]
}
]
}
Таким образом, в следующем фрагменте кода анализатор сформирует предупреждение лишь на один из вызовов метода:
package org.example;
public class Main {
public static void main(String[] args) {
var sinkObj = new Sink();
sinkObj.sink(args[0]); // V5309
sinkObj.sink(args[0], "sanitized"); // нет срабатывания
}
}