-
Notifications
You must be signed in to change notification settings - Fork 165
Expand file tree
/
Copy pathsecurity.xml
More file actions
858 lines (774 loc) · 37.8 KB
/
security.xml
File metadata and controls
858 lines (774 loc) · 37.8 KB
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
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 55e0481a24fd4d7db21b62f1885973edbca25e60 Maintainer: yannick 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 et Sécurité</title>
<para>
Lien externe : <link xlink:href="&url.session-fixation;">Session fixation</link>
</para>
<para>
La gestion des sessions HTTP représente le cœur de la sécurité sur le Web.
Des mesures d'atténuation <emphasis>doivent</emphasis> être prises en compte afin d'assurer la
sécurité des sessions.
Les développeurs doivent activer/utiliser les paramètres de sécurité appropriés.
</para>
<sect1 xml:id="features.session.security.management">
<title>Gestion basique des sessions</title>
<sect2 xml:id="features.session.security.management.basic">
<title>Sécurité des sessions</title>
<para>
Le module de session ne peut pas garantir que les informations stockées
dans une session ne sont vues uniquement par l'utilisateur qui
a créé la session. Des mesures supplémentaires sont nécessaires pour
protéger la confidentialité de la session, suivant la valeur
qu'on lui associe.
</para>
<para>
L'importance des données stockées dans une session doit être évaluée
et des protections supplémentaires peuvent être déployées ;
ceci a obligatoirement un coût tel qu'être moins pratique pour
l'utilisateur. Par exemple, pour protéger les utilisateurs
d'une tactique simple, la directive <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
doit être activée. Dans ce cas, les cookies doivent être
activés obligatoirement côté client sinon les sessions ne
fonctionneront pas.
</para>
<para>
Il y a plusieurs façons de divulguer des identifiants de session à
des tierces personnes. I.E. injections Javascripts, identifiants
de session dans les URLs, reniflement de paquets, accès physique
au périphérique, etc.
Un identifiant de session divulgué permet à un tiers d'accéder
à toutes les ressources associées avec cet identifiant. Tout d'abord,
les URLs contenant les identifiants de session. S'il y a des liens
vers des sites ou des ressources externes, l'URL incluant l'identifiant
de session doit être stockée dans les logs referrer du site externe.
Si ces données ne sont pas chiffrées, les identifiants de session
vont être transmis en texte clair sur le réseau. La solution ici est
d'implémenter SSL/TLS sur le serveur et le rendre mandataire pour les
utilisateurs. HSTS devrait être utilisé pour améliorer également la
sécurité.
</para>
<note>
<simpara>
Même HTTPS ne peut protéger la confidentialité des données
dans tous les cas. Par exemple, les vulnérabilités CRIME et BEAST
permettent à un attaquant de lire les données. De plus, il est à noter
que certains réseaux utilisent des proxys HTTPS MITM pour
des audits. Les attaquants peuvent également mettre en place
ce genre de proxy.
</simpara>
</note>
</sect2>
<sect2 xml:id="features.session.security.management.non-adaptive-session">
<title>Gestion des sessions non adaptatives</title>
<para>
Le gestionnaire de sessions PHP est adaptatif, par défaut.
Un gestionnaire de sessions adaptatif apporte des
risques supplémentaires.
</para>
<para>
Lorsque <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
est activé, et que le gestionnaire de sauvegarde des sessions le supporte,
un identifiant de session non initialisé est rejeté, et un nouveau est créé.
Ceci prévient une attaque qui force les utilisateurs à utiliser un
identifiant de session connu.
Un attaquant peut passer des liens ou envoyer des emails qui contiennent
l'identifiant de session.
I.e. <literal>http://example.com/page.php?PHPSESSID=123456789</literal> si
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link> est activé,
la victime commencera une session en utilisant l'identifiant de session
fourni par l'attaquant.
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
permet d'annuler ce type de risque.
</para>
<warning>
<simpara>
Les gestionnaires de sauvegarde définis par l'utilisateur peuvent
aussi supporter le mode de session strict en implémentant
la validation des identifiants de session. Tous les gestionnaires de
sauvegarde définis par l'utilisateur devraient implémenter la validation
des identifiants de session.
</simpara>
</warning>
<para>
Le cookie d'identifiant de session peut être défini avec les
attributs domain, path, httponly, secure et, à partir de PHP 7.3, SameSite.
Il existe une priorité définie par les navigateurs.
En utilisant les priorités, un attaquant peut définir l'identifiant de
session qui peut être utilisé en permanence. L'utilisation de la
directive <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
ne permet pas de résoudre ce problème.
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
permet de mitiger ce risque. Avec la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On,
l'identifiant de session non initialisé sera refusé.
</para>
<note>
<simpara>
Même si la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
limite les risques concernant le gestionnaire adaptatif de session, un
attaquant peut forcer les utilisateurs à utiliser un identifiant de
session non initialisé qui a été créé par l'attaquant, c.-à-d. via des injections
Javascript. Ce type d'attaque peut être limité en utilisant les
recommandations de ce manuel.
</simpara>
<simpara>
En suivant ce manuel, les développeurs devraient activer la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>,
utiliser les timestamps basés sur le gestionnaire de session,
et régénérer les identifiants de session en utilisant la fonction
<function>session_regenerate_id</function> avec les procédures
recommandées. Si les développeurs suivent ces instructions, un identifiant de session
généré par un attaquant sera normalement supprimé.
</simpara>
<simpara>
Lorsqu'un accès à une session obsolète survient, les développeurs
devraient sauvegarder toutes les données de la session active de
l'utilisateur ; ces informations seront utiles pour de futures
investigations. L'utilisateur devrait être forcé à se déconnecter
de toutes les sessions, c.-à-d. le forçant ainsi à s'identifier de
nouveau. Ceci permet de contrer les attaques utilisant des sessions
volées.
</simpara>
</note>
<warning>
<simpara>
L'accès à une session obsolète ne veut pas forcément dire qu'il s'agit d'une
attaque. Un réseau instable et/ou l'effacement immédiat de la session
active va conduire des utilisateurs légitimes à utiliser des sessions
obsolètes.
</simpara>
</warning>
<para>
À partir de PHP 7.1.0, la fonction <function>session_create_id</function> a été
ajoutée. Cette fonction permet d'accéder à toutes les sessions actives
d'un utilisateur en préfixant les identifiants de session avec l'identifiant
de l'utilisateur. L'activation de la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
est vital dans cette configuration. Sinon, les utilisateurs malicieux
peuvent définir des identifiants de sessions pour les autres utilisateurs.
</para>
<note>
<simpara>
Les utilisateurs des versions antérieures à PHP 7.1.0 <emphasis>doivent</emphasis>
utiliser <acronym>CSPRNG</acronym>, c.-à-d. <filename>/dev/urandom</filename>, ou la fonction
<function>random_bytes</function> et les fonctions de hachage
pour générer un nouvel identifiant de session. La fonction
<function>session_create_id</function> possède des mécanismes de détection
de collision, et génère un identifiant de session suivant les
configurations INI des sessions. L'utilisation de la fonction
<function>session_create_id</function> est recommandée.
</simpara>
</note>
</sect2>
<sect2 xml:id="features.session.security.management.session-id-regeneration">
<title>Régénération d'un identifiant de session</title>
<para>
La directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
est un bon compromis mais n'est pas suffisant. Les développeurs doivent
également utiliser la fonction <function>session_regenerate_id</function>
pour la sécurité des sessions.
</para>
<para>
La régénération d'un identifiant de session réduit le risque de vol d'identifiants
de session, aussi, la fonction <function>session_regenerate_id</function>
doit être utilisée périodiquement; c.-à-d. régénérer l'identifiant de session toutes
les 15 minutes pour sécuriser le contenu sensible. Même dans le cas où
un identifiant de session est volé, à la fois le légitime utilisateur
et l'attaquant aura sa session qui va expirer. En d'autres termes, l'accès
au contenu par l'utilisateur ou l'attaquant va générer une erreur d'accès
à une session obsolète.
</para>
<para>
Les identifiants de session <emphasis>doivent</emphasis> être régénérés lorsque
les privilèges de l'utilisateur sont élevés, comme après une authentification.
La fonction <function>session_regenerate_id</function> doit être appelée
avant le stockage des informations d'authentification dans <varname>$_SESSION</varname>.
(la fonction <function>session_regenerate_id</function>
sauvegarde les données de session courantes automatiquement afin de
sauvegarder les timestamps/etc. dans la session courante.)
Il faut s'assurer que la nouvelle session contient le drapeau d'authentification.
</para>
<para>
Les développeurs <emphasis>ne doivent pas</emphasis> se baser sur
l'expiration de l'identifiant de session définie par la directive
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>.
Les attaquants peuvent accéder à l'identifiant de session de la victime
de façon périodique pour éviter son expiration, et permettre son exploitation
y compris avec des sessions authentifiées.
</para>
<para>
Au lieu de cela, les développeurs doivent implémenter un timestamp
basé sur la gestion des données de session.
</para>
<warning>
<simpara>
Même si le gestionnaire de session peut gérer les timestamps de façon
transparente, cette fonctionnalité n'est pas implémentée. Les données
des anciennes sessions doivent être conservées tant que le récupérateur
de mémoire ne soit passé. Simultanément, les développeurs doivent s'assurer
eux-mêmes que les données de session obsolètes soient effectivement effacées.
Cependant, les développeurs ne doivent pas supprimer les données
de session active trop rapidement. c.-à-d. <code>session_regenerate_id(true);</code>
et <function>session_destroy</function> ne doivent jamais être appelés
en même temps pour une session active. Ça peut paraître contradictoire,
mais c'est une exigence du mandataire.
</simpara>
</warning>
<para>
<function>session_regenerate_id</function> <emphasis>n'effacera pas</emphasis>
les anciennes sessions par défaut. Les sessions authentifiées obsolètes
peuvent être présentées pour être utilisées. Les développeurs doivent s'assurer
que les anciennes sessions ne soient pas utilisées par tout le monde.
Ils doivent interdire l'accès aux données de session obsolète
en utilisant eux-mêmes des timestamps.
</para>
<warning>
<simpara>
La suppression soudaine d'une session active produit des effets de bords
indésirables. Les sessions peuvent disparaître lorsqu'il y a des connexions
concurrentes sur l'application web et/ou lorsque le réseau est instable.
</simpara>
<simpara>
Les accès potentiellement malicieux sont indétectables avec la suppression
soudaine d'une session.
</simpara>
<simpara>
Au lieu de supprimer les sessions obsolètes immédiatement, les développeurs
doivent définir un court temps d'expiration (timestamp) dans
<varname>$_SESSION</varname>, et interdire l'accès aux données de session.
</simpara>
<simpara>
Les développeurs ne doivent pas interdire l'accès aux données des
anciennes sessions immédiatement après l'exécution de la fonction
<function>session_regenerate_id</function>. L'accès doit être interdit
à un stade ultérieur ; c.-à-d. quelques secondes après pour les réseaux
stables, comme un réseau filaire et quelques minutes après pour les réseaux
instables comme des téléphones mobiles ou des réseaux Wi-Fi.
</simpara>
<simpara>
Si un utilisateur accède à une session obsolète (session ayant expirée), l'accès
à cette session doit être refusé. Il est également recommandé de supprimer le
statut d'authentification de toutes les sessions utilisateurs, car cela
peut représenter un axe d'attaque.
</simpara>
</warning>
<para>
L'utilisation de la directive <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link> et de la fonction
<function>session_regenerate_id</function> peuvent causer des DoS personnel
avec des cookies non-supprimés définis par les attaquants. Dans ce cas,
les développeurs peuvent inviter les utilisateurs à supprimer les cookies
et les avertir qu'ils peuvent rencontrer un problème de sécurité.
Les attaquants peuvent définir des cookies malicieux via une application
web vulnérable, un plugin de navigateur exposé ou vicié, un périphérique
physique compromis, etc.
</para>
<warning>
<simpara>
Il ne faut pas se méprendre sur le risque DoS. <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
est obligatoire pour la sécurité des identifiants de session !
Tous les sites sont encouragés à activer la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
</simpara>
<simpara>
DoS peut uniquement survenir lorsque le compte subit une attaque. Une injection
Javascript dans une application représente la plupart des axes d'attaque.
</simpara>
</warning>
</sect2>
<sect2 xml:id="features.session.security.management.session-data-deletion">
<title>Suppression des données de session</title>
<para>
Les données de sessions obsolètes doivent être inaccessibles
et doivent être supprimées. Le module courant de session
ne prend pas en charge cet aspect.
</para>
<para>
Les données de sessions obsolètes doivent être supprimées aussi vite
que possible. Cependant, les sessions actives ne doivent pas être
supprimées instantanément. Pour satisfaire ces recommandations, les développeurs
eux-mêmes doivent implémenter un gestionnaire des données de session basé sur
un timestamp.
</para>
<para>
Définir et gérer l'expiration du timestamp dans la variable
globale $_SESSION. Interdire l'accès aux données de sessions
périmées. Lorsqu'un accès à des données de session obsolète est détecté,
il convient de supprimer toutes les statuts authentifiés des sessions
utilisateurs et forcer les utilisateurs à s'authentifier de nouveau.
L'accès à des données de sessions obsolètes peut représenter une attaque.
Pour arriver à cette fin, les développeurs doivent suivre toutes les sessions
actives de tous les utilisateurs.
</para>
<note>
<simpara>
L'accès à une session obsolète peut également survenir à cause d'un réseau instable
et/ou d'un accès concurrent à un site web, c.-à-d. le serveur tente de définir un
nouvel identifiant de session via un cookie, mais le paquet Set-Cookie n'a jamais
atteint le client en raison d'une perte de connexion. Une connexion peut
créer un nouvel identifiant de session via la fonction <function>session_regenerate_id</function>,
mais une autre connexion concurrente peut ne pas avoir encore reçu
l'identifiant de session. Toutefois, les développeurs doivent interdire l'accès
à une session obsolète à un moment plus éloigné. c.-à-d. la gestion des sessions
basés sur le timestamp est obligatoire.
</simpara>
</note>
<para>
En résumé, les données de sessions ne doivent pas être détruites avec la fonction
<function>session_regenerate_id</function>, ni avec la fonction <function>session_destroy</function>,
mais les timestamps doivent être utilisés pour contrôler l'accès aux données de
session. Laissez la fonction <function>session_gc</function> supprimer les données obsolètes
depuis le stockage des données de sessions.
</para>
</sect2>
<sect2 xml:id="features.session.security.management.session-locking">
<title>Session et Verrouillage</title>
<para>
Les données de session sont verrouillées par défaut pour éviter les
accès concurrent. Le verrouillage est obligatoire pour conserver une
consistance des données de session au travers les requêtes.
</para>
<para>
Cependant, le verrouillage de session peut être utilisé par les attaquants
pour réaliser des attaques DoS. Pour minimiser le risque d'une attaque DoS
par verrouillage de session, il convient de minimiser les verrous.
Utiliser des données en lecture seule lorsque les données de session
n'ont pas besoin d'être mises à jour. Utiliser l'option 'read_and_close'
avec la fonction <function>session_start</function>.
<code>session_start(['read_and_close'=>1]);</code> va clôre
la session aussi vite que possible après la mise à jour de la variable
globale $_SESSION en utilisant la fonction <function>session_commit</function>.
</para>
<para>
Le module de session courant <emphasis>ne détecte pas</emphasis>
toutes les modifications de la variable $_SESSION lorsque
la session est inactive. Il en va de la responsabilité du développeur
de ne pas modifier la variable $_SESSION lorsque la session est inactive.
</para>
</sect2>
<sect2 xml:id="features.session.security.management.active-sessions">
<title>Sessions actives</title>
<para>
Les développeurs doivent conserver une trace de toutes les sessions
actives de chaque utilisateur, et leur notifier le nombre de sessions
actives, depuis quelle adresse IP, depuis combien de temps, etc.
PHP ne conserve pas de traces de ces informations. Les développeurs
sont supposés le faire eux-mêmes.
</para>
<para>
Il existe différentes façons de faire cela. Une implémentation possible
est de définir une base de données qui conserve une trace des données
nécessaires, et y stocker toutes les informations pertinentes.
Depuis que les données de session sont GCed, les développeurs doivent
faire attention aux données GCed pour maintenir la base de données
des sessions actives consistante.
</para>
<para>
Une des implémentations simple est "l'identifiant utilisateur préfixant
l'identifiant de session" et stocker les informations nécessaires dans
la variable $_SESSION. La plupart des bases de données sont relativement
performantes pour sélectionner un préfixe sous la forme d'une &string;.
Les développeurs DOIVENT utiliser la fonction <function>session_regenerate_id</function>
ainsi que la fonction <function>session_create_id</function> pour cela.
</para>
<warning>
<simpara>
N'utiliser jamais de données confidentielles comme préfixe.
Si l'identifiant utilisateur est confidentiel, il est recommandé d'utiliser
la fonction <function>hash_hmac</function>.
</simpara>
</warning>
<warning>
<simpara>
L'activation de la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
est obligatoire pour ce type de configuration. Il faut s'assurer qu'il
est activé. Sinon, la base de données des sessions actives
peut être compromise.
</simpara>
</warning>
<para>
Le gestionnaire de session basé sur un timestamp est obligatoire
pour détecter l'accès à des sessions obsolètes. Lorsque l'accès à une
session obsolète est détecté, le drapeau d'authentification doit
être supprimé de toutes les sessions actives de l'utilisateur.
Ceci permet d'éviter aux attaquants de continuer à exploiter les sessions
volées.
</para>
</sect2>
<sect2 xml:id="features.session.security.management.session-and-autologin">
<title>Session et l'auto-identification</title>
<para>
Les développeurs ne doivent pas utiliser d'identifiants de session avec une
grande durée de vie pour l'auto-identification, car cela accroit le risque
d'utiliser des sessions volées. Une fonctionnalité d'auto-identification
doit être implémentée par le développeur.
</para>
<para>
Utiliser une clé de hachage sécurisé à usage unique comme clé
d'auto-identification en utilisant la fonction
<function>setcookie</function>. Utiliser un hachage sécurisé
plus fort que SHA-2. c.-à-d. SHA-256 ou supérieur avec des données
aléatoires depuis la fonction <function>random_bytes</function>
ou via <filename>/dev/urandom</filename>.
</para>
<para>
Si l'utilisateur est non authentifié, vérifiez si la clé d'auto-identification
à usage unique est valide ou non. Dans ce cas où elle est valide, authentifiez
l'utilisateur et définissez une nouvelle clé de hachage sécurisée à usage unique.
Une clé d'auto-identification ne doit être utilisée qu'une seule fois, c.-à-d. n'utiliser
jamais une clé d'auto-identification, et régénérez-la toujours.
</para>
<para>
Une clé d'auto-identification est une clé d'authentification avec une
longue durée, elle doit être protégée autant que possible.
Utiliser les attributs de cookie path/httponly/secure/SameSite pour la sécurité.
c.-à-d. ne transmettez jamais la clé d'auto-identification tant que cela
n'est pas nécessaire.
</para>
<para>
Les développeurs doivent implémenter les fonctionnalités qui
désactivent l'auto-identification, et suppriment les cookies
contenant les clés d'auto-identification non nécessaires.
</para>
</sect2>
<sect2 xml:id="features.session.security.management.csrf">
<title>Attaques CSRF (Cross-Site Request Forgeries)</title>
<para>
Les sessions et les authentifications ne protègent pas contre les
attaques CSRF. Les développeurs doivent implémenter des protections
CSRF eux-mêmes.
</para>
<para>
La fonction <function>output_add_rewrite_var</function> peut être utilisée pour
la protection CSRF. Se référer aux pages du manuel pour plus de détails.
</para>
<note>
<simpara>
PHP, avant sa version 7.2.0, utilise le même buffer de sortie et les
mêmes configurations INI que la configuration trans-sid. Toutefois, l'utilisation
de la fonction <function>output_add_rewrite_var</function> avec les versions
de PHP antérieures à 7.2.0 n'est pas conseillée.
</simpara>
</note>
<para>
La plupart des frameworks d'applications web supportent
la protection CSRF. Se référer au manuel du
framework d'application web pour plus de détails.
</para>
<para>
À partir de PHP 7.3, l'attribut SameSite du cookie de session peut être défini.
Ceci est une mesure supplémentaire qui peut minimiser
les vulnérabilités CSRF.
</para>
</sect2>
</sect1>
<sect1 xml:id="session.security.ini">
<title>Sécurisation des configurations INI de session</title>
<para>
En sécurisant les configurations INI de sessions, les développeurs
peuvent éprouver la sécurité des sessions. Beaucoup de configurations
INI n'ont pas de configuration recommandée. Les développeurs sont
responsables de la bonne configuration des sessions.
</para>
<itemizedlist>
<listitem>
<para>
<link linkend="ini.session.cookie-lifetime">session.cookie_lifetime</link>=0
</para>
<para>
La valeur <literal>0</literal> a une signification importante.
Elle informe les navigateurs de ne pas stocker le cookie dans un
espace de stockage permanent. Aussi, lorsque le navigateur se ferme,
le cookie d'identification de session est supprimé immédiatement.
Si les développeurs définissent une valeur différente de 0, cela permet
aux autres utilisateurs d'utiliser l'identifiant de session. La
plupart des applications devraient utiliser "<literal>0</literal>" comme
valeur.
</para>
<para>
Si une fonctionnalité d'auto-identification est désirée, les développeurs
doivent implémenter leur propre système d'auto-identification sécurité.
N'utiliser pas des identifiants de session à longue durée pour cela.
Pour plus d'informations, se rapporter à la bonne section
de cette documentation.
</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>
Bien que les cookies HTTP souffrent de soucis techniques, ils
restent la façon préférée de gérer les identifiants de sessions.
N'utiliser que les cookies pour la gestion des identifiants de sessions
lorsque cela est possible. La plupart des applications doivent utiliser
un cookie pour l'identifiant de session.
</para>
<para>
Si <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=Off,
le module de session utilisera les valeurs de l'identifiant
de sessions définies par les variables GET ou POST fournies,
et le cookie de l'identifiant de session ne sera pas initialisé.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
</para>
<para>
Bien que l'activation de <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
soit obligatoire pour la sécurité des sessions, cette directive est
désactivée par défaut.
</para>
<para>
Ce mode évite que le module de session utilise un identifiant de session
non initialisé. Dit différemment, le module de session ne va accepter
que les identifiants de sessions valides générés par le module de session.
Il va rejeter tous les identifiants de session fournis par les utilisateurs.
</para>
<para>
En raison de la spécification des cookies, les attaquants sont capables
de placer des cookies contenant les identifiants de sessions en configurant
localement une base de données de cookie ou par injections Javascript.
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> peut éviter qu'un attaquant
n'initialise un identifiant de session.
</para>
<note>
<para>
Les attaquants peuvent initialiser un identifiant de session avec leur
propre périphérique, et peuvent définir l'identifiant de session
de leur victime. Ils doivent alors conserver l'identifiant de session
actif pour pouvoir en abuser.
Les attaquants doivent passer par bien d'autres étapes pour réussir leur attaque
dans ce scénario. Aussi, l'utilisation de la directive
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> permet de limiter les risques.
</para>
</note>
</listitem>
<listitem>
<para>
<link linkend="ini.session.cookie-httponly">session.cookie_httponly</link>=On
</para>
<para>
Permet de refuser l'accès à un cookie de session depuis javascript.
Cette configuration évite qu'un cookie ne soit corrompu par une
injection Javascript.
</para>
<para>
Il est possible d'utiliser un identifiant de session comme jeton CSRF, mais
ce n'est pas recommandé. Par exemple, des sources HTML peuvent être
sauvegardées et envoyées à d'autres utilisateurs.
Les développeurs ne doivent pas écrire les identifiants de session dans les
pages web pour des raisons de sécurité. Toutes les applications web doivent
utiliser l'attribut httponly pour le cookie contenant l'identifiant de session.
</para>
<note>
<para>
Le jeton CSRF doit être renouvelé périodiquement, tout comme l'identifiant
de session.
</para>
</note>
</listitem>
<listitem>
<para>
<link linkend="ini.session.cookie-secure">session.cookie_secure</link>=On
</para>
<para>
Permet d'accéder au cookie d'identifiant de session uniquement lorsque
le protocole est HTTPS. Si un site web n'est accessible que par HTTPS,
cette directive doit être activée.
</para>
<para>
HSTS doit être utilisé pour les sites web accessibles que par HTTPS.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Lax" ou
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Strict"
</para>
<para>
À partir de PHP 7.3, l'attribut <literal>"SameSite"</literal> peut être défini
pour le cookie d'identifiant de session. Cet attribut est une façon de
mitiger les attaques CSRF (Cross Site Request Forgery).
</para>
<para>
La différence entre Lax et Strict est l'accessibilité du cookie dans les requêtes
originaires d'autres domaines employant la méthode HTTP GET.
Les cookies utilisant Lax seront accessibles via une requête GET originaire
d'un autre domaine, alors que les cookies utilisant Strict ne le seront pas.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>=[choisissez le plus petit possible]
</para>
<para>
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link> est une configuration pour supprimer
l'identifiant de session obsolète. Le fait de se reposer
entièrement sur cette configuration <emphasis>n'est pas</emphasis> recommandé.
Les développeurs doivent gérer la durée de vie des sessions avec un timestamp
par eux-mêmes.
</para>
<para>
Le GC des sessions (garbage collection) est mieux réalisé en utilisant
la fonction <function>session_gc</function>.
La fonction <function>session_gc</function> doit être exécutée par un gestionnaire
de tâches ; c.-à-d. un cron sur les systèmes Unix.
</para>
<para>
GC est exécuté par probabilité, par défaut. Cette configuration
<emphasis>ne garantit pas</emphasis> que les anciennes sessions soient
supprimées. Bien que les développeurs ne doivent pas s'appuyer sur ce paramètre,
il est recommandé tout de même de le définir à une valeur la plus petite possible.
Il convient d'ajuster les directives <link
linkend="ini.session.gc-probability">session.gc_probability</link>
et <link
linkend="ini.session.gc-divisor">session.gc_divisor</link> de sorte à ce que
les sessions obsolètes soient supprimées à fréquence appropriée.
Si la fonctionnalité d'auto-identification est nécessaire, les développeurs
doivent implémenter leur propre fonctionnalité d'auto-identification sécurisée ;
voir ci-dessous pour plus d'informations. N'utiliser jamais l'identifiant
de session de longue durée pour réaliser ce genre de fonctionnalité.
</para>
<note>
<para>
Quelques modules de gestion de sauvegarde des sessions n'utilisent pas cette
fonctionnalité basée sur l'expiration et sur la probabilité ; c.-à-d.
memcached, memcache. Se référer à la documentation de ces gestionnaires
de sauvegarde des sessions pour plus de détails.
</para>
</note>
</listitem>
<listitem>
<para>
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>=Off
</para>
<para>
L'utilisation d'un gestionnaire d'identifiants de sessions transparent
n'est pas interdit. Les développeurs doivent l'employer lorsque nécessaire.
Pourtant, la désactivation de la gestion des identifiants de session de
façon transparente permet de sécuriser un peu plus les identifiants de session
en éliminant la possibilité d'une injection d'identifiant de sessions ou
de fuite de cet identifiant.
</para>
<note>
<para>
L'identifiant de session peut fuiter depuis des URLs sauvegardées,
des URLs dans des emails, d'une source HTML sauvegardée, etc.
</para>
</note>
</listitem>
<listitem>
<para>
<link linkend="ini.session.trans-sid-tags">session.trans_sid_tags</link>=[drapeaux limités]
</para>
<para>
(PHP 7.1.0 >=) Les développeurs ne doivent pas réécrire de drapeaux HTML
non nécessaires. La valeur par défaut doit être suffisante pour la
plupart des utilisations. Pour les versions de PHP plus anciennes,
utiliser plutôt
<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>=[hôtes limités]
</para>
<para>
(PHP 7.1.0 >=) Ce paramètre définit une liste blanche des hôtes qui sont
autorisés à réécrire les identifiants de session transparents. Ne jamais
ajouter d'hôte qui ne sont pas de confiance !
Le module de session autorise uniquement <literal>$_SERVER['HTTP_HOST']</literal>
lorsque ce paramètre est vide.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.referer-check">session.referer_check</link>=[URL d'origine]
</para>
<para>
Lorsque le paramètre <link
linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
est actif.
Ce paramètre réduit les risques d'injection d'identifiant de session.
Si un site web est <literal>http://example.com/</literal>,
définissez comme valeur à ce paramètre <literal>http://example.com/</literal>.
Il est à noter que les navigateurs HTTPS n'envoient pas l'en-tête referrer.
Les navigateurs peuvent ne pas envoyer l'en-tête referrer de part
leur propre configuration. Aussi, ce paramètre ne peut pas être
considéré comme une mesure fiable de sécurité.
Malgré tout, son utilisation est recommandée.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.cache-limiter">session.cache_limiter</link>=nocache
</para>
<para>
S'assure que le contenu HTTP n'est pas mis en cache pour les sessions
authentifiées. Permet la mise en cache que pour les contenus
qui ne sont pas privés. Sinon, le contenu sera exposé.
La valeur <literal>"private"</literal> doit être employée si le contenu HTTP n'inclut pas
des données sensibles d'un point de vue sécurité. Il est à noter que <literal>"private"</literal>
peut transmettre des données privées mises en cache pour les clients
partagés. <literal>"public"</literal> doit être uniquement utilisé lorsque le contenu HTML
ne contient aucune donnée privée.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.hash-function">session.hash_function</link>="sha256"
</para>
<para>
(PHP 7.1.0 <) Une fonction de hachage forte va générer un identifiant
de session fort. Bien qu'une collision de hachage soit peu probable avec des
algorithmes de hachage MD5, les développeurs doivent utiliser SHA-2 ou un
algorithme de hachage plus fort comme sha384 et sha512.
Les développeurs doivent s'assurer d'une longueur suffisante de
l'<link linkend="ini.session.entropy-length">entropie</link> pour la
fonction de hachage utilisée.
</para>
</listitem>
<listitem>
<para>
<link linkend="ini.session.save-path">session.save_path</link>=[dossier non lisible par tout le monde]
</para>
<para>
Si ce paramètre est défini à un dossier accessible en lecture par tout le monde,
comme <filename>/tmp</filename> (par défaut), les autres utilisateurs du serveur
seront capables de récupérer les sessions en listant les fichiers présents
dans ce répertoire.
</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
-->