Eine Archivierungspipeline kann über Monate stabil laufen und dennoch das Build-Konto, das Repository-Verzeichnis oder sogar den Namen eines temporären Arbeitsverzeichnisses in Artefakte schreiben. Typische Spuren sind /Users/runner/, DerivedData, Pfade zu eingebundenen Volumes und vollständige Speicherorte von Quelldateien. Sie verändern das Verhalten der App in der Regel nicht direkt, legen aber gegenüber Personen mit Zugriff auf Installationspakete, Symboldateien oder Protokolle interne Strukturen offen. Da Cloud-Macs wiederholt für unterschiedliche Aufträge verwendet werden, sollte die Pfadprüfung ein fester Schritt vor jeder Veröffentlichung sein und nicht nur gelegentlich als einfache Zeichenfolgensuche ausgeführt werden.
Umfang der zu prüfenden Artefakte festlegen
Bei einem Xcode-Archiv müssen mindestens drei Objektklassen getrennt betrachtet werden: die für die Verteilung vorgesehene .app, die intern im Team verbleibende .dSYM und die Pipeline-Protokolle. Ihre Risiken dürfen nicht pauschal zusammen bewertet werden.
Ein echtes Benutzerverzeichnis in einer verteilbaren App ist mit hoher Priorität zu behandeln. Dass eine dSYM-Datei Quellcodepfade enthält, gehört zu den Debug-Informationen und ist allein kein Grund, sie zu löschen. Problematisch wird es erst, wenn die Datei versehentlich veröffentlicht wird oder ihre Pfade Auftragskennungen enthalten, die nicht weitergegeben werden dürfen. Wie groß die Angriffsfläche von Protokollen ist, hängt von den Leseberechtigungen und der Aufbewahrungsdauer ab. Verzeichnisse mit temporären Anmeldedaten und persönliche Benutzernamen sollten dort dennoch nicht langfristig gespeichert werden.
| Objekt | Typische Pfadquelle | Empfohlene Maßnahme |
|---|---|---|
| Ausführbare App-Datei | Assertions, Debug-Zeichenfolgen, generierter Code | Bei einem Treffer für einen echten lokalen Pfad blockieren |
| dSYM | DWARF-Kompilierungsverzeichnis und Quellcodepfade | Präfixe abbilden und Symbolizierung erneut prüfen |
| Build-Protokolle | Befehlsausgabe, Skripte, Werkzeugausgaben | Bereinigen und Aufbewahrungsdauer begrenzen |
| Testanhänge | Screenshots, Diagnosepakete, Ergebnispakete | Vor der Archivierung separat prüfen |
Ziel einer Pfadprüfung ist nicht, sämtliche Debug-Informationen zu entfernen. Sie soll verhindern, dass die reale Verzeichnisstruktur der Build-Maschine in einen Distributionsbereich gelangt, in dem sie nicht benötigt wird.
Mit einem sauberen Archiv beginnen
Zunächst sollte ein fester Archivpfad vorgegeben werden, damit das Prüfskript nicht selbst zufällige Verzeichnisse erzeugt. Die Release-Konfiguration muss von der Pipeline explizit übergeben werden, statt sich auf den zuletzt auf dem Entwicklungsrechner ausgewählten Scheme-Zustand zu verlassen.
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"
Nachdem die ausführbare Hauptdatei der App ermittelt wurde, lassen sich mit dem systemeigenen Werkzeug strings besonders relevante Merkmale suchen. Neben /Users/ sollten auch /Volumes/, DerivedData, .xcworkspace und die vom Team tatsächlich verwendeten Präfixe temporärer Verzeichnisse geprüft werden.
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
Eine bestandene Prüfung des Hauptprogramms bedeutet nicht, dass das gesamte Paket frei von problematischen Pfaden ist. Auch eingebettete Frameworks, Erweiterungen und Ressourcendateien müssen durchlaufen werden. Der Prüfbericht sollte „Dateipfad, Trefferinhalt und Artefakttyp“ erfassen, aber weder vollständige Binärdateien noch Umgebungsvariablen direkt in das Protokoll hochladen.
dSYM separat prüfen
Bei einer dSYM-Datei sind vor allem DW_AT_comp_dir und die Einträge zu Quelldateien relevant, nicht die Anzahl gewöhnlicher Zeichenfolgen. Zunächst wird die DWARF-Datei ermittelt. Anschließend werden Einträge ausgegeben, die auf das reale Arbeitsverzeichnis verweisen könnten.
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"
Die UUID muss zur ausführbaren Datei im Archiv gehören. Stimmen beide nicht überein, lassen sich spätere Absturzadressen selbst bei korrekter Pfadbehandlung nicht zuverlässig rekonstruieren.
Reale Verzeichnisse mit Compiler-Präfixabbildungen vereinheitlichen
Der Swift-Compiler kann mit -debug-prefix-map das Präfix des Arbeitsverzeichnisses durch ein stabiles logisches Verzeichnis ersetzen. Clang verwendet dafür -fdebug-prefix-map. In der Release-Konfiguration von Xcode können die folgenden Einstellungen ergänzt werden:
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
Das gesamte Verzeichnis /Users sollte nicht pauschal abgebildet werden. Eine zu weit gefasste Regel kann die Herkunft externer Abhängigkeiten verschleiern und dazu führen, dass unterschiedliche Verzeichnisse unbeabsichtigt auf denselben logischen Pfad abgebildet werden. Vorrangig sollte $(SRCROOT) abgebildet werden. Falls das Checkout-Verzeichnis für Abhängigkeiten feststeht, kann dafür eine eigene Regel ergänzt werden.
Nach der Einrichtung der Abbildung muss ein neues Archiv erstellt werden. Es genügt nicht, lediglich die Build-Einstellungen zu ändern und anschließend alte DerivedData wiederzuverwenden. Außerdem ist zu kontrollieren, ob die Compilerbefehle die Parameter tatsächlich enthalten, da manche benutzerdefinierten Skripte die Projekteinstellungen umgehen und den Compiler direkt aufrufen.
Fehlalarme abstufen statt pauschal freigeben
Prüfungen finden häufig Beispielpfade in Ressourcen, Test-Fixtures oder Debug-Texte von Drittanbietern. Die Behandlung solcher Treffer sollte sich nach ihrem Speicherort und ihrer Erreichbarkeit richten, nicht nach einer ständig wachsenden globalen Liste ignorierter Begriffe.
Empfehlenswert sind drei Ergebnisstufen:
- Enthält die verteilte App oder eine eingebettete Komponente das reale Präfix der aktuellen Build-Maschine, schlägt die Prüfung sofort fehl.
- Enthält die dSYM-Datei ein nicht abgebildetes Quellcodepräfix, wird die Prüfung als fehlgeschlagen markiert; die Datei bleibt jedoch für die Diagnose erhalten.
- Treten Pfade in internen Protokollen oder Testergebnispaketen auf, wird eine Warnung erzeugt und der Zugriffsbereich überprüft.
Einträge in der Positivliste sollten exakt aus „Datei + regulärer Ausdruck + Begründung“ bestehen. Muss eine bestimmte Testressource beispielsweise tatsächlich /Users/example/ anzeigen, sollte nur diese Ressource ausgenommen werden. /Users/ darf nicht pauschal in die Ignorierliste aufgenommen werden. Die Pipeline sollte außerdem den aktuellen Pfad des Arbeitsverzeichnisses als dynamisch verbotenes Muster behandeln. Das ist zuverlässiger, als alle möglichen Benutzernamen zu erraten.
Zusätzliche Offenlegung durch das Prüfskript vermeiden
Im Bericht kann das reale Präfix durch $WORKSPACE ersetzt werden, sodass nur relative Pfade und Treffertypen erhalten bleiben. Auch bei einem fehlgeschlagenen Befehl darf nicht die vollständige Umgebung ausgegeben werden. Muss der unveränderte Bericht aufbewahrt werden, sollte er als zugriffsbeschränkter Build-Anhang gespeichert werden, statt seinen Inhalt direkt in einer für alle Teammitglieder lesbaren Konsolenausgabe einzublenden.
Symbolizierung vor der Veröffentlichung erneut prüfen
Eine Pfadabbildung kann die Prüfung bestehen, ohne dass die Debugging-Kette weiterhin vollständig funktioniert. Vor der Veröffentlichung sollten mindestens die App, die dSYM-Datei, eine UUID-Liste und die Commit-Kennung des Builds gespeichert werden. Zusätzlich ist mit einer echten Befehlsadresse ein Symbolisierungstest auszuführen. Das Ergebnis muss einen Funktionsnamen und den logischen Quelldateipfad /src/... liefern, nicht lediglich eine hexadezimale Adresse.
Die abschließende Freigabeprüfung lässt sich auf vier Bedingungen reduzieren: Die App enthält kein reales Präfix des Arbeitsverzeichnisses; die UUID der dSYM-Datei stimmt mit der Binärdatei überein; der abgebildete Quellcodepfad kann erkannt werden; und die Protokolle geben den ursprünglichen Prüfbericht nicht vollständig aus. Dadurch wird die Offenlegung von Verzeichnisinformationen begrenzt, während die für die Diagnose von Produktionsfehlern erforderlichen Nachweise erhalten bleiben.
Die Pfadprüfung sollte unmittelbar nach einem Archivierungsauftrag auf einem Cloud-Mac von VMOrbit ausgeführt werden. Sie ist weder von einem festen Benutzernamen abhängig noch erfordert sie Änderungen an der Verzeichnisstruktur des Quellcodes. Solange die Pipeline den Stammpfad des Arbeitsverzeichnisses einheitlich bereitstellt, können dieselben Regeln sowohl temporäre Aufträge als auch dauerhaft betriebene Build-Knoten abdecken.
Häufig gestellte Fragen
Ist jeder gefundene /Users/-Pfad sofort eine Schwachstelle?
Nein. Er kann jedoch Kontonamen und Projektstrukturen offenlegen. Entscheidend ist, ob der Pfad in der ausgelieferten App, nur im dSYM oder lediglich in internen Protokollen steht.
Ersetzt debug-prefix-map die Aufbewahrung der dSYM-Datei?
Nein. Die Option ändert nur die dargestellten Quellpfade. Das dSYM bleibt für die Symbolisierung erforderlich und muss mit einer echten Adresse geprüft werden.
Soll jeder Pfadtreffer den Build stoppen?
Reale lokale Pfade in der ausgelieferten App sollten blockieren. Treffer in dSYM-Dateien und internen Protokollen eignen sich zunächst für Warnungen und eine gezielte Prüfung.
Build-Aufgaben auf einen dedizierten Cloud-Mac verlagern
Wählen Sie VMOrbit M4 oder VMOrbit M4 Pro und wählen Sie den Knoten passend zum Standort Ihres Teams. Die tatsächliche Verfügbarkeit und Bereitstellungsinformation richtet sich nach den Live-Angaben in der Konsole.