-
Notifications
You must be signed in to change notification settings - Fork 43
/
security.xml
882 lines (796 loc) · 36.4 KB
/
security.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: ccb379494533c9b7d63a81f0221231a9e526eee9 Maintainer: samesch Status: ready -->
<!-- Reviewed: yes -->
<!-- Rev-Revision: 184f3f7bd45643cb80f828d0bb001991ec3a5fad Reviewer: samesch -->
<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.sid-length">session.sid_length</link>="48"
</para>
<para>
(PHP 7.1.0 >=) Je länger eine Session-ID ist, desto stärker ist sie.
Entwickler sollten in Erwägung ziehen, die Länge der Session-IDs auf
mindestens 32 Zeichen zu erhöhen. Bei
<link linkend="ini.session.sid-bits-per-character">session.sid_bits_per_character</link>="5"
sind mindestens 26 Zeichen erforderlich.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.sid-bits-per-character">session.sid_bits_per_character</link>="6"
</para>
<para>
(PHP 7.1.0 >=) Je mehr Bits ein Zeichen einer Session-ID enthält,
desto stärker ist die vom Session-Modul generierte Session-ID bei
gleicher Länge der Session-ID.
</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
-->