Yandex Cloud
Поиск
Связаться с намиПопробовать бесплатно
  • Истории успеха
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
  • Marketplace
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Искусственный интеллект
    • Безопасность
    • Инструменты DevOps
    • Бессерверные вычисления
    • Управление ресурсами
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Калькулятор цен
    • Тарифы
    • Акции и free tier
  • Истории успеха
  • Документация
  • Блог
Проект Яндекса
© 2025 ООО «Яндекс.Облако»
Безопасность в Yandex Cloud
  • Ключевые принципы безопасности
  • Разделение ответственности за обеспечение безопасности
  • Соответствие требованиям
  • Меры безопасности на стороне Yandex Cloud
  • Средства защиты, доступные пользователям облачных сервисов
  • Фреймворк безопасной работы с агентами AI-SAFE
    • Удаление аккаунта на Яндексе из Yandex Identity Hub
    • Если вас атакуют с адресов Yandex Cloud
    • Поиск секретов Yandex Cloud в открытых источниках
  • Политика поддержки пользователей при проведении проверки уязвимостей
  • Бюллетени безопасности
  • Диапазоны публичных IP-адресов

В этой статье:

  • Партнерская программа поиска секретов Yandex Cloud
  • Механизм работы партнерской программы
  • Условия участия в программе
  • GitHub
  • GitLab
  • Поисковый индекс Яндекс
  • Helm-чарты в Yandex Cloud Marketplace
  • Как узнать, что секрет обнаружен
  • Что делать если секрет обнаружен
  • Самостоятельный поиск секретов
  • Регулярные выражения для поиска
  • Дополнительная валидация найденных секретов
  1. Инструкции
  2. Поиск секретов Yandex Cloud в открытых источниках

Поиск секретов Yandex Cloud в открытых источниках

Статья создана
Yandex Cloud
Обновлена 19 декабря 2025 г.
  • Партнерская программа поиска секретов Yandex Cloud
    • Механизм работы партнерской программы
    • Условия участия в программе
  • GitHub
  • GitLab
  • Поисковый индекс Яндекс
  • Helm-чарты в Yandex Cloud Marketplace
  • Как узнать, что секрет обнаружен
  • Что делать если секрет обнаружен
  • Самостоятельный поиск секретов
    • Регулярные выражения для поиска
    • Дополнительная валидация найденных секретов

Yandex Cloud ищет следующие типы секретов в открытых источниках:

  • API-ключи.
  • IAM Cookies.
  • IAM-токены.
  • Статические ключи доступа.
  • OAuth-токен.
  • Серверные ключи SmartCaptcha.
  • Refresh-токены.
  • Секреты OIDC-приложений.

Yandex Cloud подключен к следующим программам поиска секретов:

  • Партнерская программа поиска секретов Yandex Cloud.
  • GitHub Secret scanning partner program.
  • GitLab Secret Detection.
  • Поисковый индекс Яндекс.
  • Helm-чарты в Yandex Cloud Marketplace.

Партнерская программа поиска секретов Yandex CloudПартнерская программа поиска секретов Yandex Cloud

В Yandex Cloud действует собственная партнерская программа поиска скомпрометированных секретов в публичных репозиториях и других открытых источниках.

Вы можете присоединиться к партнерской программе поиска секретов Yandex Cloud, чтобы повысить безопасность ваших сервисов.

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

Механизм работы партнерской программыМеханизм работы партнерской программы

Для взаимодействия с Yandex Cloud в рамках партнерской программы используется сервисный аккаунт. При регистрации в программе вы передадите Yandex Cloud идентификатор вашего сервисного аккаунта и получите уникальный идентификатор leak_source, который будете использовать для взаимодействия с API.

Участвуя в партнерской программе поиска секретов Yandex Cloud, вы выполняете сканирование публичных репозиториев и других источников на наличие скомпрометированных секретов и передаете в Yandex Cloud данные о найденных ключах и токенах. Yandex Cloud проверяет полученные от вас секреты.

