Server-Side Request Forgery [SSRF]

1. Введение:

Подделка запросов на стороне сервера (также известная как SSRF) - это уязвимость веб-безопасности, которая позволяет злоумышленнику заставить серверное приложение выполнять HTTP-запросы к произвольному домену по выбору злоумышленника.

При стандартной SSRF-атаке злоумышленник может заставить сервер установить соединение только с внутренними сервисами в инфраструктуре организации. В других случаях он может заставить сервер подключиться к произвольным внешним системам, что может привести к утечке конфиденциальных данных, таких как учетные данные для авторизации.

Успешная атака SSRF часто приводит к несанкционированным действиям или доступу к данным в организации, как в самом уязвимом приложении, так и в других внутренних системах, с которыми может взаимодействовать приложение. В некоторых ситуациях уязвимость SSRF может даже позволить злоумышленнику выполнить произвольную команду.

2. Типичный уязвимый код:

Вот пример того, как и почему существует уязвимость SSRF. Поскольку приведенный ниже код открывает ресурс, расположенный по заданному $url, без какой-либо санации или проверки, злоумышленник может манипулировать сервером, подделывая запрос к любому URL, который он пожелает.

<?php

    /**
    * Check if the 'url' GET variable is set
    *
    * Example request:
    *     http://localhost/?url=http://bobi.io/yakuhito.gif
    */
    if (isset($_GET['url'])){
        $url = $_GET['url'];
        
        /**
        * Send the request to the given
        * $url.
        */
        $image = fopen($url, 'rb');
        
        /**
        * Set the correct response headers.
        */
        header("Content-Type: image/png");
        
        /**
        * Return the content of the image.
        */
        fpassthru($image);
    }
...

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

3. Смягчение последствий:

3.1. Белые списки доменов HTTP-запросов:

Очевидным первым уровнем защиты является создание белого списка доменов, которые вы ЗНАЕТЕ, что ваше приложение должно запрашивать.

<?php
    # https://stackoverflow.com/questions/37069635/whitelisting-urls-in-php
    $whitelistDomains = [
        'safedomain.io',
        'anothersafe.com'
    ];
    
    function checkUrl($link, $whitelistDomains)
    {
    
        $urlData = parse_url($link);
    
        $domain = isset($urlData['host'])? $urlData['host'] : $link;
    
        if (in_array($domain,$whitelistDomains)){
            return true;
        }
        else{
            return false;
        }   
    
    }
    /**
    * Check if the 'url' GET variable is set
    *
    * Example request:
    *     http://localhost/?url=http://bobi.io/yakuhito.gif
    */
    if (isset($_GET['url'])){
        $url = $_GET['url'];
        
        /**
        * Validate the given url's domain
        */
        if(!checkUrl($url, $whitelistDomains)) {
            return;
        }
        /**
        * Send the request to the given
        * $url.
        */
        $image = fopen($url, 'rb');
        
        /**
        * Set the correct response headers.
        */
        header("Content-Type: image/png");
        
        /**
        * Return the content of the image.
        */
        fpassthru($image);
    }
...

Этого следует избегать, поскольку, как уже говорилось, вы, скорее всего, уже ЗНАЕТЕ, какие домены будете использовать для вызовов API. При этом вы можете адаптировать свой код для использования SDK (комплект для разработки программного обеспечения) для этого API или просто настроить маршруты для этих вызовов API в самом коде, а не брать их из параметра url.

3.2. Межсетевые экраны сетевого уровня:

Цель защиты сетевого уровня - не допустить, чтобы ваше приложение VulnerableApplication выполняло вызовы произвольных приложений. Для этого приложения будут доступны только разрешенные маршруты, чтобы ограничить его доступ к сети только теми, с которыми оно должно взаимодействовать.

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

В приведенной ниже схеме компонент Firewall используется для ограничения доступа приложения и, в свою очередь, для ограничения воздействия приложения, уязвимого к SSRF:

Помимо этого типа брандмауэра, можно использовать разделение сетей.

4. Выводы:

Как правило, веб-серверы не должны выполнять HTTP-запросы, если они не предназначены для выполнения конкретной задачи, например, для использования API и т. д. Исходя из этого, разработчику следует строго соблюдать белый список разрешенных доменов/сайтов, к которым должно обращаться его приложение; это также может быть обеспечено на сетевом уровне с помощью брандмауэров.

Last updated