Réinitialiser les variables $_SERVEUR['PHP_AUTH_USER'] et PSW ?

Résolu
floxone Messages postés 88 Date d'inscription mardi 19 avril 2005 Statut Membre Dernière intervention 10 août 2007 - 2 juin 2005 à 13:45
cs_sjon Messages postés 861 Date d'inscription mardi 26 mars 2002 Statut Membre Dernière intervention 29 novembre 2006 - 4 juin 2005 à 02:54
Salut,

J'ai un problème... Est-il possible de réinitiliser en dur dans une page web les variables de serveur. Et cela sans ouvrir une fenetre de saisie...

En clair, je veux me delogger d'un header('WWW-Authenticate: Basic realm="Administration"');

Merci de votre aide.

7 réponses

cs_sjon Messages postés 861 Date d'inscription mardi 26 mars 2002 Statut Membre Dernière intervention 29 novembre 2006 1
3 juin 2005 à 02:35
Sael og blesud

Par ailleurs, le plus comique dans l'histoire c'est que cela n'est pas aussi sécurisé que vous le pensez floxone. Je vais vous expliquer pourquoi : ( Désolé Antho encore un poste long ;-) )

La méthode d'authentification dite « HTTP Basic » ne met en oeuvre aucun service de confidentialité quant à la transmission des accréditations au serveur. Il s'agit d'une méthode communément employée, conjointement au protocole SSL/TLS.

Le mécanisme est le suivant :

a. Le client émet une requête à destination d'une ressource protégée, le répertoire identifié par l'URI /basic par exemple. La requête simple correspondante est :
GET /basic/ HTTP/1.0

b. Le serveur répond avec le code d'erreur 401 (Unauthorized), et sa réponse comporte l'entête WWW-authenticate, spécifiant le type d'authentifcation attendue :
HTTP/1.1 401 Authorization Required
WWW-Authenticate: Basic realm="Basic realm"

c. L'entête renvoyé par le serveur est interprété par le navigateur. Celui-ci présente une fenêtre à l'utilisateur, l'invitant à entrer ses accréditations. Le navigateur réitère la précédente requête, en intégrant l'entête Authorization, suivie de la concaténation du nom d'utilisateur, de ":" et du mot de passe, le tout encodé en base64.

Par exemple, pour la paire login/mot de passe dummy:secret :
$ echo -n 'dummy:secret' | openssl enc -a -e
ZHVtbXk6c2VjcmV0

La requête résultante est donc la suivante :
GET /basic/ HTTP/1.0
Authorization: Basic ZHVtbXk6c2VjcmV0

Les accréditations sont donc transmises en clair (encodées) à _chacune_ des requêtes (dans la mesure où le protocole HTTP est dit « sans état »). Il ne s'agit pas de chiffrement ! Les accréditations sont mises en cache par le navigateur, évitant ainsi au client d'avoir à les fournir à chacune des requêtes émises. Cette méthode d'authentification est donc particulièrement sensible à une écoute du trafic. Si un service de confidentialité est mis en oeuvre à travers un mécanisme de chiffrement au niveau transport/session (SSL/TLS par exemple), seul un serveur malveillant pourra accéder à ces accréditations (si l'on exclue la faille des protocoles SSL/TLS permettant, par analyse temporelle pour un attaquant actif, de décrypter un bloc de données chiffré suivant un algorithme symétrique en mode CBC).

d. Le serveur renvoie la page protégée (HTTP/1.1 200 OK).

Au niveau des journaux, la ligne suivante est générée :
127.0.0.1 - dummy [30/Jan/2003:13:40:50 +0100] "GET /basic/ HTTP/1.0" 200 820 "-" " ""w3m/0.3.1+cvs-1.411""

Cette ligne indique que l'utilisateur 'dummy' a accédé avec succès au répertoire /basic (code 200).

