Рубрики
Без рубрики

Как сканировать локальные файлы для секретов в Python с помощью GitGuardian API

Вы, сколько секретов, как ключи API или учетные данные, скрыты в ваших локальных файлах? Сегодня мы … Помечено Python, безопасность.

Вы, сколько секретов, как ключи API или учетные данные, скрыты в ваших локальных файлах? Сегодня мы собираемся показать вам, как вы можете сканировать файлы и каталоги для конфиденциальной информации, такой как секреты. Чтобы выполнить это, мы будем использовать GitGuardian API и Python Wrapper. К концу этого учебника вы поймете, как работает API, чтобы вы могли начать строить свои собственные, настраиваемые секреты обнаружения сценариев.

Что сделает наш скрипт

Мы создадим сценарий Python, который сканирует все файлы в локальном каталоге для секретов. Для этого мы будем использовать Gitguardian API и обертку API Python, мы рекомендуем рассмотреть эти ресурсы перед началом.

Наш сценарий будет:

  • Обнаружить секреты и другие разрывы политики из вашего файлового каталога.
  • Распечатайте имя файла, перерыв на политику и соответствия для всех слоев политики.
  • Выведите результат к формату JSON.

Получить настройку

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

Установка GitGuardian Python API-клиент

Установите клиент Gitguardian Python API, используя De Facto Package Manager «PIP».

В вашем терминале или командной строке выполните команду:

pip3 install --upgrade pygitguardian

Получение токена Gitguardian API

Подпишитесь на бесплатную учетную запись Developer от GitGuardian, используя учетную запись GitHub или электронную почту на https://dashboard.gitguardian.com Отказ

В меню перейдите на вкладку «API», прокрутите «Создать новую клавишу API» и выберите «Создать новую клавишу API». Убедитесь, что вы придаете ему соответствующее имя.

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

Настройка каталога и файлов

Откройте свой терминал или командную строку.

Создайте новый каталог в локальном вы хотите сохранить свой скрипт:

mkdir  directory-scan

Введите каталог, используя:

cd  directory-scan

Настройка переменных среды

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

Я рекомендую использовать инструмент под названием Python-dotenv Что позволит вам импортировать переменные среды, или вы можете установить токен API в вашей консоли.

Создайте новый файл под названием .env:

touch .env

Откройте этот файл в выбранном текстовом редакторе и создайте переменную для хранения нашего API:

Gg_api_key = ** Вставьте токен API * *

Написание нашего скрипта

Импортировка модулей и настройки нашего клиента

Далее давайте создадим файл под названием Directory_Scan.py:

touch directory_scan.py

Откройте этот файл с выбранным выбранным текстовым редактором.

Сначала нам нужно импортировать модули, которые нам нужны:

import  glob
import  os
import  sys
import  traceback

В дополнение к стандартным модулям. Мы также будем импортировать и использовать « » шаблон ‘. Это позволит нам получить путь и имена файлов всех файлов в нашем каталоге.

Импорт переменных среды

Если вы используете Python-Dotenv, то нам нужно загрузить в нашем токене API из нашего файла .env и используйте токен API внутри:

from  dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GG_API_KEY")

Теперь, благодаря load_dotenv () Вы сможете получить Gg_api_key таким образом и хранить его в переменной.

Импорт наших модулей клиентских модулей GitGuardian API

Следующая загрузка клиента GitGuardian API.

from pygitguardian import GGClient
from pygitguardian.config import MULTI_DOCUMENT_LIMIT

«GGClient» – это основной модуль для нашего API-клиента, он будет обрабатывать данные, которые мы сканируем, отправьте его на двигатель сканирования GitGuardian и получать результаты.

GitGuardian API позволяет максимально использовать 20 файлов или общий размер 2 МБ для каждого запроса для асинхронного сканирования. Наше Multi_document_limit Модуль импортирует эти параметры, поэтому мы не отправляем запросы Invaild на сервер.

Это не означает, что вы можете сканировать только 20 файлов одновременно. Наш скрипт будет справиться с этим, нарушив файлы в «кусочки», которые соответствуют максимальным требованиям API и отправляют несколько запросов перед сопоставлением информации в конце.

Теперь нам просто нужно инициализировать GGClient, прикрепляя нашу клавишу API:

# Initializing GGClient
client = GGClient(api_key=API_KEY) 

Загрузка файлов в массив

Теперь нам нужно загрузить все пути файлов и файлов в нашем текущем каталоге. Наш сценарий рекурсивно сканирует из рабочего каталога (каталог, из которого называется сценарий):

# Create a list of dictionaries for scanning
to_scan = []
for name in glob.glob("**/*", recursive=True):
    if ".env" in name: or os.path.isdir(name):
        continue
    with open(name) as fn:
        to_scan.append({"document": fn.read(), "filename": os.path.basename(name)})) 

