Конвейер архивации может стабильно работать несколько месяцев, но при этом сохранять в артефактах имя учётной записи сборки, каталог репозитория и даже название временной рабочей области. К типичным следам относятся /Users/runner/, DerivedData, пути к смонтированным томам и полные расположения файлов исходного кода. Обычно они напрямую не влияют на поведение приложения, однако раскрывают внутреннюю структуру всем, кто получает установочный пакет, файлы символов или журналы. Поскольку облачный Mac многократно используется разными задачами, проверка путей должна стать обязательным этапом перед выпуском, а не эпизодическим поиском строк.
Сначала определите границы проверяемых артефактов
В одной архивной сборке Xcode необходимо различать как минимум три типа объектов: предназначенное для распространения приложение .app, внутренний файл команды .dSYM и журналы конвейера. Связанные с ними риски нельзя оценивать одинаково.
Если в распространяемом приложении обнаружен реальный пользовательский каталог, такую находку следует считать высокоприоритетной. Пути к исходному коду в dSYM являются частью отладочной информации, поэтому удалять их только из-за самого факта наличия не следует. Настоящая проблема возникает, если файл по ошибке публикуется либо путь содержит идентификатор задачи, который не должен распространяться. Степень раскрытия журналов зависит от прав доступа и срока хранения, но даже в них не следует надолго сохранять каталоги с временными учётными данными и личные имена пользователей.
| Объект | Типичный источник пути | Рекомендуемое действие |
|---|---|---|
| Исполняемый файл приложения | Утверждения, отладочные строки, сгенерированный код | Блокировать сборку при обнаружении реального локального пути |
| dSYM | Каталог компиляции DWARF и пути к исходному коду | Сопоставить префиксы и повторно проверить символизацию |
| Журналы сборки | Вывод команд, скрипты, сообщения инструментов | Скрыть конфиденциальные данные и ограничить срок хранения |
| Вложения тестов | Снимки экрана, диагностические пакеты, пакеты результатов | Проверять отдельно перед архивацией |
Цель аудита путей — не удалить всю отладочную информацию, а предотвратить попадание реальной структуры каталогов машины сборки в контур распространения, где она не требуется.
Начинайте сканирование с чистого архива
Сначала зафиксируйте путь к архиву, чтобы скрипт сканирования сам не создавал случайные каталоги. Конфигурацию Release конвейер должен передавать явно, не полагаясь на Scheme, который в последний раз был выбран на машине разработчика.
set -euo pipefail
ARCHIVE="$PWD/output/App.xcarchive"
rm -rf "$ARCHIVE"
xcodebuild archive \
-workspace App.xcworkspace \
-scheme App \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath "$ARCHIVE"
Определив основной исполняемый файл приложения, используйте системную утилиту strings для поиска наиболее значимых признаков. Помимо /Users/, следует проверять /Volumes/, DerivedData, .xcworkspace и префиксы временных каталогов, которые команда действительно использует.
APP="$ARCHIVE/Products/Applications/App.app"
EXEC=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$APP/Info.plist")
BIN="$APP/$EXEC"
REPORT="$PWD/output/app-paths.txt"
strings -a "$BIN" |
grep -E '/Users/|/Volumes/|DerivedData|\.xcworkspace|\.xcodeproj' \
> "$REPORT" || true
if [ -s "$REPORT" ]; then
cat "$REPORT"
exit 1
fi
Успешная проверка основной программы не означает, что весь пакет не содержит утечек. Необходимо также обойти встроенные фреймворки, расширения и файлы ресурсов. В отчёте о сканировании следует указывать «путь к файлу, совпавшее содержимое, тип артефакта», но не загружать целиком двоичные файлы или переменные окружения непосредственно в журналы.
Проверяйте dSYM отдельно
При проверке dSYM основное внимание следует уделять DW_AT_comp_dir и записям о файлах исходного кода, а не общему количеству строк. Сначала найдите файл DWARF, а затем выведите записи, которые могут указывать на реальную рабочую область.
DSYM="$ARCHIVE/dSYMs/App.app.dSYM"
DWARF="$DSYM/Contents/Resources/DWARF/App"
xcrun dwarfdump --debug-info "$DWARF" |
grep -E 'DW_AT_(comp_dir|decl_file).*("/Users/|"/Volumes/)' \
> "$PWD/output/dsym-paths.txt" || true
xcrun dwarfdump --uuid "$DWARF"
UUID должен соответствовать исполняемому файлу из архива. Если значения не совпадают, последующее надёжное восстановление адресов сбоя будет невозможно даже при правильной обработке путей.
Скрывайте реальные каталоги с помощью сопоставления префиксов компиляции
Компилятор Swift позволяет заменить префикс рабочей области стабильным логическим каталогом с помощью -debug-prefix-map. В Clang для этого используется -fdebug-prefix-map. В конфигурацию Release проекта Xcode можно соответственно добавить:
OTHER_SWIFT_FLAGS = $(inherited) -debug-prefix-map $(SRCROOT)=/src
OTHER_CFLAGS = $(inherited) -fdebug-prefix-map=$(SRCROOT)=/src
OTHER_CPLUSPLUSFLAGS = $(inherited) -fdebug-prefix-map=$(SRCROOT)=/src
Не сопоставляйте весь каталог /Users целиком. Слишком широкое правило может скрыть происхождение внешних зависимостей и привести к тому, что разные каталоги случайно получат один логический путь. В первую очередь сопоставляйте $(SRCROOT). Если каталог извлечения зависимостей фиксирован, добавьте для него отдельное правило.
После настройки сопоставления необходимо заново создать архив. Нельзя просто изменить параметры сборки и повторно использовать прежний DerivedData. Также убедитесь, что параметры действительно присутствуют в командах компиляции: некоторые пользовательские скрипты обходят настройки проекта и вызывают компилятор напрямую.
Классифицируйте ложные срабатывания, а не разрешайте их все
При сканировании часто обнаруживаются примеры путей в ресурсах, тестовых фикстурах или сторонних отладочных строках. Решение следует принимать с учётом расположения и доступности находки, а не на основе постоянно расширяющегося глобального списка игнорируемых строк.
Рекомендуется выделить три уровня результатов:
- Если в распространяемом приложении или встроенном компоненте обнаружен реальный префикс текущей машины сборки, проверка немедленно завершается ошибкой.
- Если в dSYM обнаружен несопоставленный префикс исходного кода, проверка помечается как неуспешная, но файл сохраняется для диагностики.
- Если пути обнаружены во внутренних журналах или пакетах результатов тестирования, создаётся предупреждение и проверяется область доступа.
Каждое исключение должно быть точно задано в формате «файл + регулярное выражение + причина». Например, если тестовый ресурс действительно должен отображать /Users/example/, исключение можно ограничить только этим ресурсом. Не добавляйте весь префикс /Users/ в список игнорирования. Конвейер также должен динамически запрещать текущий путь к рабочей области — это надёжнее, чем пытаться угадать все возможные имена пользователей.
Не допускайте дополнительных утечек из скрипта сканирования
В отчёте реальный префикс можно заменить на $WORKSPACE, оставив только относительный путь и тип совпадения. При ошибке команды также не следует выводить всё окружение. Если исходный отчёт необходимо сохранить, разместите его как вложение сборки с ограниченным доступом, а не раскрывайте непосредственно в консольном выводе, доступном всем участникам.
Перед выпуском повторно проверьте символизацию
Успешное прохождение проверки путей после сопоставления ещё не означает, что цепочка отладки осталась работоспособной. Перед выпуском необходимо сохранить как минимум приложение, dSYM, список UUID и идентификатор коммита сборки, а затем выполнить тест символизации для реального адреса инструкции. Результат должен содержать имя функции и логический путь к исходному файлу вида /src/..., а не только шестнадцатеричный адрес.
Итоговый контроль можно свести к четырём условиям: в приложении отсутствует реальный префикс рабочей области; UUID файла dSYM совпадает с UUID двоичного файла; сопоставленные пути к исходному коду остаются распознаваемыми; исходное содержимое отчётов сканирования не раскрывается в журналах. Это уменьшает риск утечки сведений о структуре каталогов и одновременно сохраняет данные, необходимые для расследования сбоев в рабочей среде.
Аудит путей удобно запускать сразу после задачи архивации на облачном Mac VMOrbit. Он не зависит от фиксированного имени пользователя и не требует менять структуру каталогов исходного кода. Если корневой путь рабочей области единообразно передаётся конвейером, один набор правил сможет охватить как временные задачи, так и постоянные узлы сборки.
Часто задаваемые вопросы
Любой путь /Users/ в приложении считается уязвимостью?
Не всегда, но он может раскрыть имя учётной записи и структуру проекта. Сначала нужно определить, находится ли путь в распространяемом приложении, dSYM или внутреннем журнале.
Можно ли удалить dSYM после применения debug-prefix-map?
Нет. Преобразование префикса меняет только представление исходного пути. dSYM по-прежнему нужен, а символизацию следует проверить на реальном адресе.
Должна ли каждая найденная строка останавливать сборку?
Реальный локальный путь в распространяемом приложении должен блокировать выпуск. Находки в dSYM и внутренних журналах лучше сначала переводить в предупреждения.
Перенесите задачи сборки на выделенный облачный Mac
Выберите VMOrbit M4 или VMOrbit M4 Pro и узел с учётом расположения команды. Фактическая доступность и сведения о выдаче отображаются в консоли в реальном времени.