Remarques :
- lorsqu'un login apparemment inconnu apparaît dans les journaux, penser à regarder le code de retour correspondant
- le mot de passe peut être conservé dans une base de données, un annuaire LDAP etc. Il peut également s'agir d'un mot de passe à usage unique, de type S/KEY, PAM_OPIE etc. Seule est décrite ici la méthode employée par le client pour transmettre ses accréditations au serveur (usage des entêtes HTTP en l'occurrence).

Dans le cas de l'authentification de type « Basic », le « suivi » de session est réalisé par la retransmission systématique des accréditations (à chacune des requêtes).

La méthode d'authentification dite « HTTP Digest » met en oeuvre un service de confidentialité pour les accréditations, mais pas pour les données transférées (côté client, comme côté serveur). Elle introduit des mécanismes contre le rejeu, et protège le client contre un serveur malveillant, ou potentiellement corrompu, dans la mesure où les accréditations ne sont jamais connues par ce
dernier.

Il s'agit d'un mécanisme de type « challenge/response », joué pour chaque ressource demandée : très simplement, le serveur envoie un challenge au client, ce dernier répond par une valeur dérivée de ce challenge et d'un secret qu'il partage avec le serveur. Le serveur s'assure alors que le client possède effectivement le secret en calculant à son tour la réponse et vérifiant la
cohérence des deux.

Les traces effectuées dans cette brève ont été réalisées suite à l'utilisation du module mod_auth_digest d'Apache, et non du module standard mod_digest (qui met en oeuvre un support partiel de l'authentification digest).

Le mécanisme, dans le cas le plus simple (authentification sans intégrité), est le suivant :

a. Comme précédemment, le client émet une requête à destination d'une ressource protégée, identifiée par son URI :

GET /digest/ HTTP/1.0

b. La réponse du serveur, légèrement épurée, est comme suit :

HTTP/1.1 401 Authorization Required
WWW-Authenticate: Digest realm="Digest Realm",
nonce="uD85Pg==a766f996fa716e4d4592943b5762c73958f0378b", algorithm=MD5,
domain="/digest", qop="auth"

Elle comporte, notamment :
- un challenge (« nonce »)
- un identifiant d'algorithme (« algorithm ») : la fonction de hachage MD5, dans ce cas

Pour chaque page protégée, le client va calculer une réponse à partir de ces paramètres en utilisant son mot de passe. En pratique, le challenge n'est pas renouvelé à chaque requête -- ce qui limite le non-rejeu.

c. Le client calcule en réponse l'empreinte qui sera émise via l'entête Authorization, comme lors d'une authentification de type « Basic » : (la méthode de calcul est donnée dans la RFC 2617) :

request-digest = <"> < KD ( H(A1), unq(nonce-value)
":" nc-value
":" unq(cnonce-value)
":" unq(qop-value)
":" H(A2)
) <">
avec :

KD (secret,data) = H(concat(secret, ":", data)
- H étant la fonction de hachage MD5 (et concat signifiant la concaténation des chaînes)
A1 = unq(username-value) ":" unq(realm-value) ":" passwd
A2 = Method ":" digest-uri-value

Quelques remarques :
- unq correpond à « unquoted ».
- le paramètre cnonce-value est choisi par le client (d'où le préfixe 'c').
Dans ce cas, la valeur choisie par le navigateur donnera un champ unq(cnonce-value) égal à be09d67c532a3a02.

Le calcul effectué par le client est donc comme suit (le nom d'utilisateur étant 'dummy', et le mot de passe correspondant 'secret') :

* Pour H(A1) :

$ echo -n 'dummy:Digest Realm:secret' | openssl md5
0c440e535a0afdc350f3f8ba0aa2f271

Remarque : cette empreinte est celle conservée côté serveur (dans le fichier .htaccess, généré par htdigest( Comme décrt dans la RFC2616 ) pour un serveur Apache). Le serveur n'a donc pas la connaissance du mot de passe de l'utilisateur. La connaissance du mot de passe en clair n'est donc pas nécessaire côté serveur -- au contraire de mécanismes d'authentification similaire de type apop.

* Pour H(A2) :

$ echo -n 'GET:/digest/' | openssl md5
9942091bc79111e32fecde3962416017

Remarque : la QUERY_STRING (chaîne figurant après '?') est prise en compte dans l'URI pour le calcul de l'empreinte !

Au final, la réponse est la suivante :

$ echo -n
'0c440e535a0afdc350f3f8ba0aa2f271:uD85Pg==a766f996fa716e4d4592943b5762c7395
8f0378b:00000001:be09d67c532a3a02:auth:9942091bc79111e32fecde3962416017'
| openssl md5

Soit : 46f122dedae2a5f8ffbf82d6ad605304

La requête résultante est la suivante, avec la réponse dans le champ 'response' :

GET /digest/ HTTP/1.1
Authorization: Digest username="dummy", realm="Digest Realm",
nonce="uD85Pg==a766f996fa716e4d4592943b5762c73958f0378b", uri="/digest/",
algorithm=MD5, response="46f122dedae2a5f8ffbf82d6ad605304",
qop=auth, nc=00000001, cnonce="be09d67c532a3a02"

d. Le serveur répond positivement, avec l'entête Authentication-Info :

HTTP/1.1 200 OK
Authentication-Info: rspauth="1d4d5a9d920fb22197471146c613e767",
cnonce="be09d67c532a3a02", nc=00000001, qop=auth

L'entête rspauth permet une authentification mutuelle. Le serveur prouve en effet par ce biais qu'il connaît effectivement le mot de passe du client : le calcul effectué est identique à celui effectué par le client, au détail près que le paramètre A2 est pris égal à ':/digest/', la méthode n'est pas prise en compte.

Remarque : le non-rejeu est situé au niveau « session HTTP » (par abus de langage, session pendant laquelle est utilisable le « nonce »), et non au niveau « requête HTTP » : dans le cas du module Apache mod_auth_digest, la durée de vie du paramètre nonce est fixée par le paramètre AuthDigestNonceLifetime. Au delà de cette durée, le nonce est renouvelé, et le client doit s'authentifier à nouveau, et explicitement (le serveur lui renvoie un code d'erreur 401). On peut donc raisonnablement considérer que seul un service de confidentialité des accréditations est mis en oeuvre, et non un véritable service de non-rejeu.

Outre les indéniables avantages qu'elle présente en terme de confidentialité des accréditations (vis à vis d'un intercepteur comme d'un serveur malveillant, vers lequel le trafic aurait été détourné), la méthode d'authentification HTTP «Digest » est surtout connue, ou notoire, pour l'incompatibilité constatée entre le serveur HTTP le plus répandu, Apache, d'une part, et le navigateur le plus répandu d'autre part, MSIE.

Cette incompatibilité tient à une interprétation incorrecte de la RFC 2616 par MSIE (et IIS, par extension).

Le court CGI qui suit permet d'illustrer cette constatation :

$ cat ./digest/printenv.cgi
#!/usr/bin/perl
print "Content-Type: text/plain\n\n";
foreach $key (sort keys(%ENV)) { print "$key = $ENV{$key}\n"; }

Une requête effectuée par MSIE sur l'URI /digest/printenv.cgi avec la QUERY_STRING param=value donne le résultat, épuré, suivant :

GET /digest/printenv.cgi?param=value HTTP/1.0
Authorization: Digest username="dummy", realm="Private Area", qop="auth",
algorithm="MD5", uri="/digest/printenv.cgi",
nonce="KPw3Pg==08fc61d5b52c87dbda7b038a1c741fd82ae12756", nc=00000007,
cnonce="67fa5778e4fac113bc53ca089cf10fa6",
response="5045459a94e92c1844e8e1e5a6309c3e"

La réponse du serveur se solde par un échec (code d'erreur 400) :

HTTP/1.1 400 Bad Request
[...]

Bad Request

Your browser sent a request that this server could not understand.Digest: uri mismatch - </digest/printenv.cgi> does not match request-uri &lt;/digest/printenv.cgi?param=value&gt;

Ainsi, MSIE calcule sa réponse en prenant comme valeur pour le paramètre digest-uri-value la variable REQUEST_URI (/digest/printenv.cgi?param=value), mais _sans_ la partie QUERY_STRING (param=value). Des CGI dont l'accès est
restreint et requèrent une authentification de type digest doivent par conséquent recevoir leurs paramètres sur leur entrée standard (passés dans le corps de la requête, via POST), et non plus via l'environnement par la variable QUERY_STRING.

Une autre méthode suggérée : utiliser la variable PATH_INFO. Cette variable d'environnement est initialisée lorsqu'un « chemin » est concaténé au CGI à exécuter. Par exemple, la requête GET /digest/printenv.cgi/chemin/supplementaire?param=value va initialiser les variables PATH_INFO (/chemin/supplementaire) et QUERY_STRING (param=blah).

Comme précédemment, le suivi de session est réalisé par la transmission, à chaque requête, des accréditations. Ces dernières sont transmises et calculées pour chaque requête, dérivées des paramètres d'authentification mis en cache par le navigateur.

Voilà, j'espère que vous y trouverez vos réponses

Désolé Anthomicro ;-) ...

Bon courage ...

NB : Si la réponse vous convient merci de l'accepter pour fermer ce thread ...

Sigurjón Bírgir Sigurðssón aka Sjón

HARDWARE : Partie de l'ordinateur qui reçoit les coups quand se plante le software ...
3
cs_sjon Messages postés 861 Date d'inscription mardi 26 mars 2002 Statut Membre Dernière intervention 29 novembre 2006 1
2 juin 2005 à 20:34
Sael og blesud

Non on vous l'a déjà dit ... cf : http://www.phpcs.com/forum.v2.aspx?ID=443605

Bon courage ...

NB : Si la réponse vous convient merci de l'accepter pour fermer ce thread ...

Sigurjón Bírgir Sigurðssón aka Sjón

HARDWARE : Partie de l'ordinateur qui reçoit les coups quand se plante le software ...
0
cs_Anthomicro Messages postés 9433 Date d'inscription mardi 9 octobre 2001 Statut Membre Dernière intervention 13 avril 2007 8
2 juin 2005 à 21:46
Salut,



c'est marrant ça mdr, non non même longtemps après on ne dira pas le contraire floxone hein...

<hr size="2" width="100%">




<li>Entraide, dépannage et vulgarisation informatique: Mon site de vulgarisation informatique</li>
0
cs_Anthomicro Messages postés 9433 Date d'inscription mardi 9 octobre 2001 Statut Membre Dernière intervention 13 avril 2007 8
3 juin 2005 à 13:31
Non mais c'est un poste d'une très grande qualité ;-)



Par contre pour la sécurisation si tu parles de la sécurisation des
données transmises ok, sinon un htaccess apporte quand même une
meilleure sécurité que son équivalent en PHP (tout dépend comment c'est
codé encore une fois...)



Bref je suis d'accord avec toi

<hr size="2" width="100%">




<li>Entraide, dépannage et vulgarisation informatique: Mon site de vulgarisation informatique</li>
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
floxone Messages postés 88 Date d'inscription mardi 19 avril 2005 Statut Membre Dernière intervention 10 août 2007
3 juin 2005 à 14:46
Voici une reponse d'une grande qualite...

Ca merite bien un accepté !

Merci ;-)
0
cs_sjon Messages postés 861 Date d'inscription mardi 26 mars 2002 Statut Membre Dernière intervention 29 novembre 2006 1
3 juin 2005 à 21:00
Sael og blesud

>> Antho <<< end_antho

Tout d'abord merci pour le Post. Le but était tout naturellement d'expliquer le mécanisme usé lors d'authentification PHP qui est relativement faible côté sécurité quand ce dernier est de type "Basic" puisqu'il ne s'agît que d'un encodage base64 en non pas de chiffrement ... Afin de montrer à Floxone que cela n'était pas aussi sécurisé qu'il voulait bien le croire ;-). Ensuite j'ai montré le mécanisme lorsque le type est "Digest" qui est un peu mieux mais non sans exception ... Comme vous dîtes cela dépend de la façon dont c'est codé. Mais cela dépend aussi de la façon dont le dit server est configuré et maintenu. J'ai vu en effet certains administrateurs qui ne voulant pas bloquer la moindre requête DNS de leur réseau interne par exemple ouvrait volontairement le port 53 UDP partout sur tous les server ;-O et cela par pure incompétence qu'elle soit dûe au laxisme ou à l'ignorance ... ;-). Cependant j'aurais aussi pu aborder l'authentification HTTPS.
Au niveau du .htaccess je suis relativement d'accord avec vous mais là encore j'ajouterai un bémol ... ;-) ... En effet combien de webmaster use de ce procédé pour du RewritingURL par exemple mais sans maitriser les expressions régulière ( Perl est très bien pour apprendre leurs fonctionnements ;-) ). Ce qui fait que cela fonctionne pour ce qu'il souhaite et c'est là la seule chose qu'ils testent alors que comme leurs expressions ne sont pas "blindées" cela ouvre de multiples possibilités. Enfin le discours pourrait être long encore à ce sujet ... Mais merci bien ...

