NamedPipeServerStream mit PipeOptions.CurrentUserOnly strafft Unix-Socketdateiberechtigungen

Um die Berechtigungen auf dem Datenträger besser mit der dokumentierten Absicht von PipeOptions.CurrentUserOnly und mit der Windows Implementierung auszurichten, wird die zugrunde liegende Unix-Domänensocketdatei jetzt mit Dateiberechtigungen 0600 erstellt (nur Lese-/Schreibzugriff für den besitzernden Benutzer). Zuvor hat die Socketdatei Berechtigungen vom Prozess umask geerbt und CurrentUserOnly nur benutzerübergreifende Verbindungen zur Verbindungszeit abgelehnt, ohne einzuschränken, wer die Socketdatei selbst öffnen konnte.

Eingeführt in Version

.NET 11 Vorschau 4

Bisheriges Verhalten

Zuvor wurde die Socketdatei, die eine NamedPipeServerStream unterstützte, mit den Berechtigungen erstellt, die der Prozess umask zuließ (üblicherweise 0644 oder 0755). Die Angabe PipeOptions.CurrentUserOnly hat den Dateimodus auf dem Datenträger nicht geändert. Andere lokale Benutzer könnten stat und je nach Plattform und effektiven Berechtigungen möglicherweise versuchen, eine Verbindung mit der Socket-Datei herzustellen. Benutzerübergreifende Verbindungsversuche wurden zur Verbindungszeit durch Peer-Credential-Prüfungen abgelehnt, die Socketdatei selbst könnte jedoch für andere Benutzer sichtbar sein, und auf einigen Unix-Systemen kann auch auf Betriebssystemebene eine Verbindung hergestellt werden.

using var server = new NamedPipeServerStream(
    "mypipe", PipeDirection.InOut, 1,
    PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly);

// Mode reflected the process umask, for example UserRead | UserWrite | GroupRead | OtherRead.
UnixFileMode mode = File.GetUnixFileMode("/tmp/CoreFxPipe_mypipe");

Neues Verhalten

Ab .NET 11 wird beim Angeben von PipeOptions.CurrentUserOnly die Socketdatei zu 0600chmod unmittelbar nach bind(). Andere lokale Benutzer (außer root) können die Socketdatei auf Betriebssystemebene nicht mehr öffnen oder darauf zugreifen.

using var server = new NamedPipeServerStream(
    "mypipe", PipeDirection.InOut, 1,
    PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly);

// Always UserRead | UserWrite (0600).
UnixFileMode mode = File.GetUnixFileMode("/tmp/CoreFxPipe_mypipe");

Für den prozessintern freigegebenen Servercache, bei dem mehrere NamedPipeServerStream Instanzen denselben Pipenamen verwenden, ist die Berechtigungsänderung einseitig (ratcheted):

  • Wenn eine CurrentUserOnly Instanz für einen bestimmten Pipenamen erstellt wird, wird die Socketdatei an diesem Punkt auf 0600 festgelegt und bleibt so für die restliche gemeinsame Lebensdauer dieses Pfads.
  • Eine spätere Instanz für denselben Pipenamen, die CurrentUserOnly nicht angibt, lockert den Modus nicht wieder.

Art der einschneidenden Änderung

Diese Änderung ist eine Verhaltensänderung.

Grund für die Änderung

PipeOptions.CurrentUserOnly wird als Einschränkung des Zugriffs auf den aktuellen Benutzer dokumentiert. Auf Unix wurde die Socketdatei jedoch mit Berechtigungen erstellt, die vom Prozess umask abgeleitet wurden, sodass die Erzwingung auf Peer-Credential-Prüfungen zur Verbindungszeit beruhte. Dadurch wurde die Socketdatei für andere lokale Benutzer auffindbar, und auf Plattformen, die Socketknoten-Berechtigungsbits berücksichtigen, könnte es anderen Benutzern auch ermöglichen, eine Verbindung zu versuchen oder herzustellen, bevor Peer-Anmeldeinformationen den benutzerübergreifenden Zugriff abgelehnt haben. Dieses Verhalten machte Unix-Verhalten inkonsistent mit der dokumentierten Absicht der Option und mit der Windows Implementierung. Weitere Informationen finden Sie unter dotnet/runtime#127239.

Die meisten Anrufer profitieren von den strengeren Berechtigungen und müssen nichts tun.

Unter Linux und macOS NamedPipeServerStream werden Unix-Domänensockets verwendet. Wenn Sie sich darauf verlassen, dass diese Socketdatei für andere lokale Benutzer als den Besitzer sichtbar oder verbindbar ist, aktualisieren Sie Ihre Anleitungen und Annahmen Ihrer App so, dass PipeOptions.CurrentUserOnly jetzt den Socketdateimodus auf 0600 beim Binden setzt.

Durch das Entfernen von PipeOptions.CurrentUserOnly wird nicht automatisch ein benutzerübergreifender Zugriff gewährt. Wenn Sie diese Option weglassen, erbt die Socketdatei weiterhin Berechtigungen vom Prozess umask, und andere Benutzer benötigen auch genügend Zugriff auf das Verzeichnis, das den Socketpfad enthält. Wenn Sie den benutzerübergreifenden Zugriff zulassen möchten, überprüfen Sie den effektiven Socketdateimodus und die Verzeichnisberechtigungen für das Zielsystem.

Damit der Server Verbindungen von anderen lokalen Benutzern akzeptieren kann, z. B. aus einem Hilfsprozess, der unter einem anderen Konto ausgeführt wird, oder von externen Tools, die den Socket untersuchen, beenden Sie die Übergabe PipeOptions.CurrentUserOnly.

Berücksichtigen Sie auch das prozessbezogene Ratschenverhalten. Wenn eine NamedPipeServerStream Instanz für einen bestimmten Pipenamen im Prozess CurrentUserOnly angibt, behalten alle nachfolgenden Instanzen für diesen Pipenamen 0600 Berechtigungen auf der Socket-Datei, bis der freigegebene Servereintrag freigegeben wird.

Betroffene APIs