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

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

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

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

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

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

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

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

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

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 ТОО «Облачные Сервисы Казахстан»