Взаимодействие с API Yandex Cloud происходит в два этапа:

  1. Вы регулярно запрашиваете в Yandex Cloud актуальный список регулярных выражений, соответствующих известным типам секретов:

    • Эндпоинт запроса: https://leak-detector.yandexcloud.net/secret-types.

    • Метод запроса: GET.

    • Пример запроса:

      curl \
        --request GET \
        --header "Authorization: Bearer <IAM-токен>" \
        "https://leak-detector.yandexcloud.net/secret-types?leak_source_id=<идентификатор_leak_source>"
      

      Где:

      • <IAM-токен> — IAM-токен, полученный для зарегистрированного в партнерской программе сервисного аккаунта.
      • <идентификатор_leak_source> — уникальный идентификатор, полученный при регистрации в партнерской программе.
    Пример ответа:
    [
      {
        "type": "yandex_cloud_api_key_v1",
        "regex_matcher": "AQW9[A-Za-z0-9_-]{35,38}"
      },
      {
        "type": "yandex_cloud_iam_access_secret",
        "regex_matcher": "YC[a-zA-Z0-9_\\-]{38}"
      },
      {
        "type": "yandex_cloud_iam_cookie_v1",
        "regex_matcher": "c1\\.[A-Z0-9a-z_-]{200,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,910}[=]{0,2}\\.[A-Z0-9a-z_-]{86}[=]{0,2}"
      },
      {
        "type": "yandex_cloud_iam_key_v1",
        "regex_matcher": "PLEASE DO NOT REMOVE THIS LINE\\! Yandex\\.Cloud SA Key ID (<|(\\\\u003[cC]))([0-9a-zA-Z+/=]*)(>|(\\\\u003[eE]))(\\s+)(-----BEGIN PRIVATE KEY-----(\\s+)([0-9a-zA-Z+/=]{64}(\\s+))*([0-9a-zA-Z+/=]{1,63}(\\s+))?-----END PRIVATE KEY-----\\s?)"
      },
      {
        "type": "yandex_cloud_iam_refresh_token_v1",
        "regex_matcher": "rt1\\.[A-Z0-9a-z_-]{200,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,910}[=]{0,2}\\.[A-Z0-9a-z_-]{86}[=]{0,2}"
      },
      {
        "type": "yandex_cloud_iam_token_v1",
        "regex_matcher": "t1\\.[A-Z0-9a-z_-]{200,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,1000}[A-Z0-9a-z_-]{0,910}[=]{0,2}\\.[A-Z0-9a-z_-]{86}[=]{0,2}"
      },
      {
        "type": "yandex_cloud_lockbox_secret_v1",
        "regex_matcher": "(yc|YC)[!-~]{18,254}"
      },
      {
        "type": "yandex_cloud_smartcaptcha_server_key",
        "regex_matcher": "ysc2_[a-zA-Z0-9]{40}[0-9a-f]{8}"
      },
      {
        "type": "yandex_passport_oauth_token",
        "regex_matcher": "y[0-6]_[-_A-Za-z0-9]{55,199}"
      }
    ]
    
  2. Вы сканируете ваши данные на предмет поиска соответствий полученному списку регулярных выражений. При обнаружении таких соответствий вы отправляете данные о них в Yandex Cloud для проверки:

    • Эндпоинт запроса: https://leak-detector.yandexcloud.net/suspects.

    • Метод запроса: POST.

    • Пример запроса:

      curl \
        --request POST \
        --header "Content-Type: application/json" \
        --header "Authorization: Bearer <IAM-токен>" \
        --data \
                '''
                {
                  "leak_source_id": "my_leak_source",
                  "suspects": [
                    {
                      "data_type": "yandex_cloud_lockbox_secret_v1",
                      "uri": "https://www.example.com/vcs/sources/project1/my_data.yaml",
                      "payload": "ycBHKGefu78t^%RD3gre387HO"
                    },
                    {
                      "data_type": "yandex_cloud_iam_token_v1",
                      "uri": "https://www.example.com/vcs/sources/project2/my_data.yaml",
                      "payload": "t1.Aga0BCD123efGhIjkLmNoPqRsTuVwXyZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
                    }
                  ]
                }
                ''' \
        "https://leak-detector.yandexcloud.net/suspects"
      

      Где:

      • <IAM-токен> — IAM-токен, полученный для зарегистрированного в партнерской программе сервисного аккаунта.
      • <идентификатор_leak_source> — уникальный идентификатор, полученный при регистрации в партнерской программе.
      • suspects — список объектов, каждый из которых содержит информацию об одном найденном соответствии регулярному выражению.
      • data_type — тип секрета, как он указан в ответе на GET-запрос при получении списка регулярных выражений.
      • uri — URI ресурса, на котором обнаружена потенциальная утечка.
      • payload — тело (содержимое) найденного секрета.
    • Пример ответа:

      ["NOT_CONFIRMED","CONFIRMED"]
      

      Ответ содержит список статусов. Количество и порядок возвращенных в ответе статусов соответствует количеству и порядку секретов, отправленных в GET-запросе в объекте suspects.

      Возможные статусы:

      • NOT_CONFIRMED — обнаруженный случай соответствия регулярному выражению не является секретом.
      • CONFIRMED — обнаруженный случай соответствия регулярному выражению является секретом.
      • TEMPORARILY_UNAVAILABLE — провайдер секретов недоступен. Повторите запрос в отношении данного секрета позднее с применением алгоритма экспоненциальной выдержки.