Модуль «Глоба» позволяет нам создать список файлов и имен путей, которые мы добавим в массив под названием to_scan Таким образом, мы можем отсканировать их.

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

Это будет просматривать файлы рекурсивно (из рабочего каталога сценарий внутри), но если вы хотите сканировать другой каталог, вы можете добавить в путь к файлу.

Пример Для имени в Glob.glob («Пользователи \ User \ Documents \ **»,):

Если вы хотите проверить свой код до сих пор. На новой строке добавьте «Печать (to_scan)». Вы должны получить список всех файлов и их содержимое в текущем каталоге. Комментировать или удалить, прежде чем продолжить.

Процесс файлы в «Кусках» и сделав запрос API

Как уже упоминалось ранее, API будет принимать только 20 файлов на запрос на максимум 1 МБ на файл. Поэтому мы собираемся распустить наши файлы в приемлемые кусочки для отправки в качестве запроса:

# Process in a chunked way to avoid passing the multi document limit
to_process = []
for i in range(0, len(to_scan), MULTI_DOCUMENT_LIMIT):
   chunk = to_scan[i : i + MULTI_DOCUMENT_LIMIT]
   try:
       scan = client.multi_content_scan(chunk)
   except Exception as exc:
       # Handle exceptions such as schema validation
       traceback.print_exc(2, file=sys.stderr)
       print(str(exc))
   if not scan.success:
       print("Error scanning some files. Results may be incomplete.")
       print(scan)
   to_process.extend(scan.scan_results)

Во-первых, создайте пустой массив, чтобы удерживать результаты сканирования из API, мы называем этот массив to_process Отказ

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

Диапазон (start_value, end_value, шаг)

Мы собираемся загрузить текущие значения нашего массива в переменную, называемую «кусок».

Использование блока попробовать, мы сканируем наш текущий кусок, используя Команда Multi Content Scan клиента GG API.

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

Трассировка покажет точную строку, которую она не удалась.

Давайте добавим в сообщение в сценарии, наш сканирование не удается.

Наконец, мы собираемся добавить наши результаты сканирования на наш массив ‘to_process’.

FAQ: Если мне нужно сканировать 200 файлов, будет ли этот счет как 1 или 10 запросов API на мою панель приборной панели? Это будет рассчитывать на 10, но не волнуйтесь, у вас есть 1000 запросов API в месяц.

Результаты печати

Теперь мы будем петлю через наши результаты. Если нарушение политики обнаружено, что он будет захвачен .has_secrets. Тег Если это правда, мы распечатаем этот результат:

# Printing the results
for i, scan_result in enumerate(to_process):
   if scan_result.has_policy_breaks:
       print(f"{chunk[i]['filename']}: {scan_result.policy_break_count} break/s found")
Now we will loop through our results. If a policy break is detected it will be captured by the .has_policies_breaks tag, if this is true, we will print that result.

Код CheckPoint 1.

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

import  glob
import  os
import  sys
import  traceback
from  dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GG_API_KEY") 

from pygitguardian import GGClient
from pygitguardian.config import MULTI_DOCUMENT_LIMIT

# Initializing GGClient
client = GGClient(api_key=API_KEY) 

# Create a list of dictionaries for scanning
to_scan = []
for name in glob.glob("**/*", recursive=True):
    with open(name) as fn:
        to_scan.append({"document": fn.read(), "filename": os.path.basename(name)})) 

# Process in a chunked way to avoid passing the multi document limit
to_process = []
for i in range(0, len(to_scan), MULTI_DOCUMENT_LIMIT):
   chunk = to_scan[i : i + MULTI_DOCUMENT_LIMIT]
   try:
       scan = client.multi_content_scan(chunk)
   except Exception as exc:
       # Handle exceptions such as schema validation
       traceback.print_exc(2, file=sys.stderr)
       print(str(exc))
   if not scan.success:
       print("Error scanning some files. Results may be incomplete.")
       print(scan)
   to_process.extend(scan.scan_results)

# Printing the results
for i, scan_result in enumerate(to_process):
   if scan_result.has_secrets:
       print(f"{chunk[i]['filename']}: {scan_result.policy_break_count} break/s found")

Запуск скрипта

Теперь мы готовы запустить наше первое сканирование каталога.

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

Переместите файл directory_scan.py в каталог, который вы хотите сканировать.

Откройте свой терминал, перейдите к каталогу и запустите команду:

python3 directory_scan.py

Поздравляем, вы просто отсканировали ваш каталог для перерывов политики!

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

main.py: 1 break/s found
sample.yaml: 1 break/s found

Теперь мы знаем, какие файлы имеют перерывы политики.

Но мы не знаем, является ли поломка политики секретным, и мы не знаем, какой это секрет. Поэтому дальше мы добавим дополнительные детали в наши результаты.

Отображение дополнительной информации

Включая тип перерыва политики и соответствия

