mirror of
https://github.com/php/doc-de.git
synced 2026-03-24 07:12:15 +01:00
858 lines
36 KiB
XML
858 lines
36 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 55e0481a24fd4d7db21b62f1885973edbca25e60 Maintainer: samesch Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
|
|
<chapter xml:id="session.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Sessions und Sicherheit</title>
|
|
<para>
|
|
Externe Links:
|
|
<link xlink:href="&url.session-fixation;">Session fixation</link>
|
|
</para>
|
|
<para>
|
|
Die HTTP-Session-Verwaltung stellt den Kern der Web-Sicherheit dar. Es
|
|
sollten <emphasis>alle</emphasis> möglichen Schutzmaßnahmen ergriffen werden,
|
|
um sicherzustellen, dass die Sessions abgesichert sind. Entwickler sollten
|
|
darüber hinaus geeignete Sicherheitsmaßnahmen aktivieren/verwenden.
|
|
</para>
|
|
|
|
<sect1 xml:id="features.session.security.management">
|
|
<title>Grundlagen der Session-Verwaltung</title>
|
|
|
|
<sect2 xml:id="features.session.security.management.basic">
|
|
<title>Session-Sicherheit</title>
|
|
|
|
<para>
|
|
Das Session-Modul kann nicht garantieren, dass die in einer Session
|
|
gespeicherten Informationen nur von dem Benutzer eingesehen werden können,
|
|
der die Session erstellt hat. Es sind zusätzliche Maßnahmen erforderlich,
|
|
um die Vertraulichkeit der Session zu schützen, je nach dem, welcher Wert
|
|
mit ihr verbunden ist.
|
|
</para>
|
|
|
|
<para>
|
|
Die Wichtigkeit der Daten, die in der Session enthalten sind, muss
|
|
bewertet werden und weitere Schutzmaßnahmen können erforderlich sein; dies
|
|
hat in der Regel einen Preis, &zb; einen geringeren Komfort für den
|
|
Benutzer. Um den Benutzer zum Beispiel vor einer einfachen Taktik des
|
|
Social Engineering (Sozialmanipulation, Ausnutzung menschlicher Schwächen)
|
|
zu schützen, muss
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
aktiviert werden. In diesem Fall müssen auf der Client-Seite unbedingt
|
|
Cookies erlaubt sein, sonst funktionieren die Sessions nicht.
|
|
</para>
|
|
|
|
<para>
|
|
Es gibt mehrere Wege, eine bestehende Session-ID an Dritte durchsickern zu
|
|
lassen, &zb; JavaScript-Injections, Session-IDs in URLs, Packet Sniffing,
|
|
physischer Zugriff auf das Gerät etc. Eine durchgesickerte Session-ID
|
|
ermöglicht Dritten, auf alle Ressourcen zuzugreifen, die mit einer
|
|
bestimmten ID verbunden sind. Erstens: URLs, die die Session-IDs
|
|
enthalten. Wenn es Links zu einer externen Seite oder Ressource gibt, kann
|
|
die URL einschließlich der Session-ID in den Referrer-Protokollen der
|
|
externen Seite gespeichert werden. Zweitens: Ein aktiverer Angreifer
|
|
könnte den Netzwerkverkehr abhören. Wenn dieser unverschlüsselt ist,
|
|
fließen die Session-IDs im Klartext über das Netzwerk. Die Lösung ist,
|
|
SSL/TLS auf dem Server zu implementieren und für die Benutzer
|
|
obligatorisch zu machen. Für eine verbesserte Sicherheit sollte HSTS
|
|
verwendet werden.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Auch HTTPS kann vertrauliche Daten nicht immer schützen. Zum Beispiel
|
|
können die Sicherheitslücken CRIME und Beast einem Angreifer ermöglichen,
|
|
die Daten zu lesen. Zu beachten ist auch, dass viele Netzwerke
|
|
HTTPS-MITM-Proxys zu Prüfzwecken einsetzen. Angreifer können ebenfalls
|
|
einen solchen Proxy einrichten.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.non-adaptive-session">
|
|
<title>Nicht-adaptive Session-Verwaltung</title>
|
|
|
|
<para>
|
|
Der Session-Verwalter von PHP ist derzeit standardmäßig adaptiv. Ein
|
|
adaptiver Session-Verwalter birgt zusätzliche Risiken.
|
|
</para>
|
|
|
|
<para>
|
|
Wenn
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
aktiviert ist und die Session-Speicherroutine dies unterstützt, wird eine
|
|
uninitialisierte Session-ID verworfen und eine neue erstellt. Dies
|
|
verhindert einen Angriff, der Benutzer dazu zwingt, eine bereits bekannte
|
|
Session-ID zu verwenden. Ein Angreifer könnte Links einfügen oder E-Mails
|
|
senden, die die Session-ID enthalten, &zb;
|
|
<literal>http://example.com/page.php?PHPSESSID=123456789</literal>. Wenn
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
|
|
aktiviert ist, startet das Opfer damit eine Session mit der vom Angreifer
|
|
angegebenen Session-ID.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
entschärft dieses Risiko.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Benutzerdefinierte Speicherroutinen können den strikten Session-Modus
|
|
ebenfalls unterstützen, indem sie eine Validierung der Session-ID
|
|
implementieren. Alle benutzerdefinierten Speicherroutinen sollten eine
|
|
Validierung der Session-ID implementieren.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Das Cookie für die Session-ID kann mit den Attributen domain, path,
|
|
httponly, secure und ab PHP 7.3 mit dem Attribut SameSite gesetzt werden.
|
|
<!-- Not exactly sure what the meaning here is - girgias -->
|
|
Es gibt eine von den Browsern definierte Vorrangigkeit. Durch das
|
|
Ausnutzen der Rangfolge kann ein Angreifer eine Session-ID setzen, die
|
|
dauerhaft verwendet werden kann. Die Verwendung von
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
wird dieses Problem nicht lösen.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
entschärft dieses Risiko. Mit
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
wird die nicht initialisierte Session-ID abgelehnt.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Auch wenn
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
das Risiko der adaptiven Session-Verwaltung abschwächt, kann ein Angreifer
|
|
die Benutzer dazu bringen, eine initialisierte Session-ID zu verwenden,
|
|
die von ihm erstellt wurde, &zb; durch eine JavaScript-Injection. Dieser
|
|
Angriff kann durch die Empfehlungen dieses Handbuchs entschärft werden.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Wenn Entwickler dieses Handbuch befolgen, sollten sie
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
aktivieren, die zeitstempelbasierte Session-Verwaltung verwenden und die
|
|
Session-IDs mittels <function>session_regenerate_id</function> mit den
|
|
empfohlenen Verfahren neu erzeugen. Folgen Entwickler allen oben
|
|
genannten Punkten, wird eine von einem Angreifer generierte Session-ID
|
|
letztlich gelöscht werden.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Wenn ein Zugriff auf eine veraltete Session erfolgt, sollten Entwickler
|
|
alle aktiven Session-Daten des Benutzers speichern, da diese
|
|
Informationen für eine anschließende Untersuchung relevant sind. Der
|
|
Benutzer sollte zwangsweise von allen Sessions abgemeldet werden, &dh;
|
|
er muss sich neu authentifizieren. Dies verhindert, dass Angreifer
|
|
gestohlene Sessions missbrauchen können.
|
|
</simpara>
|
|
</note>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Der Zugriff auf eine veraltete Session deutet nicht unbedingt auf einen
|
|
Angriff hin. Ein instabiles Netzwerk und/oder die sofortige Löschung der
|
|
aktiven Session kann dazu führen, dass legitime Benutzer veraltete
|
|
Sessions verwenden.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Ab PHP 7.1.0 wurde <function>session_create_id</function> hinzugefügt.
|
|
Diese Funktion kann verwendet werden, um effizient auf alle aktiven
|
|
Sessions eines Benutzers zuzugreifen, indem den Session-IDs die
|
|
Benutzer-ID vorangestellt wird. Die Aktivierung von
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
ist bei dieser Einrichtung unbedingt erforderlich. Andernfalls können
|
|
böswillige Benutzer schädliche Session-IDs für andere Benutzer setzen.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Vor PHP 7.1.0 <emphasis>sollten</emphasis> Benutzer einen CSPRNG
|
|
(kryptographisch sicheren Zufallszahlengenerator) verwenden, um eine neue
|
|
Session-ID zu erzeugen, &zb; /dev/urandom oder
|
|
<function>random_bytes</function> und Hash-Funktionen.
|
|
<function>session_create_id</function> hat eine Kollisionserkennung und
|
|
erzeugt eine Session-ID gemäß den INI-Einstellungen für Sessions. Die
|
|
Verwendung von <function>session_create_id</function> ist vorzuziehen.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-id-regeneration">
|
|
<title>Erneuern von Session-IDs</title>
|
|
|
|
<para>
|
|
Die Anweisung
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
ist ein guter erster Schritt, reicht aber nicht aus. Für die Sicherheit
|
|
von Sessions sollten Entwickler auch die Funktion
|
|
<function>session_regenerate_id</function> verwenden.
|
|
</para>
|
|
|
|
<para>
|
|
Das Erneuern einer Session-ID reduziert das Risiko von gestohlenen
|
|
Session-IDs, daher sollte die Funktion
|
|
<function>session_regenerate_id</function> regelmäßig aufgerufen werden;
|
|
&zb; sollte die Session-ID für sicherheitsrelevante Inhalte alle 15
|
|
Minuten neu generiert werden. Selbst für den Fall, dass eine Session-ID
|
|
gestohlen wird, läuft die Session sowohl beim legitimen Benutzer als auch
|
|
beim Angreifer ab. Mit anderen Worten: Der Zugriff auf den Inhalt,
|
|
entweder durch den Benutzer oder den Angreifer, erzeugt beim Zugriff auf
|
|
eine veraltete Session einen Fehler.
|
|
</para>
|
|
|
|
<para>
|
|
Session-IDs <emphasis>müssen</emphasis> neu generiert werden, wenn die
|
|
Berechtigungen des Benutzers erhöht werden, &zb; nach einer
|
|
Authentifizierung. Die Funktion <function>session_regenerate_id</function>
|
|
muss aufgerufen werden, bevor die Authentifizierungsinformationen in
|
|
<varname>$_SESSION</varname> gespeichert werden
|
|
(<function>session_regenerate_id</function> speichert die aktuellen
|
|
Session-Daten automatisch, um Zeitstempel etc. in der aktuellen Session zu
|
|
speichern). Stellen Sie sicher, dass nur die neue Session das
|
|
Authentifizierungsflag enthält.
|
|
</para>
|
|
|
|
<para>
|
|
Entwickler <emphasis>dürfen sich nicht</emphasis> auf den Ablauf der
|
|
Session-ID durch
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>
|
|
verlassen. Angreifer können in regelmäßigen Abständen auf die Session-ID
|
|
eines Opfers zugreifen, um deren Ablauf zu verhindern und sie weiter
|
|
auszunutzen, unter anderem auch bei einer authentifizierten Session.
|
|
</para>
|
|
|
|
<para>
|
|
Stattdessen müssen Entwickler eine zeitstempelbasierte
|
|
Session-Datenverwaltung implementieren.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Obwohl der Session-Verwalter Zeitstempel transparent verwalten kann, ist
|
|
diese Funktion nicht implementiert. Alte Session-Daten müssen bis zur GC
|
|
aufbewahrt werden. Gleichzeitig müssen die Entwickler sicherstellen, dass
|
|
veraltete Session-Daten entfernt werden. Allerdings dürfen Entwickler
|
|
aktive Session-Daten nicht sofort entfernen, &dh;
|
|
<code>session_regenerate_id(true);</code> und
|
|
<function>session_destroy</function> dürfen niemals zusammen für eine
|
|
aktive Session aufgerufen werden. Dies mag widersprüchlich klingen, ist
|
|
aber eine zwingende Voraussetzung.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
<function>session_regenerate_id</function> löscht veraltete Sessions
|
|
standardmäßig <emphasis>nicht</emphasis>. Veraltete authentifizierte
|
|
Sessions können zur weiteren Verwendung vorhanden sein. Entwickler müssen
|
|
daher sicherstellen, dass veraltete Sessions von niemandem genutzt werden
|
|
können. Sie müssen den Zugriff auf veraltete Session-Daten selbst mit
|
|
Zeitstempeln verhindern.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Das plötzliche Entfernen einer aktiven Session erzeugt unerwünschte
|
|
Nebeneffekte. Sessions können verschwinden, wenn es gleichzeitige
|
|
Verbindungen zur Webanwendung gibt und/oder das Netzwerk instabil ist.
|
|
</simpara>
|
|
<simpara>
|
|
Potenziell böswillige Zugriffe sind durch das plötzliche Entfernen
|
|
aktiver Sessions nicht zu erkennen.
|
|
</simpara>
|
|
<simpara>
|
|
Anstatt veraltete Sessions sofort zu löschen, müssen Entwickler eine
|
|
kurzfristige Verfallszeit (Zeitstempel) in <varname>$_SESSION</varname>
|
|
setzen, die den Zugriff auf die Session-Daten verhindert.
|
|
</simpara>
|
|
<simpara>
|
|
Entwickler dürfen den Zugriff auf alte Session-Daten nicht sofort nach
|
|
<function>session_regenerate_id</function> verbieten. Das muss zu einem
|
|
späteren Zeitpunkt erfolgen, &dh; ein paar Sekunden später bei stabilen
|
|
Netzwerken, &zb; einem kabelgebundenen Netzwerk, und ein paar Minuten
|
|
später bei instabilen Netzwerken, &zb; einem Mobiltelefon oder Wi-Fi.
|
|
</simpara>
|
|
<simpara>
|
|
Wenn ein Benutzer auf eine veraltete (abgelaufene) Session zugreift,
|
|
sollte der Zugriff auf diese verweigert werden. Es wird auch empfohlen,
|
|
den Status "authentifiziert" aus allen Sessions des Benutzers zu
|
|
entfernen, da es sich wahrscheinlich um einen Angriff handelt.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Die korrekte Verwendung von
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
und <function>session_regenerate_id</function> kann einen persönlichen DoS
|
|
mit nicht löschbaren Cookies verursachen, die von Angreifern gesetzt
|
|
wurden. In diesem Fall können die Entwickler die Benutzer auffordern, die
|
|
Cookies zu entfernen und sie darauf hinweisen, dass sie von einem
|
|
Sicherheitsproblem betroffen sein könnten. Angreifer können bösartige
|
|
Cookies über eine anfällige Webanwendung setzen, über ein
|
|
ungeschütztes/schädliches Browser-Plugin, über ein physisch
|
|
kompromittiertes Gerät usw.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Unterschätzen Sie das DoS-Risiko nicht.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
ist für die allgemeine Sicherheit der Session-ID zwingend erforderlich!
|
|
Allen Webseiten wird empfohlen
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
zu aktivieren.
|
|
</simpara>
|
|
<simpara>
|
|
Ein DoS kann nur auftreten, wenn das Konto angegriffen wird. Eine durch
|
|
JavaScript verursachte Sicherheitslücke in einer Anwendung ist die
|
|
häufigste Ursache.
|
|
</simpara>
|
|
</warning>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-data-deletion">
|
|
<title>Löschen der Session-Daten</title>
|
|
|
|
<para>
|
|
Veraltete Session-Daten müssen unzugänglich gemacht und gelöscht werden.
|
|
Das aktuelle Session-Modul kann dies nicht gut handhaben.
|
|
</para>
|
|
|
|
<para>
|
|
Veraltete Session-Daten sollten so schnell wie möglich entfernt werden.
|
|
Aktive Sessions dürfen jedoch nicht sofort entfernt werden. Um diese
|
|
Anforderungen zu erfüllen, müssen die Entwickler eine auf Zeitstempel
|
|
basierende Session-Datenverwaltung selbst implementieren.
|
|
</para>
|
|
|
|
<para>
|
|
Setzen und verwalten Sie den Ablaufzeitstempel in $_SESSION. Verbieten Sie
|
|
den Zugriff auf veraltete Session-Daten. Wenn der Zugriff auf veraltete
|
|
Session-Daten festgestellt wird, ist es ratsam, den kompletten
|
|
Authentifizierungsstatus aus den Sessions des Benutzers zu entfernen und
|
|
ihn zu zwingen, sich erneut zu authentifizieren. Der Zugriff auf veraltete
|
|
Session-Daten kann einen Angriff darstellen. Um dies zu verhindern, müssen
|
|
die Entwickler alle aktiven Sessions jedes Benutzers verfolgen.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Der Zugriff auf eine veraltete Session kann auch aufgrund eines
|
|
instabilen Netzwerks und/oder konkurrierende Zugriffe auf die Website
|
|
erfolgen. Der Server hat &zb; versucht, eine neue Session-ID über ein
|
|
Cookie zu setzen, aber das betreffende Set-Cookie-Paket hat den Client
|
|
möglicherweise aufgrund eines Verbindungsverlusts nicht erreicht. Eine
|
|
Verbindung kann eine neue Session-ID per
|
|
<function>session_regenerate_id</function> ausgeben, aber eine andere
|
|
gleichzeitige Verbindung hat die neue Session-ID möglicherweise noch
|
|
nicht erhalten. Daher müssen die Entwickler den Zugriff auf die veraltete
|
|
Session zu einem späteren Zeitpunkt verhindern. Das heißt, eine
|
|
zeitstempelbasierte Session-Verwaltung zwingend ist erforderlich.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
Zusammenfassend lässt sich sagen, dass Session-Daten weder mit
|
|
<function>session_regenerate_id</function> noch mit
|
|
<function>session_destroy</function> zerstört werden dürfen, sondern es
|
|
müssen Zeitstempel verwendet werden, um den Zugriff auf die Session-Daten
|
|
zu kontrollieren. Lassen Sie <function>session_gc</function> veraltete
|
|
Daten aus dem Session-Datenspeicher entfernen.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-locking">
|
|
<title>Session und Sperren</title>
|
|
|
|
<para>
|
|
Session-Daten sind standardmäßig gesperrt, um Race Conditions zu
|
|
vermeiden. Das Sperren ist zwingend erforderlich, um Session-Daten über
|
|
Anfragen hinweg konsistent zu halten.
|
|
</para>
|
|
|
|
<para>
|
|
Die Session-Sperrung kann jedoch von Angreifern missbraucht werden, um
|
|
DoS-Angriffe durchzuführen. Halten Sie Sperren möglichst gering, um das
|
|
Risiko eines DoS-Angriffs durch die Session-Sperrung zu minimieren.
|
|
Verwenden Sie schreibgeschützte Sessions, wenn die Session-Daten nicht
|
|
aktualisiert werden müssen. Verwenden Sie bei der Funktion
|
|
<function>session_start</function> die Option "read_and_close":
|
|
<literal>session_start(['read_and_close'=>1]);</literal>. Schließen Sie
|
|
die Session, nachdem Sie $_SESSION aktualisiert haben, so schnell wie
|
|
möglich mit <function>session_commit</function>.
|
|
</para>
|
|
|
|
<para>
|
|
Das aktuelle Session-Modul erkennt <emphasis>keinerlei</emphasis>
|
|
Änderungen an $_SESSION, wenn die Session inaktiv ist. Es liegt in der
|
|
Verantwortung des Entwicklers, $_SESSION nicht zu verändern, während die
|
|
Session inaktiv ist.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.active-sessions">
|
|
<title>Aktive Sessions</title>
|
|
|
|
<para>
|
|
Die Entwickler sollten alle aktiven Sessions für jeden Benutzer im Auge
|
|
behalten und sie darüber informieren, wie viele Sessions aktiv sind, von
|
|
welcher IP-Adresse, wie lange usw. PHP speichert diese Informationen
|
|
nicht. Die Entwickler sollen dies selbst tun.
|
|
</para>
|
|
|
|
<para>
|
|
Es gibt mehrere Möglichkeiten, dies zu implementieren. Eine Möglichkeit
|
|
besteht darin, eine Datenbank zu definieren, die die erforderlichen Daten
|
|
verwaltet, und alle relevanten Informationen darin zu speichern. Da die
|
|
Session-Daten mit einer GC verbunden sind, müssen die Entwickler auf die
|
|
GC-Daten achten, um die Datenbank der aktiven Sessions konsistent zu
|
|
halten.
|
|
</para>
|
|
|
|
<para>
|
|
Eine einfache Implementierung besteht darin, die Benutzer-ID als Präfix
|
|
vor die Session-ID zu setzen und die notwendigen Informationen in der
|
|
Variablen $_SESSION zu speichern. Die meisten Datenbanken sind relativ gut
|
|
darin, ein Präfix als Zeichenkette auszuwählen. Entwickler KÖNNEN hierfür
|
|
sowohl die Funktion <function>session_regenerate_id</function> als auch
|
|
die Funktion <function>session_create_id</function> verwenden.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Verwenden Sie niemals vertrauliche Daten als Präfix. Wenn die Benutzer-ID
|
|
geheim ist, erwägen Sie die Verwendung von
|
|
<function>hash_hmac</function>.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Das Aktivieren von
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
ist für diese Konfiguration zwingend erforderlich. Stellen Sie sicher,
|
|
dass es aktiviert ist. Andernfalls kann die aktive Session-Datenbank
|
|
kompromittiert werden.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
Die zeitstempelbasierte Session-Verwaltung ist zwingend erforderlich, um
|
|
den Zugriff auf veraltete Sessions zu erkennen. Wenn der Zugriff auf eine
|
|
veraltete Session erkannt wird, sollten die Authentifizierungsflags aus
|
|
allen aktiven Sessions des Benutzers entfernt werden. Dies verhindert,
|
|
dass Angreifer weiterhin gestohlene Sessions ausnutzen können.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-and-autologin">
|
|
<title>Session und automatische Anmeldung</title>
|
|
|
|
<para>
|
|
Entwickler dürfen keine langlebigen Session-IDs für automatische
|
|
Anmeldungen verwenden, da dies das Risiko von gestohlenen Sessions erhöht.
|
|
Die Funktionalität für eine automatische Anmeldung sollte vom Entwickler
|
|
implementiert werden.
|
|
</para>
|
|
|
|
<para>
|
|
Verwenden Sie mithilfe der Funktion <function>setcookie</function> einen
|
|
sicheren, einmaligen Hash-Schlüssel als Schlüssel für die automatische
|
|
Anmeldung. Verwenden Sie einen sicheren Hash, der stärker ist als SHA-2,
|
|
&zb; SHA-256 oder höher, mit Zufallsdaten aus
|
|
<function>random_bytes</function> oder <filename>/dev/urandom</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Wenn der Benutzer nicht authentifiziert ist, prüfen Sie, ob der einmalige
|
|
Schlüssel für die automatische Anmeldung gültig ist oder nicht. Falls er
|
|
gültig ist, authentifizieren Sie den Benutzer und setzen Sie einen neuen
|
|
sicheren Einmal-Hash-Schlüssel. Ein Schlüssel für eine automatische
|
|
Anmeldung darf nur einmal verwendet werden, &dh; verwenden Sie einen
|
|
solchen Schlüssel niemals mehrfach, sondern erzeugen Sie immer einen
|
|
neuen.
|
|
</para>
|
|
|
|
<para>
|
|
Ein Schlüssel für eine automatische Anmeldung ist ein
|
|
Authentifizierungsschlüssel mit langer Lebensdauer, er sollte so gut wie
|
|
möglich geschützt werden. Verwenden Sie die Cookie-Attribute
|
|
path/httponly/secure/SameSite, um ihn zu schützen, &dh; übertragen Sie
|
|
den Schlüssel für die automatische Anmeldung nie, wenn es nicht
|
|
erforderlich ist.
|
|
</para>
|
|
|
|
<para>
|
|
Der Entwickler muss die Funktionalität implementieren, die die
|
|
automatische Anmeldung deaktivieren und das nicht benötigte Cookie für die
|
|
automatische Anmeldung entfernen.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.csrf">
|
|
<title>CSRF-Angriffe (Cross-Site Request Forgeries)</title>
|
|
|
|
<para>
|
|
Sessions und Authentifizierung schützen nicht vor CSRF-Angriffen.
|
|
Entwickler müssen den CSRF-Schutz selbst implementieren.
|
|
</para>
|
|
|
|
<para>
|
|
<function>output_add_rewrite_var</function> kann für den CSRF-Schutz
|
|
verwendet werden. Weitere Details sind auf der entsprechenden
|
|
Handbuchseite zu finden.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
PHP verwendet vor Version 7.2.0 denselben Ausgabepuffer und dieselbe
|
|
INI-Einstellung wie trans-sid. Daher ist die Verwendung von
|
|
<function>output_add_rewrite_var</function> in PHP vor Version 7.2.0
|
|
nicht empfohlen.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
Die meisten Webanwendungs-Frameworks unterstützen einen Schutz gegen CSRF.
|
|
Weitere Details sind im Handbuch des Webanwendungs-Frameworks zu finden.
|
|
</para>
|
|
|
|
<para>
|
|
Ab PHP 7.3 kann das SameSite-Attribut für das Session-Cookie gesetzt
|
|
werden. Dies ist eine zusätzliche Maßnahme, die CSRF-Schwachstellen
|
|
entschärfen kann.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="session.security.ini">
|
|
<title>INI-Einstellungen für die Sicherheit von Sessions</title>
|
|
|
|
<para>
|
|
Durch die Absicherung der für Sessions relevanten INI-Einstellungen können
|
|
Entwickler die Sicherheit von Sessions verbessern. Für einige wichtige
|
|
INI-Einstellungen gibt es keine empfohlenen Einstellungen. Für die
|
|
Absicherung der Session-Einstellungen sind die Entwickler verantwortlich.
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-lifetime">session.cookie_lifetime</link>=0
|
|
</para>
|
|
<para>
|
|
<literal>0</literal> hat eine besondere Bedeutung. Es teilt den Browsern
|
|
mit, dass das Cookie nicht dauerhaft gespeichert werden soll. Daher wird
|
|
das Cookie für die Session-ID sofort gelöscht, wenn der Browser
|
|
geschlossen wird. Wenn Entwickler diese Einstellung auf einen anderen
|
|
Wert als 0 setzen, kann dies dazu führen, dass andere Benutzer die
|
|
Session-ID verwenden können. Die meisten Anwendungen sollten dafür
|
|
"<literal>0</literal>" verwenden.
|
|
</para>
|
|
<para>
|
|
Wenn eine automatische Anmeldung erforderlich ist, müssen die Entwickler
|
|
ihre eigene sichere Funktion für die automatische Anmeldung
|
|
implementieren. Verwenden Sie dafür keine langlebigen Session-IDs.
|
|
Weitere Informationen sind oben im entsprechenden Abschnitt zu finden.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-cookies">session.use_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
Obwohl HTTP-Cookies einige Probleme aufweisen, bleiben Cookies die
|
|
bevorzugte Methode zur Verwaltung von Session-IDs. Wenn möglich, sollten
|
|
nur Cookies für die Verwaltung der Session-IDs verwendet werden. Die
|
|
meisten Anwendungen sollten ein Cookie für die Session-ID verwenden.
|
|
</para>
|
|
<para>
|
|
Bei
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=Off
|
|
verwendet das Session-Modul, falls das Cookie für die Session-ID nicht
|
|
initialisiert ist, die von GET oder POST gesetzten Werte.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
</para>
|
|
<para>
|
|
Obwohl die Aktivierung von
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
für sichere Sessions zwingend erforderlich ist, ist es standardmäßig
|
|
deaktiviert.
|
|
</para>
|
|
<para>
|
|
Dies verhindert, dass das Session-Modul eine nicht initialisierte
|
|
Session-ID verwenden kann. Anders ausgedrückt, akzeptiert das
|
|
Session-Modul nur gültige Session-IDs die vom Session-Modul erzeugt
|
|
wurden. Es lehnt jede vom Benutzer vorgegebene Session-ID ab.
|
|
</para>
|
|
<para>
|
|
Aufgrund der Cookie-Spezifikation sind Angreifer in der Lage, durch
|
|
Anlegen einer lokalen Cookie-Datenbank oder durch eine
|
|
JavaScript-Injection nicht entfernbare Cookies für die Session-ID zu
|
|
platzieren.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
kann verhindern, dass eine vom Angreifer initialisierte Session-ID
|
|
verwendet wird.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Angreifer können mit ihrem Gerät eine Session-ID initialisieren und die
|
|
Session-ID des Opfers setzen. Sie müssen die Session-ID aktiv halten, um
|
|
sie zu nutzen. In diesem Szenario benötigen Angreifer zusätzliche
|
|
Schritte, um einen Angriff durchzuführen. Daher funktioniert
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
als Schutzmaßnahme.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-httponly">session.cookie_httponly</link>=On
|
|
</para>
|
|
<para>
|
|
Verweigert den Zugriff auf das Session-Cookie durch JavaScript. Diese
|
|
Einstellung verhindert das Abgreifen von Cookies durch eine
|
|
JavaScript-Injection.
|
|
</para>
|
|
<para>
|
|
Es ist möglich, eine Session-ID als CSRF-Token zu verwenden, aber dies
|
|
wird nicht empfohlen. Zum Beispiel können HTML-Quellen gespeichert und an
|
|
andere Benutzer gesendet werden. Um die Sicherheit zu erhöhen, sollten
|
|
Entwickler keine Session-IDs in Webseiten schreiben. Fast alle
|
|
Anwendungen müssen das httponly-Attribut für das Cookie der Session-ID
|
|
verwenden.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Das CSRF-Token sollte genau wie die Session-ID regelmäßig erneuert
|
|
werden.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-secure">session.cookie_secure</link>=On
|
|
</para>
|
|
<para>
|
|
Den Zugriff auf das Cookie für die Session-ID nur dann zulassen, wenn
|
|
das Protokoll HTTPS ist. Wenn eine Webseite nur über HTTPS zugänglich
|
|
ist, sollte diese Einstellung aktiviert werden.
|
|
</para>
|
|
<para>
|
|
HSTS sollte für Webseiten in Betracht gezogen werden, die nur über HTTPS
|
|
zugänglich sind.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Lax" or
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Strict"
|
|
</para>
|
|
<para>
|
|
Ab PHP 7.3 kann das <literal>"SameSite"</literal>-Attribut für das Cookie
|
|
der Session-ID gesetzt werden. Dieses Attribut ist eine Möglichkeit,
|
|
CSRF-Angriffe (Cross Site Request Forgery) zu entschärfen.
|
|
</para>
|
|
<para>
|
|
Der Unterschied zwischen Lax und Strict ist die Verfügbarkeit des Cookies
|
|
in Anfragen, die von einer anderen registrierbaren Domain stammen und die
|
|
HTTP-GET-Methode verwenden. Cookies, die Lax verwenden, stehen in einer
|
|
GET-Anfrage, die von einer einer anderen registrierbaren Domain stammen,
|
|
zur Verfügung, während Cookies, die Strict verwenden, nicht zur Verfügung
|
|
stehen.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>=[kleinstmöglichen Wert wählen]
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>
|
|
ist eine Einstellung zum Löschen veralteter Session-IDs. Es wird
|
|
empfohlen, sich <emphasis>nicht</emphasis> auf diese Einstellung zu
|
|
verlassen. Entwickler sollten die Gültigkeitsdauer von Sessions mit einem
|
|
Zeitstempel selbst verwalten.
|
|
</para>
|
|
<para>
|
|
Die Session-GC (Garbage Collection) wird am besten mit der
|
|
<function>session_gc</function> durchgeführt. Die Funktion
|
|
<function>session_gc</function> sollte von einem Taskmanager, &zb; cron
|
|
auf UNIX-ähnlichen Systemen, ausgeführt werden.
|
|
</para>
|
|
<para>
|
|
Die GC wird standardmäßig mit einer gewissen Wahrscheinlichkeit
|
|
durchgeführt. Diese Einstellung garantiert <emphasis>nicht</emphasis>,
|
|
dass eine veraltete Session gelöscht wird. Obwohl sich Entwickler nicht
|
|
auf diese Einstellung verlassen können, wird empfohlen, sie auf den
|
|
kleinstmöglichen Wert einzustellen. Die Einstellung von
|
|
<link linkend="ini.session.gc-probability">session.gc_probability</link>
|
|
und <link linkend="ini.session.gc-divisor">session.gc_divisor</link> ist
|
|
so anzupassen, dass veraltete Sessions in angemessenen Abständen gelöscht
|
|
werden. Wenn eine automatische Anmeldung erforderlich ist, müssen die
|
|
Entwickler ihre eigene sichere Funktion für die automatische Anmeldung
|
|
implementieren. Siehe oben für weitere Informationen. Für diese Funktion
|
|
darf keine langlebige Session-ID verwendet werden.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Einige Module zur Speicherung von Sessions verwenden diese Einstellung
|
|
für die wahrscheinlichkeitsbasierte Verfallszeit nicht, &zb; memcached,
|
|
memcache. Details sind der Dokumentation des Session-Save-Handlers zu
|
|
entnehmen.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>=Off
|
|
</para>
|
|
<para>
|
|
Die Verwendung einer transparenten Verwaltung von Session-IDs ist nicht
|
|
verboten. Entwickler können sie verwenden, wenn sie erforderlich ist. Die
|
|
Deaktivierung der transparenten Verwaltung von Session-IDs verbessert
|
|
jedoch die allgemeine Sicherheit von Session-IDs, indem die Möglichkeit
|
|
einer Session-ID-Injection und/oder eines Session-ID-Lecks ausgeschlossen
|
|
wird.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Eine Session-ID kann von URLs in Lesezeichen, URLs in E-Mails,
|
|
gespeicherten HTML-Quellen usw. nach außen dringen.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-tags">session.trans_sid_tags</link>=[eingeschränkte Tags]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Entwickler sollten nicht benötigte HTML-Tags nicht
|
|
umschreiben. Der Standardwert sollte für die meisten Anwendungen
|
|
ausreichend sein. Ältere PHP-Versionen verwenden stattdessen
|
|
<link linkend="ini.url-rewriter.tags">url_rewriter.tags</link>.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-hosts">session.trans_sid_hosts</link>=[eingeschränkte Hosts]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Diese INI-Einstellung definiert Whitelist-Hosts, die
|
|
trans-sid-Rewrite erlauben. Fügen Sie niemals nicht vertrauenswürdige
|
|
Hosts hinzu. Wenn diese Einstellung leer ist, erlaubt das Session-Modul
|
|
nur <literal>$_SERVER['HTTP_HOST']</literal>.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.referer-check">session.referer_check</link>=[Ursprungs-URL]
|
|
</para>
|
|
<para>
|
|
Wenn
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
|
|
aktiviert ist, verringert diese Einstellung das Risiko der Injektion von
|
|
Session-IDs. Wenn die Webseite <literal>http://example.com/</literal>
|
|
ist, dann setzen Sie diese Option auf
|
|
<literal>http://example.com/</literal>. Beachten Sie, dass Browser bei
|
|
HTTPS keine Referrer-Header senden. Je nach Einstellungen des Browsers
|
|
werden möglicherweise keine Referrer-Header gesendet. Es handelt sich
|
|
also nicht um eine zuverlässige Sicherheitsmaßnahme, aber es wird
|
|
empfohlen, diese Einstellung zu verwenden.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cache-limiter">session.cache_limiter</link>=nocache
|
|
</para>
|
|
<para>
|
|
Stellt sicher, dass HTTP-Inhalte für authentifizierte Sessions nicht
|
|
zwischengespeichert werden. Erlaubt die Zwischenspeicherung nur, wenn der
|
|
Inhalt nicht privat ist. Andernfalls kann der Inhalt offengelegt werden.
|
|
Der Wert <literal>"private"</literal> kann verwendet werden, wenn
|
|
HTTP-Inhalte keine sicherheitsrelevanten Daten enthalten. Zu beachten
|
|
ist, dass <literal>"private"</literal> private Daten übertragen kann, die
|
|
von gemeinsam genutzten Clients zwischengespeichert werden können.
|
|
<literal>"public"</literal> darf nur verwendet werden, wenn HTTP-Inhalte
|
|
überhaupt keine privaten Daten enthalten.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.hash-function">session.hash_function</link>="sha256"
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 <) Eine stärkere Hash-Funktion erzeugt eine stärkere
|
|
Session-ID. Obwohl eine Hash-Kollision selbst mit dem
|
|
MD5-Hash-Algorithmus unwahrscheinlich ist, sollten Entwickler SHA-2 oder
|
|
einen stärkeren Hash-Algorithmus wie sha384 und sha512 verwenden. Die
|
|
Entwickler müssen sicherstellen, dass sie eine ausreichend lange
|
|
<link linkend="ini.session.entropy-length">Entropie</link> für die
|
|
verwendete Hashing-Funktion angeben.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.save-path">session.save_path</link>=[nicht allgemein lesbares Verzeichnis]
|
|
</para>
|
|
<para>
|
|
Wenn dies auf ein für die Allgemeinheit lesbares Verzeichnis gesetzt
|
|
wird, &zb; <filename>/tmp</filename> (der Standard), können andere
|
|
Benutzer auf dem Server in der Lage sein, Sessions zu kapern, indem sie
|
|
die Liste der Dateien in diesem Verzeichnis auslesen.
|
|
</para>
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|