Условия участия в программеУсловия участия в программе

Партнерская программа поиска секретов Yandex Cloud действует в течение периода, установленного при вашем присоединении к ней. При отсутствии с вашей стороны заявления о выходе из программы ее действие продлевается на один год. Количество таких продлений не ограничено.

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

Как присоединиться к программе

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

GitHubGitHub

Yandex Cloud подключен к secret scanning partner program, чтобы уменьшить риски пользователей от утечек секретов в публичные репозитории.

По умолчанию GitHub ищет секреты Yandex Cloud в публичных репозиториях и отправляет все подозрительные фрагменты в Yandex Cloud.

В публичных репозиториях поиск выполняется автоматически. Включить secret scanning для приватного репозитория может администратор репозитория или владелец организации.

GitLabGitLab

Стандартный список шаблонов секретов для Secret Detection включает секреты Yandex Cloud.

Чтобы включить Secret Detection для вашего проекта, следуйте инструкции.

Поисковый индекс ЯндексПоисковый индекс Яндекс

Yandex Cloud по умолчанию ищет секреты на страницах, которые проиндексированы поиском Яндекс.

Helm-чарты в Yandex Cloud MarketplaceHelm-чарты в Yandex Cloud Marketplace

Yandex Cloud по умолчанию ищет секреты в Helm-чартах, доступных в Yandex Cloud Marketplace.

Как узнать, что секрет обнаруженКак узнать, что секрет обнаружен

Если будет обнаружен валидный секрет, владельцу организации придет письмо c адреса технической поддержки Yandex Cloud. Письмо будет содержать часть обнаруженного секрета и адрес в интернете, где секрет был обнаружен.

Также Identity and Access Management запишет в аудитный лог событие DetectLeakedCredential.

Что делать если секрет обнаруженЧто делать если секрет обнаружен

Если ваш секрет попал в публичный репозиторий:

  1. Перевыпустите или отзовите секрет по инструкции. Удалите затронутые ресурсы при необходимости.
  2. Удалите секрет из репозитория и истории коммитов по инструкции для GitHub или GitLab.

Важно

Yandex Cloud не отзывает найденные секреты и не удаляет их из репозитория. Все действия над секретом выполняет только владелец секрета.

Самостоятельный поиск секретовСамостоятельный поиск секретов

Регулярные выражения для поискаРегулярные выражения для поиска

Вы можете использовать следующие регулярные выражения, чтобы самостоятельно проверять свои репозитории:

  • IAM Cookies

    c1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}
    
  • IAM-токены

    t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}
    
  • API-ключи

    AQVN[A-Za-z0-9_\-]{35,38}
    
  • Статические ключи доступа

    YC[a-zA-Z0-9_\-]{38}
    
  • OAuth-токены

    y[0-6]_[-_A-Za-z0-9]{55,199}
    
  • Серверные ключи SmartCaptcha

    ysc2_[a-zA-Z0-9]{40}[0-9a-f]{8}
    
  • Refresh-токены

    rt1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2}
    
  • Секреты OIDC-приложений

    yccs__[0-9a-f]{64}_[0-9a-f]{8}
    

Примечание

С осторожностью используйте регулярные выражения, так как со временем форматы секретов могут измениться. В документации эти изменения могут отразиться с задержкой.