Теперь мы обнаружили перерывы политики, мы, возможно, пожелали узнать, какие перерывы политики были обнаружены, например, это был разветвлен токен, ключ AWS или политику имени файла, которая была нарушена.

Давайте добавим строку на выходе, которая сообщает нам, какие перерывы политики были нарушены.

Вы можете найти больше информации о перерывах политики в Gitguardian щиток приборов

 # Printing the results
for i, scan_result in enumerate(to_process):
   if scan_result.has_policy_breaks:
       print(f"{chunk[i]['filename']}: {scan_result.policy_break_count} break/s found")
       # Printing policy break type
       for  policy_break in scan_result.policy_breaks:
           print(f"\t{policy_break.break_type}:")

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

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

    main.py: 1 break/s found
        AWS Key: 
    sample.yaml: 1 break/s found
        Google API Key:

Добавление матчей

Не всегда подходит печатать матчи, которые мы находим, но в случае этого примера мы будем делать только это.

Мы собираемся создать другой для цикла, снова вложенный. Теперь мы собираемся позвонить на тег «Match» из GG и распечатайте это. Это даст нам нашу политику.

 # Printing the results
for i, scan_result in enumerate(to_process):
   if scan_result.has_policy_breaks:
       print(f"{chunk[i]['filename']}: {scan_result.policy_break_count} break/s found")
       # Printing policy break type
       for  policy_break in scan_result.policy_breaks:
           print(f"\t{policy_break.break_type}:")
           # Printing matches
           for match in policy_break.matches:
                print(f"\t\t{match.match_type}:{match.match}")

Давайте запустим это снова, и теперь мы должны получить

  • Имя файла и количество разрывов политики.
  • Типы нарушений политики (секреты, если таковые имеются).
    main.py: 1 break/s found
        AWS Key: *********************************
    sample.yaml: 1 break/s found
        Google API Key: *****************************

Получение вывода как JSON

Теперь скажем, нам нужно выводить эти результаты в формате JSON.

API встроен в функциональность для преобразования результатов в формат JSON.

Давайте проведем наши файлы, и если наши результаты сканирования имеют политические разрывы внутри них, мы распечатаем их в JSON.

  #Getting results in JSON format           
for i, scan_result in enumerate(to_process):
   if scan_result.has_policy_breaks:
       print(scan_result.to_json())

CheckPoint 2.

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

import  glob
import  os
import  sys
import  traceback
from  dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("GG_API_KEY") 

from pygitguardian import GGClient
from pygitguardian.config import MULTI_DOCUMENT_LIMIT

# Initializing GGClient
client = GGClient(api_key=API_KEY) 

# Create a list of dictionaries for scanning
to_scan = []
for name in glob.glob("**/*", recursive=True):
    with open(name) as fn:
        to_scan.append({"document": fn.read(), "filename": os.path.basename(name)})) 

# Process in a chunked way to avoid passing the multi document limit
to_process = []
for i in range(0, len(to_scan), MULTI_DOCUMENT_LIMIT):
   chunk = to_scan[i : i + MULTI_DOCUMENT_LIMIT]
   try:
       scan = client.multi_content_scan(chunk)
   except Exception as exc:
       # Handle exceptions such as schema validation
       traceback.print_exc(2, file=sys.stderr)
       print(str(exc))
   if not scan.success:
       print("Error scanning some files. Results may be incomplete.")
       print(scan)
   to_process.extend(scan.scan_results)

# Printing the results
for i, scan_result in enumerate(to_process):
   if scan_result.has_secrets:
       print(f"{chunk[i]['filename']}: {scan_result.policy_break_count} break/s found")
       # Printing policy break type
       for  policy_break in scan_result.policy_breaks:
           print(f"\t{policy_break.break_type}:")
           # Printing matches
           for match in policy_break.matches:
                print(f"\t\t{match.match_type}:{match.match}")

#Getting results in JSON format    
for i, scan_result in enumerate(to_process):
   if scan_result.has_policy_breaks:
       print(scan_result.to_json())

Предупреждение

Обратите внимание, что вы должны сканировать только для секретов в местах, которые они не должны существовать и отменить какие-либо найденные. Как правило, любые секреты в том, что в конечном итоге в удаленные места, не предназначенные для обеспечения безопасности чувствительных данных, должны считаться скомпрометированными. Это включает в себя использование GitGuardian API.

Следующие шаги

Теперь, когда вы создали свой первый скрипт, используя GitGuardian API и Wrapper Python, вы можете создавать свои собственные удивительные сценарии для сканирования файлов.

Следующий учебник поможет вам сканировать файлы предварительно совершить или в CI.

Любые вопросы на API, пожалуйста, напишите нам, mackenzie.jackson@gitguardian.com Отказ

Оригинал: “https://dev.to/cuireuncroco/how-to-scan-local-files-for-secrets-in-python-using-the-gitguardian-api-190h”