PS : Vous avez vu ma signature n'est pas si longue que cela en fait ( cf : post précédent ) ;-)

end_antho

>>floxone <<<end_floxone

Bah merci bien pour le Post. Je ne pense pas que vous trouverez votre solution dans l'authentification PHP mais via des sessions cela peut apporter un niveau de sécurité suffisament important. Mais c'est comme pour tout il faut que cela soit bien codé et propre surtout, ne rien laissé au hasard ( si je fais cela qu'est-ce qui peut en découler ? ... etc ... ). Merci ...

end_floxone

Oh et puis après tout ;-)
>> Antho Bah heu comment dire heu ...désolé
>> Floxone cela peut vous correspondre ... à vous de voir

Authentification HTTPS :

Le protocole HTTPS met en oeuvre des services d'authentification des parties (unilatérale ou mutuelle, à partir du protocole SSLv3), d'authenticité et de confidentialité des données pendant toute une session SSL/TLS (la session «multiplexant » les connexions TCP et requêtes HTTP associées).

La méthode d'authentification HTTP de type Basic est le plus souvent utilisée conjointement à SSL/TLS, afin d'assurer la confidentialité des accréditations.

Le protocole HTTPS introduit, par l'intermédiaire des protocoles SSLv3/TLS, une méthode d'authentification du client par certificat X.509v3.

