Ich suche nach einem sicheren Ort zum Platzieren von Unix-Domain-Sockets, die zur Steuerung eines REPL verwendet werden.
Unter Linux würde ich verwenden /run/user/$UID
, das alle Anforderungen außer der Portabilität erfüllt. Das Programm, das sie verarbeitet, muss portierbar sein.
Eine Möglichkeit besteht darin, ein Verzeichnis darunter zu verwenden, ~
dabei tritt jedoch ein anderes Problem auf: Das Home-Verzeichnis des Benutzers könnte sich aufgrund der Pfadlängenbeschränkung in einem zu tiefen Verzeichnis befinden, um einen Unix-Domain-Socket daran binden zu können.
Das Platzieren des Sockets in einem Verzeichnis unter /tmp
ist portierbar, aber ich mache mir Sorgen wegen Race Conditions beim Entfernen des Verzeichnisses. Ich mache mir auch Sorgen darüber, ob /tmp
man sich darauf verlassen kann, dass das Sticky-Bit auf allen Plattformen gesetzt ist (das heißt, dass Benutzer die temporären Dateien anderer Benutzer nicht löschen oder umbenennen können). Ich gehe /tmp
jedoch davon aus, dass es Sticky ist, da sonst viele, viele Anwendungen (jedes Skript, das verwendet mkstemp
) unsicher sind.
Mein aktueller Plan sieht vor, dass der Server ein temporäres Verzeichnis in erstellt /tmp
und die Clients den Besitz des enthaltenen Verzeichnisses überprüfen, bevor sie den Socket verwenden. Reicht das aus Sicherheitsgründen aus?
Antwort1
Dervon Rechts wegenStandardDer Speicherort für temporäre Dateien wird in der Umgebungsvariable angegeben TMPDIR
.
Diese Variable soll den Pfadnamen eines Verzeichnisses darstellen, das für Programme verfügbar gemacht wird, die einen Ort zum Erstellen temporärer Dateien benötigen.
Tatsächlich definieren viele Systeme nicht TMPDIR
. Diede factoDer Standardspeicherort für temporäre Dateien ist /tmp
. Überprüfen Sie also TMPDIR
, und wenn es nicht festgelegt ist, verwenden Sie /tmp
. In einem Shell-Skript können Sie verwenden ${TMPDIR:-/tmp}
, oder, wenn Sie es bequemer finden,
if [ -z "$TMPDIR" ]; then TMPDIR=/tmp; fi
oder zu bewältigen mitset -u
: "${TMPDIR:=/tmp}"
Sie können davon ausgehen, dass dieser Speicherort beschreibbar ist, er kann aber auch für alle Benutzer lesbar und beschreibbar sein. Daher gilt:
- Wenn Sie eine normale Datei erstellen, achten Sie immer darauf, dass Sie keine vorhandene Datei überschreiben, die Ihnen möglicherweise nicht gehört. Verwenden Sie hierfür keine Shell-Umleitung. Es ist nicht sicher, den Besitz separat zu testen, da ein Angreifer symbolische Links verschieben könnte, während Ihr Programm ausgeführt wird, um die Prüfungen zu täuschen. Darüber hinaus können Sie sich nicht darauf verlassen, dass ein bestimmter Name nicht existiert. Um zu verhindern, dass ein parallel laufendes Programm einen Denial-of-Service-Angriff auslöst, indem es kurz vor Ihnen eine Datei mit demselben Namen erstellt, verwenden Sie einen zufälligen Namen. Sie können das
mktemp
Dienstprogramm (weit verbreitet, vorhanden unter GNU, BusyBox, BSD, aber nicht unter POSIX) oder diemkstemp
C-Bibliotheksfunktion verwenden. Unter der Haube mussopen
odercreat
mit dem Flag aufgerufen werdenO_EXCL
. - Sie können ein Verzeichnis mit erstellen
mkdir
. Dies ist sicher gegen den Diebstahl von Eigentumsrechten, da eine vorhandene Datei nicht wiederverwendet wird, ist jedoch anfällig für denselben Denial-of-Service-Angriff wie normale Dateien, daher sollten Sie einen zufälligen Namen verwenden.mktemp -d
ist eine gute Möglichkeit, dies zu tun. - Sie können einen Socket erstellen (dafür gibt es kein Standard-Shell-Dienstprogramm). Wie im Fall des Verzeichnisses ist es gegen Besitzertricks geschützt, aber nicht gegen Denial-of-Service.
Linux respektiert Berechtigungen für benannte Sockets, aber es gibt Unix-Varianten, die das nicht tun. Aus diesem Grund/tmp
werden Sockets normalerweise in Unterverzeichnissen erstellt.
Zu den Programmen, die ein Unterverzeichnis von /tmp
(oder, $TMPDIR
wenn festgelegt) erstellen und dort einen benannten Socket erstellen, gehören X11-Server, SSH-Agent, GPG-Agent, KDE, Emacs usw. (das sind nur die, die auf dem Computer vorhanden sind, auf dem ich dies poste). Wie Sie sehen, sind Sie in guter Gesellschaft.