# V5334. OWASP. Possible server-side request forgery. Potentially tainted data in the URL is used to access a remote resource.

Анализатор обнаружил обращение к удалённому ресурсу без проверки предоставленного пользователем URL-адреса. Использование непроверенных внешних данных для формирования адреса может стать причиной возникновения Server-Side Request Forgery.

Уязвимости такого типа относятся к категории рисков OWASP Top 10 Application Security Risks 2021:

- A10:2021 – Server-Side Request Forgery (SSRF)

Приведём пример:

    public static class UrlController {
      private final String BASE_URL = "http://localhost/";

      protected void connect(HttpServletRequest req) throws IOException {
        String filter = req.getParameter("filter");
        URL url = new URL(BASE_URL + filter);
        url.openConnection();                      // <=
        //....
      }
    }

В данном примере переменная `filter` может содержать заражённые данные, так как они приходят из внешнего источника и участвуют в формировании запроса, отправляемого от имени сервера на ресурс, адрес которого записан в переменной `BASE_URL`.

Таким образом, злоумышленник получает возможность совершать вредоносные действия, отправляя запросы к ресурсам, прямой доступ к которым у него отсутствует.

Злоумышленник может записать в переменную `filter` следующий текст:

    admin/delete?username=testSSRF

Тогда итоговый запрос будет иметь следующий вид:

    http://localhost/admin/delete?username=testSSRF

При выполнении запроса с таким адресом злоумышленник может удалить пользователя.

Также стоит заметить, что при борьбе с SSRF не стоит использовать запрещённый список или регулярные выражения. Злоумышленник может легко обойти эти ограничения:

- Перенаправление — злоумышленник может создать внешний ресурс, который в качестве ответа перенаправляет на другой URL.
- Альтернативные представления:

    http://2130706433/ = http://127.0.0.1
    http://0x7f000001/ = http://127.0.0.1

Пример борьбы с SSRF с использованием проверки предоставленных данных:

    public static class UrlController {
      private final String BASE_URL;
      private final List<URL> whitelist;

      protected void connect(HttpServletRequest req) throws IOException {
        URL url = new URL(BASE_URL + req.getParameter("filter"));
        if (whiteList.contains(url)) {                    // <=
          url.openConnection();
          //....
        }
      }
    }

Также можно использовать специальные URL-кодировщики, которые экранируют запрос. Например, пользователь может передать следующую строку как параметр:

    ../admin/secure-info

Код, который формирует запрос на сторонний ресурс, выглядит следующим образом:

    private final static String INTERNAL_URL = "http://localhost/service/";
    protected void connect(HttpServletRequest req) throws IOException {
      String filter = req.getParameter("filter");
      URL url = new URL(INTERNAL_URL + filter);
      url.openConnection();                       // <=
      //....
    }

В случае, если символ `../` никак не экранируется, итоговый запрос на сторонний ресурс принимает вид:

    http://localhost/admin/secure-info

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

Чтобы защититься от таких атак, следует экранировать запрос пользователя. Пример безопасного кода:

    private final static String INTERNAL_URL = "http://localhost/service/";
    protected void connect(HttpServletRequest req) throws IOException {
      String filter = req.getParameter("filter");
      String encodedFilter = URLEncoder.encode(filter, "UTF_8");            // <=
      URL url = new URL(INTERNAL_URL + encodedFilter);
      url.openConnection();
      //....
    }

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки непроверенного использования чувствительных данных (ввода пользователя, файлов, сети и пр.).

Данная диагностика классифицируется как:

CWE-918 OWASP-5.2.6