Mécanisme :

Observons déjà le format du fichier openssl.conf

Il faut se référer au fichier openssl.cnf par défaut pour avoir le format général. Seules les extensions v3 seront manipulées, respectant la syntaxe : extension_name=[critical,] extension_options

Ces extensions sont introduites car les bi-clés générés peuvent être de divers usages (bi-clé de chiffrement, bi-clé de signature et bi-clé d'échange de clés) et les exigences en terme de sécurité différentes (recouvrement pour un bi-clé de chiffrement, auquel un service de non répudiation ne peut donc être associé).

Outre des informations sur le bi-clé, ces extensions permettent d'imposer des contraintes sur l'itinéraire de certification à parcourir
(autrement dit la chaîne à parcourir pour valider un certificat), renseigner sur la politique de certification concernant le certificat
présenté, ou encore sur la façon d'accèder aux listes de révocation.

Les plus courantes sont brièvement abordées :

* basicConstraints
- pathlen : nombre de CA pouvant apparaître sous (autrement signés par) le certificat
- CA : TRUE pour une autorité, inutile pour une entité terminale (mais à FALSE pour compatibilité)

* keyUsage
- digitalSignature (RSA/DSA) : pour la signature (en tant que mécanisme, autrement dit le chiffrement d'une empreinte avec une clé privée)
- nonRepudiation (RSA/DSA) : idem, mais en tant que service (autrement dit la volonté d'ajouter un service de non répudiation à une signature). Pour du S/MIME, bit positionné avec digitalSignature typiquement
- keyEncipherment (RSA) : chiffrement de clé (clé secrète d'algorithme symétrique généralement, ou premaster secret ou encore clé RSA éphémère en SSL/TLS)
- dataEncipherment (RSA) : chiffrement de données (hors clé de session, crl, certificat)
- keyCertSign (RSA/DSA) : signature de certificats (pour les CA donc)
- cRLSign (RSA/DSA) : signature de listes de révocation
- keyAgreement (DH) : pour la négociation d'une clé de session
- encipherOnly et decipherOnly (DH) : positionnés conjointement à keyAgreement

* nsCertType
- client ou server : pour une authentification client ou serveur en SSL/TLS
- email : pour du S/MIME
- objsign : pour la signature de code (applet java typiquement)
- sslCA, emailCA, objCA : pour délivrer des certificats ayant les propriétés précédentes

* extendedKeyUsage
serverAuth, clientAuth, codeSigning, emailProtection, pour les plus courantes.
Les noms sont suffisamment explicites.

* subjectAltName
Utiles pour les hôtes virtuels par nom, ou encore les adresses emails multiples associées à un même certificat. Malheureusement, c'est le commonName qui est généralement utilisé.

* crlDistributionPoints
Indique le(s) façon(s) de télécharger les listes de révocation, via LDAP ou HTTP.

Maintenant voyons la génération des certificats

Le fichier de configuration openssl.cnf, est supposé situé dans le répertoire courant.

On crée les fichiers et répertoires nécessaires :
$ mkdir -p ca/newcerts # Répertoire recueillant les certificats émis par CA ROOT
$ touch ca/index.txt # Base de données des certificats émis
$ echo '01' > ca/serial # Numéro de série, initialisé à 1. Incrémenté par la suite

$ mkdir -p cassl/newcerts #idem, pour CA SSL
$ touch cassl/index.txt
$ echo '01' > cassl/serial

Génération du certificat de l'autorité racine

Il s'agit du CA racine, par conséquent autosigné.

* Génération du bi-clé RSA, protégé par une passphrase
$ openssl genrsa -out ca/ca.key -des3 2048

* Génération du certificat auto-signé
$ openssl req -new \
-x509 \ # Génération d'un certificat autosigné, et non d'une simple requête
-key ca/ca.key \ # La clé publique est extraite du bi-clé précédente
-out ca/ca.pem \ # Le certificat est copié
-config ./openssl.cnf \ # Le fichier de configuration n'est pas celui par défaut
-extensions CA_ROOT # La section CA_ROOT est utilisée (cf Annexe)

Pour vérifier le bon usage du certificat :
$ openssl x509 -in ca/ca.pem -text -noout
$ openssl x509 -purpose -in ca/ca.pem -noout

Génération du certificat de l'autorité intermédiaire SSL

Il s'agit d'un CA intermédiaire, dont le certificat est signé par le CA ROOT.

$ openssl genrsa -out cassl/cassl.key -des3 2048

Génération de la demande de certificat :
$ openssl req -new \ # Génération d'une demande de certificat
-key cassl/cassl.key \
-out cassl/cassl.crs \
-config ./openssl.cnf

Signature de la demande de certificat par le ca root (CA par défaut dans openssl.cnf) :
$ openssl ca -out cassl/cassl.pem \
-config ./openssl.cnf \
-extensions CA_SSL \
-infiles cassl/cassl.crs # Demande de certificat à signer
Ainsi :
* Le certificat signé est crée dans cassl/cassl.pem
* Une copie est réalisée dans ca/newcerts/01.pem
* Les fichiers ca/serial et ca/index.txt sont mis à jour

Génération d'un certificat serveur SSL

# openssl genrsa -out cassl/serverssl.key -des3 1024
$ openssl req -new \
-key cassl/serverssl.key \
-out cassl/serverssl.crs \
-config ./openssl.cnf

$ openssl ca -config ./openssl.cnf \
-name CA_ssl_default \ # Le certificat utilisé pour signer la requête est celui de CA SSL
-extensions SERVER_RSA_SSL \
-infiles cassl/serverssl.crs

Dans ce cas, l'autorité signataire est ca_ssl Si tout se déroule correctement :
Le certificat serveur est renvoyé sur la sortie standard, et copié dans cassl/newcerts/01.pem Les fichiers cassl/serial et cassl/index.txt sont mis à jour.

Remarque : pour générer un certificat client, il faut reproduire la procédure ci-dessus, avec l'extension CLIENT_RSA_SSL (voir le fichier de configuration en annexe). Généralement, on l'exporte avec la clé privée dans un fichier pkcs#12, suivant la syntaxe :

$ openssl pkcs12 -export \
-inkey clientssl.key \
-in clientssl.pem \
-out clientssl.p12 \
-name "Certificat client"

Enfin on importe le fichier obtenu dans son navigateur.

Configuration

Les paramètres généralement rencontrés sont les suivants :

(1) Le certificat X.509 à présenter pour l'authentification :
Il doit s'agir du certificat dont on possède la clé privée. Ce certificat doit être au format PEM (DER encodé en base64).

(2) La clé privée correspondant à la clé publique renfermée dans le certificat :
Au format PEM encore une fois. Il est généralement recommandé de chiffrer cette clé (mais ce n'est pas le cas généralement).

(3) La liste des certificats des autorités reconnues :
Dans ce cas, deux possibilités pour la configuration,

- Utilisation d'un répertoire (-CApath) : L'ensemble des certificats, au format PEM, doit être placé dans le répertoire passé en paramètre. Les certificats sont recherchés suivant le "subject name hash value" (en premier lieu). Celui-ci est calculé via l'option hash d'openssl. Pour accélérer la recherche, un lien pointant vers le certificat est crée, dont le nom est "hash.0"
Exemple :
$ openssl x509 -hash -in certificat.pem -noout
22f2539e
$ ln -s certificat.pem 22f2539e.0

Si deux certificats ont le même 'subject name hash value', ils seront distingués suivant la valeur de l'extension, typiquement : 9d66eef0.0, 9d66eef0.1

Les liens peuvent être crées automatiquement avec l'utilitaire c_rehash:
$ c_rehash .
Doing .
certificat.pem => 22f2539e.0

- Utilisation d'un fichier (-CAfile) : Dans ce cas, les certificats des autorités de confiance doivent être concaténés dans un seul et même fichier, au format PEM. Seuls les champs situés entre les balises -----BEGIN CERTIFICATE----- et -----END CERTIFICATE----- sont considérés. Le reste est du commentaire.

A partir de ce fichier est construite la chaîne de certification présentée au client, ainsi que les certificats proposés pour son
authentification. Il est recommandé d'utiliser l'option CAfile :

- D'une part, le fichier est lu à l'initialisation du programme, et peut par conséquent être placé hors d'une cage, dans le cas d'un chroot() par exemple bien que ce ne pas là la seule façon d'isolé un service. L'utilisation la plus courante concerne Postfix-SSL.

- D'autre part, la liste des certificats présentés au client pour authentification est souvent constituée des certificats de ce fichier
uniquement (la documentation n'est pas extrêmement claire à ce sujet) : ces certificats sont en effet chargés par la fonction
SSL_CTX_set_client_CA_list(), dont le prototype est :
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *list);

Or, dans le patch pour Postfix :
$ grep 'SSL_CTX_set_client_CA_list' pfixtls.diff
SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile));

de même dans apps/s_server.c (archive openssl) :
$ grep SSL_CTX_set_client_CA_list s_server.c
SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));

La liste des certificats présentés au client provient uniquement de la liste pointée par l'option CAfile dans les 2 cas. Les deux options ne sont donc pas strictement équivalentes, dans ces cas là.

Le cas du serveur Apache est différent :
$ grep 'SSL_CTX_set_client_CA_list' pkg.sslmod/ssl_engine_init.c
SSL_CTX_set_client_CA_list(sc->pSSLCtx, skCAList);
où skCAList est initialisé ainsi :
(skCAList = ssl_init_FindCAList(s, p, sc->szCACertificateFile,
sc->szCACertificatePath)

Je ne montrerai pas d'exemple ici mais à la demande ...

Dans ce cas, le serveur et l'application peuvent s'appuyer sur la session SSL/TLS mutuellement authentifiée pour assurer un suivi de session authentifiée de l'utilisateur, au niveau applicatif par conséquent et non plus au niveau HTTP.

Suivi de session authentifiée

Dans le cas d'une authentification du client par certificat X.509, un certain nombre de paramètres discriminants permettent d'identifier l'utilisateur authentifié. Ces paramètres discriminants sont, à titre d'exemple, les champs DN (distinguishedName), CN (commonName) ou encore l'adresse de courrier électronique dérivés du certificat présenté lors de la négociation des
paramètres de la session SSL/TLS.
La liste des variables d'environnement initialisées par mod_ssl, dérivant du certificat client, est la suivante :

SSLPassPhraseDialog, SSLMutex, SSLRandomSeed, SSLSessionCache, SSLSessionCacheTimeout, SSLEngine, SSLProtocol, SSLCipherSuite, SSLCertificateFile, SSLCertificateKeyFile, SSLCertificateChainFile, SSLCACertificatePath, SSLCACertificateFile, SSLCARevocationPath, SSLCARevocationFile, SSLVerifyClient, SSLVerifyDepth, SSLLog, SSLLogLevel, SSLOptions, SSLRequireSSL, SSLRequire, Additional Features, Environment Variables, Custom Log Formats


Dans le cas où le client n'est pas authentifié par certificat X.509, le paramètre discriminant, dont pourrait être dérivé un identifiant de session au niveau de l'application, ne peut plus plus provenir du certificat client. Les seuls paramètres « candidats » sont ceux négociés lors du handshake SSL/TLS, et plus particulièrement le session_id sur 32 bits (variable d'environnement SSL_SESSION_ID pour mod_ssl, initialisé par le serveur).

Le standard RFC2246 (« The TLS Protocol Version 1.0 ») stipule, à propos de la durée de vie de cet identifiant :

« An upper limit of 24 hours is suggested for session ID lifetimes, since an attacker who obtains a master_secret may be able to impersonate the compromised party until the corresponding session ID is retire ».

La limite supérieure de durée de vie de cet identifiant est donc proposée à 24 heures - ce qui est a priori largement suffisant pour suivre une session authentifiée. Cependant, certaines versions d'Internet Explorer (IE 5.0/5.01(SP1)/5.5(SP1) 9x/NT4) renégocient ce paramètre toutes les 2 minutes.

Ce comportement peut être modifié dans la base de registres : HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL
La clef ClientCacheTime est positionnée à 120000 (ms) par défaut.

Le suivi de session fondé sur le session_id SSL/TLS uniquement est donc, malheureusement, inexploitable en pratique.
La solution, lorsque l'authentification par certificat client n'est pas mise en oeuvre, repose donc sur les mécanismes usuels utilisés dans HTTP - qui seront brièvement abordés par la suite, avec la notion d'identifiant de session authentifiée (cookie ou autre).

Remarque : outre le suivi de session authentifiée au niveau « applicatif », ce renouvellement fréquent du session_id SSL/TLS pose le problème de l'équilibrage de charge sur des flux HTTPS (pour s'appuyer sur d'autres paramètres que l'adresse IP notamment). À cet effet, la bibliothèque OpenSSL 0.9.7 introduit la fonction SSL_CTX_set_generate_session_id(), permettant au serveur HTTPS de générer des sessions id SSL dont le préfixe est statique et exploitable au niveau de l'équipement de répartition de charge, pour peu que celui-ci permette un tel paramétrage.

Voilà ... On peut aussi regarder du côté de l'authentification "applicative"

L'authentification entendue au sens « applicatif » consiste en la vérification par l'application elle-même des accréditations présentées par le client. Il ne s'agit plus, pour cette dernière, de s'appuyer sur une authentification réalisée au niveau HTTP ou SSL/TLS, par l'intermédiaire des variables d'environnement initialisées par le serveur par exemple : REMOTE_USER pour une
authentification HTTP, SSL_CLIENT_DN pour une authentification par certificat client etc.

Les accréditations ne sont donc plus transmises via les entêtes HTTP (méthodes d'authentification HTTP précédemment décrites), mais par un mécanisme indiqué par la « requête simple » de la requête. La méthode utilisée peut être GET (via
la QUERY_STRING, concaténée à l'URI) ou POST (dans le corps de la requête), indifféremment.

Remarque : il est clair que les langages de scripts, comme PHP par exemple, permettent également de mettre en oeuvre des mécanismes d'authentification de type HTTP « Basic », dans la mesure où ils peuvent également lire/écrire les requêtes/réponses.

Les accréditations sont généralement transmises via un tunnel chiffré/authentifié unilatéralement (SSL/TLS avec authentification du serveur par certificat), afin d'assurer la confidentialité des accréditations transmises.

Remarque : une solution alternative, et rarement employée, consiste à utiliser un mécanisme local au client, de type javascript, pour générer des accréditations à « usage unique » à partir des paramètres d'authentification, et envoyer ces accréditations au serveur (à travers un canal non chiffré). À titre d'exemple, la mise en oeuvre d'une authentification de type CHAP, par un
javascript côté client et des scripts ASP côté serveur.

Suivi de session authentifiée

Le suivi de session est à la charge de l'application. Dans les cas HTTP « Basic » et « Digest » (avec ou sans surcouche SSL/TLS), il y a authentification à chaque requête, avec une gestion d'état (ensemble de variables associées à une « session » applicative, à un ensemble de requête provenant d'un même utilisateur) côté serveur. Le même principe peut être adopté pour une application.

Mais le processus est tout autre, en pratique : l'utilisateur commence par s'authentifier au niveau d'un formulaire, les paramètres sont transmis (via la méthode GET ou la méthode POST) pour validation, puis un identifiant de session est attribué et sera utilisé pour lier les requêtes suivantes au contexte initialisé côté serveur -- d'où la notion de session applicative.

Les méthodes de passage d'identifiant de session sont multiples.

À titre d'exemple, une liste non exhaustive de techniques rencontrées :

- cookie - géré par le serveur HTTP :
- Fixé côté serveur, par l'entête Set-Cookie ou via javascript :
Set-Cookie: SESSIONID=e3e5f57ca9adbbb19a21b1c2a22be987; path=/
- Émis par le client, par l'entête Cookie :
Cookie: SESSIONID=e3e5f57ca9adbbb19a21b1c2a22be987

Le cookie est intéressant d'un point de vue « sécurité », avec l'introduction de fonctionnalités via les paramètres «secure» (permettant la transmission du cookie via un tunnel SSL/TLS uniquement, afin d'éviter son interception « passive » par écoute du trafic) ou encore « httponly » (introduit par le Service Pack 1 d'IE 6, protégeant ce navigateur contre les attaques de type XSS en interdisant la manipulation du cookie par des scripts, type javascript notamment -- tout en demeurant vulnérable à un usage détourné de la méthode HTTP TRACE qu'il convient donc de désactiver au niveau des serveurs HTTP).

- méthode GET :
GET /page.php?SESSIONID=e3e5f57ca9adbbb19a21b1c2a22be987

- méthode POST :
POST /page.php
Content-type: application/x-www-form-urlencoded
Content-length: 42

SESSIOND=e3e5f57ca9adbbb19a21b1c2a22be987

- insertion dans la REQUEST_URI (mod_rewrite + PHP4 ) :
GET /SESSIOND=e3e5f57ca9adbbb19a21b1c2a22be987/index.php

- réécriture d'URL
GET /index.php
Host: e3e5f57ca9adbbb19a21b1c2a22be987.webserver.tld

La sécurité relative à la génération d'un cookie (ou d'un identifiant de session plus généralement) d'une part, et à son suivi d'autre part sont deux sujets non triviaux qui débordent du cadre de ce post. Le point essentiel est qu'il convient d'identifier les requêtes (indépendantes les unes des autres, dans la mesure où HTTP est « sans état ») d'un même utilisateur authentifié, et les associer à un contexte unique géré côté serveur et initialisé suite à une phase d'authentification.

Certaines suites logicielles de SSO, par exemple, mettent en oeuvre des mécanismes tout à fait satisfaisants, en générant par exemple un nouvel identifiant de session à chaque requête et permettant de se prémunir contre les attaques de type XSS. La gestion correcte de cet identifiant assurera la sécurité du service d'authentification, mais cet identifiant devra par la suite être correctement corrélé avec les habilitations des utilisateurs, afin de mettre un place une véritable gestion des autorisations, et non une simple « personnalisation » des menus affichés à l'utilisateur... Le manque de cloisonnement entre les contextes utilisateurs au niveau applicatif sont aussi dangereux que les vols de session par XSS, et leur résolution ne passe pas forcément par l'ajout d'options diverses à un cookie, ou encore à un filtrage systématique du contenu des pages renvoyées au client, mais à une conception sécurisée de l'application même, qu'une solution de filtrage ou de SSO ou autre, aussi évoluée soit-elle, ne remplacera pas.

Voili voilou ...

Bon courage ...

NB : Si la réponse vous convient merci de l'accepter pour fermer ce thread ...

Sigurjón Bírgir Sigurðssón aka Sjón

HARDWARE : Partie de l'ordinateur qui reçoit les coups quand se plante le software ...
0
cs_sjon Messages postés 861 Date d'inscription mardi 26 mars 2002 Statut Membre Dernière intervention 29 novembre 2006 1
4 juin 2005 à 02:54
Sael og blesug

Veuillez pardonner les erreurs d'indentations, mais il semble et ce après plusieurs essais locaux que la FreeTextBox ( qui est magnifique ici :-) ) Ne semble pas pas fonctionner sous OpenBSD 3.7.x et amaya ...

Nix, je ne vous en tiens aucunes rigueurs quelles qu'elles soient, j'utilise un navigateur à la con ( soit car peu l'l'utilise et que cela est mon domain ) et vous avez suffisament à faire en les petites gué-guère concernant le Microsift IE et Mozilla et sa grande famille dont fait partie Firefox ... Ne l'oublions pas ...

PS Nix : Je suis d'accord avec vous : Quand vont-ils se mettre d'accord ??? Et respecter ensemble les normes et ce quelles qu'elles soient ... ( PS' : Sûrement jamais ;-) ) ... Merci en tout cas ...

Bon courage ...

NB : Si la réponse vous convient merci de l'accepter pour fermer ce thread ...

Sigurjón Bírgir Sigurðssón aka Sjón

HARDWARE : Partie de l'ordinateur qui reçoit les coups quand se plante le software ...
0
Rejoignez-nous