Дополнительная валидация найденных секретовДополнительная валидация найденных секретов

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

  • OAuth-токены

    Go
    package main
    
    import (
        "encoding/base64"
        "fmt"
        "os"
        "strconv"
        "hash/crc32"
    )
    
    const (
        statefulMaskLen  = 40
        maxShard         = 16
    )
    
    func isNotValidEnvironmentType(token string) bool {
        n, err := strconv.Atoi(token[1:2])
        if err != nil {
            return true
        }
        if 0 <= n && n <= 6 {
            return false
        }
        return true
    }
    
    func isStatefulToken(token string) bool {
        if isNotValidEnvironmentType(token) {
            return false
        }
    
        decoded, err := base64.RawURLEncoding.DecodeString(token[3:])
        if err != nil {
            return false
        }
    
        crc := uint32(0)
        for i := 0; i < 4; i++ {
            crc <<= 8
            crc |= uint32(decoded[i+(len(decoded)-4)])
        }
    
        if crc != crc32.Checksum(decoded[:len(decoded)-4], crc32.MakeTable(crc32.IEEE)) {
            return false
        }
    
        return true
    }
    
    func fatalf(msg string, a ...interface{}) {
        _, _ = fmt.Fprintf(os.Stderr, "oauth_filter: " + msg + "\n", a...)
        os.Exit(1)
    }
    
    func main() {
        fmt.Println(isStatefulToken("<TOKEN>"))
    }
    
  • Статические ключи доступа

    Go
    package main
    
    import (
        base64 "encoding/base64"
        "encoding/binary"
        "fmt"
        "hash/crc32"
        "strings"
    )
    
    const (
        YcPrefix = "YC"
    )
    
    func checkStaticCred(token string) bool {
        if !strings.HasPrefix(token, YcPrefix) {
            return false
        }
    
        decoded, err := base64.RawURLEncoding.DecodeString(token)
        if err != nil {
            return false
        }
    
        // CRC32-C checksum
        calculatedChecksum := crc32.Checksum(decoded[0:len(decoded)-4], crc32.MakeTable(crc32.Castagnoli))
        checksum := binary.BigEndian.Uint32(decoded[len(decoded)-4:])
    
        return calculatedChecksum == checksum
    }
    
    func main() {
        // ^YC[a-zA-Z0-9_\-]{38}$ - regexp
        fmt.Println(checkStaticCred("<TOKEN>"))
        fmt.Println(checkStaticCred("<TOKEN>"))
    }
    
  • Серверные ключи SmartCaptcha

    Go
    Python
    package main
    
    import (
        "fmt"
        "hash/crc32"
    )
    
    func isValidToken(token string) bool {
        calculatedChecksum := crc32.Checksum([]byte(token[:len(token)-8]), crc32.MakeTable(crc32.IEEE))
    
        return token[len(token)-8:] == fmt.Sprintf("%08x", calculatedChecksum)
    }
    
    func main() {
        fmt.Println(isValidToken("ysc2_D0ur60kwXTL7rM52UzJ7Vi5D7a5Qu48zktqy0fE0********"))
    }
    
    import re
    import zlib
    
    def is_valid_secret(secret):
        if not re.match("ysc2_[a-zA-Z0-9]{40}[0-9a-f]{8}", secret):
            return False
    
        if secret[-8:] != "%08x" % zlib.crc32(secret[:-8].encode()):
            return False
    
        return True
    
    print(is_valid_secret("ysc2_D0ur60kwXTL7rM52UzJ7Vi5D7a5Qu48zktqy0fE0********")) # True
    
  • Секреты OIDC-приложений

    Go
    Java
    package main
    
    import (
      "encoding/binary"
      "encoding/hex"
      "fmt"
      "regexp"
    
      "github.com/spaolacci/murmur3"
    )
    
    func ValidateOauthClientSecret(str string) bool {
      re := regexp.MustCompile(`yccs__[0-9a-f]{64}_[0-9a-f]{8}`)
      if !re.MatchString(str) {
        return false
      }
    
      prefix := str[:71]
      suffix := str[71:]
    
      hash := murmur3.Sum32([]byte(prefix))
    
      hashBytes := make([]byte, 4)
      binary.BigEndian.PutUint32(hashBytes, hash)
    
      expectedSuffix := hex.EncodeToString(hashBytes)
      return suffix == expectedSuffix
    }
    
    func main() {
      test := "<SECRET>"
      isValid := ValidateOauthClientSecret(test)
      if isValid {
        fmt.Println("Secret is valid.")
      } else {
        fmt.Println("Secret isn't valid")
      }
    }
    
    package yandex.cloud.leakdetector.server.provider;
    
    import org.apache.commons.codec.binary.Hex;
    import org.apache.commons.codec.digest.MurmurHash3;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.util.regex.Pattern;
    
    public class Main {
        private static final Pattern SECRET_PATTERN = Pattern.compile("yccs__[0-9a-f]{64}_[0-9a-f]{8}");
    
        public static boolean validateOauthClientSecret(String str) {
            if (!SECRET_PATTERN.matcher(str).matches()) {
                return false;
            }
    
            String prefix = str.substring(0, 71);
            String suffix = str.substring(71);
    
            String hashHex = hashStringMurmur3(prefix);
            return suffix.equals(hashHex);
        }
    
        private static String hashStringMurmur3(String str) {
            int intHashValue = MurmurHash3.hash32x86(str.getBytes());
            return Hex.encodeHexString(
                    ByteBuffer.allocate(4)
                            .order(ByteOrder.BIG_ENDIAN)
                            .putInt(intHashValue)
                            .array()
            );
        }
    
        public static void main(String[] args) {
            String test = "<SECRET>";
            boolean isValid = validateOauthClientSecret(test);
            if (isValid) {
                System.out.println("Secret is valid.");
            } else {
                System.out.println("Secret isn't valid");
            }
        }
    }
    

Была ли статья полезна?

Предыдущая
Если вас атакуют с адресов Yandex Cloud
Следующая
Политика поддержки пользователей при проведении проверки уязвимостей
Проект Яндекса
© 2025 ООО «Яндекс.Облако»