﻿# V5339\. OWASP\. Potential RCE vulnerability\. Insecure GraalVM context is used to process potentially tainted data\.

Анализатор обнаружил использование небезопасно сконфигурированного Polyglot Context \(GraalVM\), который может исполнить скрипт с вредоносным кодом\. Такая конфигурация может сделать приложение уязвимым к Remote Code Execution \(RCE\)\. Подробнее суть данной уязвимости описана здесь\.

Потенциальная эксплуатация небезопасной конфигурации Polyglot Context относится к категориям рисков OWASP Top 10 Application Security Risks:

* [A03:2021 — Injection](https://owasp.org/Top10/2021/A03_2021-Injection/)
* [A05:2021 — Security Misconfiguration](https://owasp.org/Top10/2021/A05_2021-Security_Misconfiguration/)

Рассмотрим пример c небезопасной настройкой в [`Context.Builder`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.Builder.html):

```cpp
public void evalScript(String script) {
    try (Context c = Context.newBuilder()
                            .allowAllAccess(true)
                            .build()
    ) {
        c.eval("js", script);
    }
}
```

В метод [`Context.eval`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.html#eval(java.lang.String,java.lang.CharSequence)) передаётся непроверенный JavaScript код, полученный из параметра публичного метода\. Поскольку метод является публичным, в него могут поступать данные из внешних источников: контроллеров, форм, пользовательского ввода и т\.п\.

Использование небезопасной настройки [`.allowAllAccess(true)`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.Builder.html#allowAllAccess(boolean)) приводит к тому, что создаваемый `Context` получает права на вызов всех публичных конструкторов/методов хостового языка\.

Непроверенный скрипт в сочетании с опасными настройками создаёт риск удалённого выполнения произвольного кода\. Например, злоумышленник сможет выполнить команду `rm -rf /`, используя такой скрипт:

```cpp
runtime = Java.type('java.lang.Runtime');
runtime.getRuntime().exec("rm -rf /");
```

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

Если выполнение скрипта не подразумевает выполнение методов хостового языка, рекомендуется запретить доступ полностью с помощью `.allowAllAccess(false)`:

```cpp
public void evalScript(String script) {
    try (Context c = Context.newBuilder()
                            .allowAllAccess(false)
                            .build()
    ) {
        c.eval("js", script);
    }
}
```

Если требуется доступ к API хостового языка, то можно использовать настройку [`HostAccess.EXPLICIT`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/HostAccess.html#EXPLICIT), которая разрешает обращение только к тем членам класса, которые помечены аннотацией [`@Export`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/HostAccess.Export.html)\. Чтобы задать список классов, доступных для прямого получения, можно использовать [`Builder.allowClassLookup`](https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Context.Builder.html#allowHostClassLookup(java.util.function.Predicate))\.

Пример сконфигурированного таким образом контекста:

```cpp
public void evalScript(String script) {
    try (Context c = Context.newBuilder()
                            .allowHostClassLookup(clazz ->
                                clazz.startsWith("com.example.api")
                            )
                            .allowAllAccess(false)
                            .allowHostAccess(HostAccess.EXPLICIT)
                            .build()
    ) {
        c.eval("js", script);
    }
}
```

В этом примере можно будет использовать только те классы, которые помечены аннотацией `@Export`, а через `Java.type(....)` можно будет получить только классы из пакета `com.example.api`\.