PID-Wiederverwendung verfälscht die Zuordnung von Agent-Sitzungen
Die Wiederverwendung von PIDs kann Agent-Aktionen falsch zuordnen. Baue sicherere macOS-Agent-Sitzungen mit Prozessstartdaten, Signaturprüfungen, Eltern-Snapshots und strenger erneuter Validierung.

Eine alleinstehende PID reicht für eine Statusanzeige aus. Sie reicht nicht als Identität hinter einer Freigabe, einem Audit-Eintrag oder einer Agent-Sitzung mit Zugangsdaten. Das Betriebssystem verwendet Prozess-IDs wieder. Wenn ein Agent-System eine wiederverwendete Nummer als denselben Akteur behandelt, kann es einen späteren Prozess an die Freigabe eines früheren Prozesses hängen.
Dafür braucht ein Angreifer weder Kernelzugriff noch einen exotischen Race-Condition-Fall. Der Fehler tritt auf, wenn ein kurzlebiger Agent beendet wird, ein ausgelasteter Rechner genügend Prozesse startet, um seine PID wiederzuverwenden, und eine Komponente einen Aufruf erneut verbindet, eine Anzeige aktualisiert oder einen alten Audit-Eintrag anhand der PID auflöst. Der spätere Prozess kann ganz gewöhnliche Software sein. Die Zuordnung ist trotzdem falsch. Ein Freigabesystem, das auf einer falschen Zuordnung handelt, hat den Sinn von Freigaben bereits verfehlt.
Die Lösung ist nicht kompliziert, verlangt aber eine andere Begrifflichkeit. Höre auf, eine PID als Prozessidentität zu bezeichnen. Speichere stattdessen einen erfassten Prozessdatensatz mit PID, Startzeit, Informationen zur Codesignatur und Herkunft des Elternprozesses, die du bei der Autorisierungsentscheidung gesammelt hast. Jede spätere Prüfung muss dann nachweisen, dass der laufende Prozess noch zu diesem Datensatz passt.
Eine PID bezeichnet einen Platz, nicht den Lebenszyklus eines Prozesses
Eine Prozess-ID identifiziert einen aktuell belegten Kernel-Prozess-Eintrag. Sie benennt nicht für immer dasselbe Programm und garantiert keine globale Eindeutigkeit über die Zeit hinweg. Wenn der Prozess beendet wird, kann seine PID wieder vergeben werden.
Dieser Unterschied klingt zunächst kleinlich, bis ein System eine frühere Freigabe weitergibt. Angenommen, ein Agent-Client startet als PID 4812, möchte eine Berechtigung für einen Deployment-Vorgang verwenden und die Person gibt diese Ausführung frei. Der Client wird beendet. Später erhält ein anderer Prozess die PID 4812. Wenn dein Gateway fragt: «Hat PID 4812 eine freigegebene Sitzung?», kann es die alte Freigabe finden und sie an den neuen Prozess hängen.
Der gefährliche Teil ist, dass sich alter und neuer Prozess nicht überschneiden müssen. Viele Implementierungen machen den Fehler in einem Datenbank-Join, einer Cache-Abfrage oder einem späteren Anreicherungsjob. Sie speichern die Freigabe als pid = 4812, speichern Aufrufe genauso und verlassen sich darauf, dass eine spätere Abfrage noch dieselbe Bedeutung hat. Das tut sie nicht.
Eine PID kann in einem Datensatz für Menschen weiterhin nützlich sein, weil sie Operatoren bei der Untersuchung eines laufenden Systems hilft. Behalte sie. Mache sie nur nicht zur primären Identität für Autorisierung oder Zuordnung.
Es gibt eine zweite Falle: fork und exec erschweren einfache Erklärungen. Ein Fork erzeugt ein neues Kind mit einer anderen PID. Ein Exec ersetzt das Programmbild in einem bestehenden Prozess, während dessen PID erhalten bleibt. Wenn du einen Shell-Runner freigibst und er ein anderes Binärprogramm per Exec startet, bleibt die PID vertraut, doch der Code, der die nächste Anfrage stellt, kann ein anderer sein. Ein Identitätsmodell muss deshalb sowohl die PID-Wiederverwendung nach dem Beenden als auch den Programmaustausch in einem weiterlaufenden Prozess berücksichtigen.
Einen Prozessdatensatz beim Sitzungsbeginn erfassen
Ein zuverlässiger Sitzungsdatensatz ist ein Snapshot, der an der Sicherheitsgrenze aufgenommen wird, keine später rekonstruierte Sammlung von Fakten. Erfasse ihn, wenn der Agent-Prozess erstmals eine Sitzung anfordert, bevor du eine Freigabe mit Angaben zum Aufrufer anzeigst.
Für ein macOS-Agent-Gateway würde ich diese Felder als einen unveränderlichen Prozess-Snapshot speichern:
- PID und effektive Benutzer-ID.
- Prozessstartzeit mit Sekunden und Mikrosekunden, sofern die Plattform sie liefert.
- Pfad zur ausführbaren Datei zum Zeitpunkt der Erfassung.
- Signatur-ID, Team- oder Signaturkontext und Code-Directory-Hash, sofern verfügbar.
- Snapshot des Elternprozesses einschließlich dessen PID und Startzeit.
Die Prozessstartzeit macht aus einer PID eine lebenszyklusbezogene Referenz. Ein praktisches Tupel sieht so aus:
process_instance = (
pid = 4812,
start_time = 2026-07-22T14:03:18.482911Z,
euid = 501
)
Dieses Tupel beantwortet die enge Frage: «Handelt es sich um denselben Kernel-Prozesslebenszyklus, den ich zuvor gesehen habe?» Es beantwortet nicht, ob der Prozess vertrauenswürdig ist. Der Signaturdatensatz beantwortet eine andere Frage: «Welchen Code hat macOS validiert, als ich diesen Prozess untersucht habe?» Der Eltern-Snapshot beantwortet wiederum: «Was hat diesen Prozess erzeugt, so wie es beim Sitzungsbeginn beobachtet wurde?»
Fasse diese Fragen nicht zu einem Textetikett wie Claude Code (PID 4812) zusammen. Für eine Freigabekarte kann dieses Etikett ausreichen. Es verliert aber die Fakten, die du brauchst, wenn jemand fragt, warum eine bestimmte Sitzung autorisiert wurde.
Unter macOS kann ein Prozessinspektor proc_pidinfo mit PROC_PIDTBSDINFO verwenden, um proc_bsdinfo zu erhalten. Diese Struktur enthält pbi_start_tvsec und pbi_start_tvusec. Apple stellt die Prozess-start_time außerdem in seinem Endpoint-Security-Prozessmodell bereit. Entscheidend ist nicht, welche API du wählst. Entscheidend ist, dass du die Startzeit an der Entscheidungsgrenze erfasst und später vergleichst.
Eine schmale C-Hilfsfunktion für den Lebenszyklus kann so aussehen:
#include <libproc.h>
#include <sys/proc_info.h>
#include <cstdio.h>
int read_process_lifetime(pid_t pid) {
struct proc_bsdinfo info = {0};
int size = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0,
&info, sizeof(info));
if (size != sizeof(info)) {
return -1;
}
printf("pid=%d start=%lld.%06d parent=%d uid=%d\n",
info.pbi_pid,
info.pbi_start_tvsec,
info.pbi_start_tvusec,
info.pbi_ppid,
info.pbi_uid);
return 0;
}
Die Form der Ausgabe ist wichtiger als die Sprachbindung:
pid=4812 start=1784738598.482911 parent=4760 uid=501
Wenn eine spätere Abfrage dieselbe PID mit einem anderen Startzeitpunkt zurückgibt, handelt es sich um einen anderen Prozess. Verweigere die Sitzungszuordnung, auch wenn jede Komfortschicht die Nummer weiterhin als vertraut behandeln möchte.
Codesignaturen beschreiben Code, nicht eine einzelne laufende Instanz
Daten zur Codesignatur liefern wertvolle Herkunftsinformationen, werden aber nicht automatisch zu einer Prozessidentität. Eine Signatur-ID kann von jeder veröffentlichten Version einer Anwendung gemeinsam genutzt werden. Eine Team-ID bezeichnet eine signierende Organisation, nicht eine bestimmte ausführbare Datei. Ein Code-Directory-Hash ist spezifischer für den signierten Codeinhalt, doch viele gleichzeitig laufende Instanzen derselben ausführbaren Datei haben weiterhin denselben Hash.
Apples Dokumentation zur Codesignatur macht eine wichtige Unterscheidung, die Sicherheitsprodukte oft verwischen. Eine Signatur-ID kann von mehreren Signierern beansprucht werden. Deshalb empfiehlt Apple, die Validierungskategorie und bei Code, der nicht von Apple stammt, zusätzlich die Team-ID zu prüfen. Apples Technical Note TN3127 erklärt außerdem, dass eine Designated Requirement eine ID mit Signaturanforderungen verbindet, um die Codeidentität über Updates hinweg festzustellen.
Das ist das richtige Denkmodell: Signaturinformationen zeigen, welche ausführbare Datei macOS validiert hat und ob sie deine Vertrauensanforderung erfüllt. Sie sagen nicht, ob es sich um denselben Prozess handelt, den die Person vor fünf Minuten freigegeben hat.
Für die Sitzungsautorisierung brauchst du beide Ebenen:
same_process_lifetime:
pid, start_time, euid all match the captured record
same_expected_code:
captured signing requirement still validates for the live process
same_session:
the session token refers to this captured process record, not only its PID
Vergleiche nicht nur einen Anzeigenamen, eine Bundle-ID oder einen Pfad. Pfade ändern sich. Nicht signierte Kommandozeilenprogramme haben möglicherweise nur schwache oder lokale Identitätsmerkmale. Eine Person kann außerdem eine Kopie eines vertrauten Tools von einem anderen Ort ausführen. Deine Freigabeoberfläche kann ein verständliches Etikett anzeigen. Dein Autorisierungscode sollte aber die ausgewerteten Signaturinformationen bewahren, die zu diesem Etikett geführt haben.
Eine häufige schlechte Empfehlung lautet, allein anhand der Signatur-ID zu autorisieren, weil sie Anwendungsupdates übersteht. Sie ist beliebt, weil die Kontinuität bei Updates bequem wirkt. Für eine Freigabe pro Ausführung ist sie falsch. Wenn jemand einen laufenden Agent-Prozess freigegeben hat, ist ein späterer Start desselben signierten Programms eine neue Ausführung und sollte eine neue Sitzungsentscheidung erhalten. Eine stabile Codeidentität macht die Freigabekarte verständlicher. Sie erlaubt nicht, eine Freigabe für eine einzelne Ausführung stillschweigend auf jede künftige Instanz auszudehnen.
Eine Eltern-PID ist nur dann ein Beleg, wenn du ihren Lebenszyklus bewahrst
Informationen zum Elternprozess helfen Prüfern zu verstehen, wie ein Agent gestartet wurde. Sie können einen aus einem Terminal gestarteten Client von einem Prozess unterscheiden, den ein Editor, ein Scheduler oder ein anderer Agent gestartet hat. Doch ppid = 4760 hat dasselbe Wiederverwendungsproblem wie die PID des Kindes.
Das falsche Muster ist leicht zu erkennen:
session.agent_pid = 4812
session.parent_pid = 4760
Drei Stunden später löst eine Audit-Ansicht die PID 4760 zu einem Prozess auf, der diese Nummer trägt, und bezeichnet ihn als Elternprozess der Sitzung. Der ursprüngliche Elternprozess kann längst beendet sein. Ein anderer Prozess besitzt nun die 4760. Die Audit-Seite hat eine historische Aussage in eine Live-Abfrage verwandelt und dabei stillschweigend die Vergangenheit umgeschrieben.
Erfasse den Eltern-Snapshot zusammen mit dem Snapshot des Kindes:
parent_instance = (
pid = 4760,
start_time = 2026-07-22T14:01:02.117604Z,
euid = 501,
executable_path = "/usr/bin/login",
signing_requirement = "captured evaluation",
relationship = "observed_parent_at_session_open"
)
Das letzte Beziehungsfeld klingt banal, verhindert aber viel ungenaue Sprache. Der Eltern-Datensatz bedeutet: «Dies war der direkte Elternprozess, als das System das Kind beobachtete.» Er bedeutet nicht: «Dieser Elternprozess hat das Kind autorisiert», «Dieser Elternprozess besitzt das Kind für immer» oder «Dieser Elternprozess ist weiterhin der aktuelle Elternprozess». Für diese Aussagen brauchst du andere Belege.
Wenn du Endpoint-Security-Ereignisse hast, stellt Apples es_process_t die ursprüngliche Eltern-PID bereit und enthält parent_audit_token und responsible_audit_token sowie Startzeit und Signaturinformationen. Audit-Tokens sind rohen PIDs vorzuziehen, wenn die API sie liefert, weil sie mehr Kontext bewahren. Behandle das Prozessobjekt eines Ereignisses trotzdem als erfasste Beobachtung. Ersetze es nicht durch eine spätere PID-Abfrage und behaupte, beides sei gleichwertig.
Bei Systemen ohne Endpoint Security solltest du die besten verfügbaren Prozess-APIs verwenden, schnell erfassen und Unsicherheit sichtbar machen. Ein Elternprozess kann beendet werden, während du zuerst das Kind und danach den Elternprozess liest. Erzeuge in diesem Wettlauf keine künstliche Gewissheit. Markiere den Elternprozess als nicht verfügbar oder unvollständig, bewahre die erfasste Identität des Kindes und behaupte keine Elternbeziehung, die du nicht beobachten konntest.
Vor einer Aktion einer freigegebenen Sitzung erneut prüfen
Bei der Sitzungsfreigabe gibt es zwei Momente für den Umgang mit Identität: die Erfassung beim Öffnen der Sitzung und die erneute Prüfung bei der Nutzung der Berechtigung. Die einmalige Erfassung schützt den Audit-Verlauf. Die erneute Prüfung schützt die nächste Aktion.
Stell dir diese Abfolge vor:
- Ein Agent-Prozess öffnet eine Sitzung. Du erfasst PID 4812, Startzeit, Signaturinformationen und Angaben zum Elternprozess.
- Eine Person gibt genau diese Agent-Ausführung frei.
- Der Prozess wird beendet, während das Sitzungstoken noch im Speicher oder auf einer lokalen IPC-Verbindung liegt.
- Ein späterer Prozess erhält die PID 4812 und präsentiert ein veraltetes Token oder erreicht über einen Fehler eine alte Zuordnung.
- Dein Gateway prüft den laufenden Prozess, bevor es einen Aufruf mit Zugangsdaten ausführt.
Bei der letzten Prüfung kann die PID übereinstimmen. Die Startzeit wird es nicht. Diese Abweichung muss die Sitzung schließen. Korrigiere den Datensatz nicht mit dem neuen Zeitstempel, erstelle keine unbemerkte Ersatzsitzung und ordne die Aktion nicht dem früheren Prozess zu.
Die Prüfung muss auch bei fehlgeschlagener Inspektion sicher verweigern. Wenn dein Code die Prozessinformationen nicht lesen kann, weil der Prozess beendet wurde, sich Berechtigungen geändert haben oder das Betriebssystem unvollständige Daten zurückgibt, kannst du nicht feststellen, dass der Anfragende der freigegebene Prozess ist. Die richtige Antwort ist eine neue Sitzung.
Halte den Vergleich eng und wörtlich. Verwende keine ungenauen Kriterien wie «derselbe Befehlsname», «dasselbe Arbeitsverzeichnis» oder «dasselbe Terminalfenster». Diese Felder helfen Menschen beim Verständnis des Kontexts, überstehen aber weder absichtliche noch versehentliche Mehrdeutigkeit. Ein Prozess kann sein Arbeitsverzeichnis ändern, und zwei unabhängige Prozesse können denselben Befehlsnamen wählen.
Der richtige Ort für einen Cache ist die Autorisierungsentscheidung, die an die erfasste Prozessinstanz gebunden ist. Der falsche Ort ist eine Zuordnung von PID zu Freigabestatus. Eine nach PID indizierte Zuordnung besteht Tests auf einem ruhigen Laptop und scheitert bei starkem Prozesswechsel. Das macht den Fehler besonders schwer zu diagnostizieren, sobald er Nutzer erreicht.
Sitzungen als unveränderliche Ereignisse modellieren, nicht als veränderliche Prozesszeilen
Ein Sitzungsjournal sollte festhalten, was das Gateway zu jedem Zeitpunkt beobachtet hat. Eine veränderliche Zeile, die immer sagt «PID 4812 ist aktiv», kann nicht beantworten, ob ihre Felder vom ursprünglichen Agent, einem Ersatzprozess oder einer späteren Hintergrundaktualisierung stammen.
Verwende unveränderliche Ereignisdatensätze mit eindeutigen Verweisen. Die Struktur kann einfach sein:
{
"event_type": "session_authorized",
"session_id": "sess_7d9f",
"process_instance": {
"pid": 4812,
"start_time": "2026-07-22T14:03:18.482911Z",
"euid": 501,
"signing_id": "com.example.agent",
"team_id": "A1B2C3D4E5",
"cdhash": "captured-code-directory-hash"
},
"parent_instance": {
"pid": 4760,
"start_time": "2026-07-22T14:01:02.117604Z"
},
"approval": {
"scope": "this process run",
"decision": "approved"
}
}
Das nächste Aufrufereignis verweist auf sess_7d9f und zeichnet seine eigene Zeit, den angeforderten Kanal, das Aktionsziel und das Ergebnis auf. Es kopiert nicht nur pid: 4812 und hofft, dass ein Analyst den Rest rekonstruieren kann. Wenn die erneute Prüfung fehlschlägt, schreibe ein eigenes Ablehnungsereignis mit der beobachteten Abweichung.
{
"event_type": "action_denied",
"session_id": "sess_7d9f",
"reason": "process_start_time_mismatch",
"captured_pid": 4812,
"captured_start_time": "2026-07-22T14:03:18.482911Z",
"observed_start_time": "2026-07-22T15:47:09.031882Z"
}
So erhält ein Prüfer etwas Konkretes: Die Prozessnummer wurde wiederverwendet, das Gateway hat die Abweichung erkannt und die Anfrage verweigert. Ohne beide Zeitstempel sagt das Ereignis nur, dass etwas fehlgeschlagen ist. Das reicht nicht, wenn du einen Softwarefehler von einem böswilligen Versuch unterscheiden musst, eine Berechtigung zu übernehmen.
Sallyports Trennung zwischen Sitzungsjournal und Aktivitätsjournal ist hier nützlich, weil Sitzungsautorisierung und einzelne Aktionen unterschiedliche Audit-Fragen beantworten. Beide müssen den Prozess-Snapshot bewahren, der bei der Sitzungsentscheidung existierte, statt sich bei späterer Darstellung oder Prüfung auf eine alleinstehende PID zu verlassen.
Die Freigabekarte sollte Herkunft beschreiben, ohne Gewissheit vorzutäuschen
Menschen können keine gute Entscheidung aus einem Dialog treffen, der nur sagt: «Agent möchte Zugriff.» Sie brauchen genügend Identitätskontext, um den Aufrufer zu erkennen. Die Karte sollte aber nicht mit Feldern überladen werden, die präzise aussehen und wenig aussagen.
Beginne mit der von dir geprüften Signaturinstanz. Füge den Namen oder Pfad der ausführbaren Datei hinzu, wenn das hilfreich ist. Zeige die Prozessbeziehung in verständlicher Sprache, etwa «von einer signierten Terminalanwendung gestartet» oder «aus einer Editor-Hilfsanwendung gestartet», aber nur, wenn du die entsprechenden Daten erfasst hast. Zeige die PID als Detail für die Fehlersuche, nicht als behauptete Identität.
Stelle eine Elternkette nicht so dar, als wäre sie eine Zertifikatskette. Die Elternbeziehung ist eine Momentaufnahme des Betriebssystems. Ein signierter Elternprozess kann ein nicht signiertes Kind starten. Ein erwarteter Elternprozess kann ein Wrapper sein, der per Exec etwas anderes startet. Die Freigabekarte sollte deutlich machen, wer die Sitzung jetzt anfordert, und Angaben zum Elternprozess als Kontext liefern.
Dieser Unterschied verändert auch den Widerruf. Widerrufe eine Sitzungs-ID, keine PID. Wenn eine Person die Sitzung widerruft, markiere den unveränderlichen Sitzungsdatensatz als widerrufen und lehne künftige Aktionsversuche ab, die darauf verweisen. Der ursprüngliche Prozess verliert seinen Zugriff, falls er noch läuft. Wenn er beendet wurde und seine PID wiederverwendet ist, bleibt der Widerruf korrekt, weil er nie von der Kontrolle über diese numerische PID abhing.
Eine Freigabe sollte eine beobachtete Ausführung bedeuten. Wenn Nutzer eine umfassendere Vertrauensentscheidung wünschen, baue dafür eine eigene, ausdrücklich aktivierte Funktion mit klarem Umfang, etwa eine signierte Code-Anforderung plus festgelegte Dauer. Verstecke diesen größeren Umfang nicht in einer Freigabe pro Sitzung, nur weil die Implementierung zufällig über einen praktischen PID-Cache verfügt.
Den Fehler testen, statt normales Prozessverhalten zu vertrauen
Fehler durch PID-Wiederverwendung bleiben verborgen, weil gewöhnliche manuelle Tests nicht genügend Wechsel erzeugen. Eine Testsuite sollte deinen Code dazu zwingen nachzuweisen, dass er einen Ersatzprozess ablehnt, der eine Nummer übernommen hat, und dass er ein Exec ablehnt, das den Code hinter einem weiterlaufenden Prozess verändert.
Du musst nicht darauf warten, dass macOS eine bestimmte PID zufällig wiederverwendet. Lege die Prozessinspektion hinter eine Schnittstelle und speise sie anschließend mit kontrollierten Snapshots. Ein guter Test enthält einen freigegebenen Datensatz und eine spätere laufende Beobachtung mit derselben PID, aber einer anderen Startzeit:
captured: pid=4812 start=1784738598.482911 signer=team-A
observed: pid=4812 start=1784744029.031882 signer=team-B
expected: deny with process_start_time_mismatch
Füge einen zweiten Fall hinzu, in dem PID und Startzeit übereinstimmen, die Signaturanforderung aber fehlschlägt. Ergänze einen weiteren Fall, in dem das Kind weiterläuft, Exec jedoch die Angaben zur ausführbaren Datei verändert hat. Diese Tests zeigen, dass dein Autorisierungscode die richtigen Felder gemeinsam auswertet, statt nur zu prüfen, ob die Prozessinspektion Daten liefert.
Teste die Audit-Ansicht separat. Lege eine alte Sitzung mit einer Eltern-PID an, simuliere das Beenden dieses Elternprozesses und liefere danach einen unabhängigen Prozess mit derselben PID. Die dargestellte historische Sitzung muss die ursprünglich erfassten Angaben zum Elternprozess behalten. Sie darf sie nicht durch einen Namen ersetzen, der aus der aktuellen Prozesstabelle stammt.
Teste schließlich Abbruch- und Inspektionsfehler. Ein Prozess kann in dem kurzen Zeitraum zwischen dem Annehmen einer IPC-Anfrage und dem Abfragen seiner Details verschwinden. Dein Code sollte einen klaren Ablehnungsgrund aufzeichnen und vom Aufrufer den Aufbau einer neuen Sitzung verlangen. Systeme, die solche Fehler in bestmögliche Zuordnungen verwandeln, erzeugen genau die Mehrdeutigkeit, die das Identitätsmodell beseitigen sollte.
Die wichtige Invariante ist einfach und streng
Jede privilegierte Agent-Aktion muss auf eine Sitzung verweisen, die an einen erfassten Prozesslebenszyklus gebunden ist. Eine passende laufende Anfrage muss nachweisen, dass sie aus genau diesem Lebenszyklus stammt, und ihre ausführbare Datei muss weiterhin die freigegebene Codeidentität erfüllen. Eine wiederverwendete PID scheitert am ersten Test. Ein anderes Binärprogramm hinter einer unveränderten PID scheitert am zweiten.
Diese Invariante hält Prozessinformationen in ihren richtigen Rollen. Startdaten unterscheiden Lebenszyklen. Signaturdaten identifizieren validierten Code. Angaben zum Elternprozess liefern Herkunft. Die Sitzungs-ID trägt die menschliche Entscheidung. Kein Feld kann die Aufgabe der anderen Felder übernehmen.
Sallyport kann diese Entscheidung sichtbar machen, indem die Sitzungsautorisierung mit der Codesignaturinstanz des Prozesses beginnt und getrennte Datensätze für Ausführungen und Aufrufe bewahrt. Die Implementierung muss trotzdem verhindern, dass eine praktische Nummer, so vertraut sie in einem Log auch aussehen mag, an die Stelle des Prozesses tritt, der die Freigabe erhalten hat.
Wenn du das nächste Mal eine Tabelle siehst, die nach pid indiziert ist, frage dich, was nach dem Beenden des Prozesses passiert. Wenn die Antwort lautet: «Wir suchen sie erneut nach», ist die Tabelle kein Speicher für Sitzungsidentitäten. Behebe das, bevor ein harmloses Ereignis im Prozesslebenszyklus zu einem Autorisierungsfehler wird.
FAQ
Warum ist eine Prozess-ID keine eindeutige Prozessidentität?
Eine PID ist ein Platz in der Prozesstabelle des Betriebssystems, keine dauerhafte Identität. Sobald ein Prozess beendet wird, kann macOS dieselbe Nummer einem später gestarteten Prozess zuweisen. Wenn dein Datensatz nur «PID 8421» enthält, kann er nach genügend Prozesswechseln auf den falschen Prozess verweisen.
Was sollte ich zusammen mit einer PID speichern, um einen Agent-Prozess sicher zu identifizieren?
Verwende mindestens die PID zusammen mit der Startzeit des Prozesses. Für ein Agent-Steuerungssystem solltest du außerdem die Benutzer-ID, den beim Verbindungsaufbau erfassten Pfad zur ausführbaren Datei, Signaturinformationen und einen Snapshot des Elternprozesses speichern. Jedes dieser Felder fängt eine andere Art ab, wie eine alleinstehende PID in die Irre führen kann.
Reichen PID und Prozessstartzeit für die Autorisierung eines Agents aus?
Nein. Die Startzeit unterscheidet zwei Lebenszyklen, denen zufällig dieselbe PID zugewiesen wurde. Sie sagt aber nichts darüber aus, ob du der ausführbaren Datei vertraust. Kombiniere sie mit geprüften Signaturinformationen und bewahre den Elternprozess als zusätzliche Herkunftsinformation auf.
Kann ich einer macOS-Signatur-ID allein vertrauen?
Eine Code-Signatur-ID benennt Code innerhalb eines Signaturbereichs. Sie beweist allein aber nicht, dass es sich um den Prozess handelt, den du freigeben wolltest. Eine solide Identitätsprüfung umfasst den Kontext des Signierers oder Teams und validiert die Code-Anforderung. Für forensische Datensätze solltest du außerdem den Code-Directory-Hash speichern, sofern die Plattform ihn bereitstellt.
Wie kann ich einen Prozess-Elternteil ohne Fehler durch PID-Wiederverwendung aufzeichnen?
Erfasse den Elternprozess, wenn sich das Kind verbindet oder du das Exec-Ereignis beobachtest. Suche die Eltern-PID nicht später erneut ab und behandle das Ergebnis nicht als historische Wahrheit. Eltern-PIDs können genauso wie Kind-PIDs wiederverwendet werden.
Wie verhindere ich, dass eine PID-Wiederverwendung den falschen Agent freigibt?
Behandle die Prozessidentität als Eingabe für die Autorisierung, nicht als Anzeigeetikett. Prüfe den laufenden Prozess unmittelbar vor der Freigabe einer Sitzung erneut, vergleiche Startzeit und Signaturinformationen mit dem erfassten Datensatz und verweigere die Anfrage, wenn der Prozess beendet oder verändert wurde.
Löst Endpoint Security die Prozesszuordnung auf macOS?
Endpoint Security kann dabei hilfreich sein, ersetzt aber keinen Identitätsdatensatz, der den gesamten Lebenszyklus berücksichtigt. Endpoint Security stellt in seinen Prozessstrukturen die Startzeit, Audit-Daten, Code-Signaturfelder und Audit-Daten des Elternprozesses bereit. Dafür sind jedoch die passende Berechtigung und zusätzlicher Betriebsaufwand nötig, den viele Desktop-Apps nicht brauchen.
Was ist der Unterschied zwischen einem cdhash und einer Prozessidentität?
Nein. Ein Code-Directory-Hash identifiziert den Inhalt signierten Codes, während eine Prozessidentität eine einzelne laufende Instanz dieses Codes bezeichnet. Zehn gleichzeitig laufende Prozesse können denselben Hash haben, und eine PID kann im Lauf der Zeit zu mehreren verschiedenen Prozessen gehören.
Wie sollte ein Audit-Protokoll Agent-Sitzungen und Prozessbeendigungen modellieren?
Verwende unveränderliche Ereignisse statt einer einzigen veränderlichen Sitzungszeile, die überschrieben wird. Speichere die erfasste Identität bei der Sitzungsfreigabe, füge Aufrufdatensätze hinzu, die auf diese Sitzungsidentität verweisen, und zeichne Widerruf oder Beendigung als spätere Ereignisse auf. So sehen Prüfer eine nachvollziehbare Abfolge statt einer Vermutung aus dem aktuellen Zustand.
Kann Exec einen freigegebenen Agent-Prozess ändern, ohne seine PID zu verändern?
Durch Forking kann eine PID erhalten bleiben, während Exec das Programmbild dieses Prozesses ersetzt. Dadurch können PID und sogar die Beziehung zum Elternprozess gleich bleiben, während sich die ausführbare Datei und der Signierer ändern. Prüfe die Identität beim tatsächlichen Verbindungsaufbau des Agents und erneut, bevor eine länger gültige Autorisierung verwendet wird.