> Tech > Filtrage des saisies utilisateur

Filtrage des saisies utilisateur

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

Commençons par ajouter une couche de sécurité qui empêche un utilisateur indésirable de se servir des applications connectées à  votre base de données en vue d'insérer des commandes SQL malveillantes. Dans mon exemple d'attaque par injection de code SQL, la saisie de l'intrus comportait plus de caractères (dont certains caractères

Filtrage des saisies utilisateur

spéciaux)
qu’un nom d’utilisateur ou un mot de passe
classiques. Le filtrage de ce type de saisie à  la
source constitue probablement la méthode la plus facile
pour se prémunir contre les attaques par injection de code
SQL.

Dans Visual Studio .NET, chaque champ de texte vous
permet de spécifier une longueur maximum. Pour définir ce
paramètre, il suffit de sélectionner l’une des zones de texte
sur le formulaire et de localiser la fenêtre Properties, située
généralement dans l’angle inférieur droit de l’écran. Dans la
liste des propriétés, recherchez l’attribut maxlength, puis entrez
une valeur supérieure à  0 afin de limiter le nombre de caractères
qu’un utilisateur peut saisir. Cette limite constitue
une étape simple, mais ô combien importante, lors du filtrage
des saisies utilisateur.


Tous les formulaires ne contiennent pas de valeurs dont
vous pouvez limiter la longueur, mais vous pouvez aussi
contrôler la saisie en interdisant ou en limitant les caractères
spéciaux. ASP.NET propose un contrôle permettant de filtrer
les saisies des utilisateurs. A partir de la boîte à  outils Visual
Studio, vous pouvez ajouter un contrôle de validation pour
chacun des champs de saisie. .NET propose en effet différents
contrôles de validation dans la boîte à  outils Visual
Studio .NET. Lorsque vous en utilisez un, vous pouvez spécifier,
par exemple, qu’un champ donné doit être du type numérique.
Des contrôles de validation sont disponibles pour
identifier les champs requis, comparer des champs et définir
des plages numériques. Il est même possible de créer des
contrôles de validation personnalisés. De surcroît, Visual
Studio .NET fournit un contrôle ValidationSummary utilisable
en tant qu’affichage d’erreur pour plusieurs contrôles
de validation. Ces contrôles sont des composants très précieux.
En effet, bien qu’ils s’exécutent sur le client, le filtrage
final des saisies utilisateur se déroule sur le serveur. Le fait
que ce dernier exécute ou réexécute chaque contrôle de validation
apporte la garantie qu’un utilisateur débrouillard ne
pourra pas contourner le filtrage en manipulant les données
et en injectant du code dans une chaîne après avoir quitté le
navigateur.


Le contrôle de validation RegularExpression permet de
spécifier que les caractères d’une chaîne de saisie peuvent
s’insérer dans la définition d’une expression régulière. Voici
un exemple d’expression régulière :

^[0-9a-zA-Z_]$

Cette expression précise qu’une chaîne de saisie ne peut
contenir que des caractères alphanumériques et le caractère
de soulignement. Dans les exemples de cet article, ces limitations
permettraient de filtrer les caractères spéciaux de la
chaîne d’injection que j’ai utilisée. Avec cette définition, le
serveur d’applications rejetterait la chaîne employée pour
l’attaque. Vous pouvez créer des expressions régulières similaires
en exploitant les informations sur les éléments de
langage des expressions régulières fournies par Microsoft à  l’adresse http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/cpgenref/html/cpconcharacterclasses.asp
ou les informations de référence de syntaxe sur le site de Jan
Goyvaert, Regular-Expressions.info, à  l’adresse http://www.
regular-expressions.info/reference.html.


Vous n’avez pas besoin de limiter votre filtrage à  l’interface
utilisateur de l’application. Il est également
possible d’inclure des expressions régulières
dans le code. Par exemple, le code
Visual Basic .NET suivant crée une expression
régulière qui vérifie la présence de caractères
valides et une longueur maximum
de 10 caractères.


Dim reg As Regex = New
Regex(« ^[A-zA-Z0-9_]{10}$ »)
reg.IsMatch(TextBox1.Text)

L’expression générée par ce code peut
servir à  valider les noms d’utilisateur. Ayez à  l’esprit que pour
ajouter ce code à  l’exemple de l’article, vous devez inclure la
référence complète de System.Text.RegularExpressions, à 
moins que vous ajoutiez l’instruction Imports System.
Text.RegularExpressions en haut du fichier source. .NET assure
la gestion intégrée des expressions régulières au niveau
du contrôle, mais plus important encore, aussi au sein de
votre code. Même si vous n’êtes pas en mesure d’éliminer les
caractères spéciaux de tous les champs, vous pouvez filtrer
les caractères particulièrement suspects, tels que les deux tirets.

Dans certains cas, vous devez veiller à  ce que votre application
gère correctement les caractères spéciaux, si l’utilisateur
en saisit. Comme l’exemple d’attaque le montre, le
guillemet simple revêt un intérêt particulier car il permet à 
un intrus de fermer un guillemet ouvrant, fournissant ainsi
un emplacement pour introduire une nouvelle chaîne dans
le code de votre système. Dans ce cas, la solution consiste à 
vérifier que si un utilisateur tape un guillemet simple dans
une chaîne, le nouveau guillemet sera ignoré. Autrement dit,
au lieu de traiter le caractère comme un guillemet simple
classique, le code le considérera comme n’importe quel
autre caractère de la chaîne. Pour ignorer un guillemet
simple, il suffit de le faire correspondre à  un deuxième guillemet
simple. Une méthode facile permettant d’y parvenir
consiste à  employer la méthode Replace() sur une chaîne


TextBox1.Text.Replace( » ‘ « , » ‘
‘ « )


Cette commande doit contenir un guillemet simple uniquement
dans la première paire de guillemets doubles et
une paire de guillemets simples dans la deuxième paire de
guillemets doubles. Cette commande remplace chaque instance
d’un guillemet simple par deux instances, afin qu’il
soient ignorés par rapport à  la séquence d’exécution SQL.
Vous pouvez procéder de même pour d’autres caractères
spéciaux.


Le défi associé réside dans le fait que vous devez placer
cette commande de filtrage de caractères dans votre code.
Une option consiste à  ajouter une transformation telle que la
commande précédente aux emplacements de votre application
qui acceptent une saisie utilisateur, ce qui peut imposer
d’insérer la commande à  des centaines d’emplacements.
Une autre approche consiste à  exécuter ce filtrage juste avant
que le code appelle SQL Server. Naturellement, si votre accès
aux données n’est pas centralisé, il sera peut-être encore nécessaire
d’effectuer un filtrage à  des centaines d’emplacements
dans le code d’une application volumineuse.

La mise en oeuvre du filtrage des caractères devient aisée
lorsque toutes vos commandes d’accès aux données transitent
par un ensemble de composants, les composants DALC
(Data Access Layer Components). Le Microsoft Data Access
Application Block constitue un excellent modèle pour votre
logique d’accès aux données, mais prévoyez de le personnaliser
en fonction de votre situation.


Même si vous employez plusieurs ensembles de composants
d’accès aux données, vous pouvez mettre en oeuvre
une conception qui canalise tous vos appels de base de données
à  travers un ensemble de classes d’accès aux données.
Outre le fait d’imposer à  votre logique d’accès aux bases de
données de passer via un processus de filtrage personnalisé,
vous pouvez employer DALC pour mettre en oeuvre d’autres
pratiques éprouvées. Par exemple, DALC peut vous servir à 
limiter les possibilités des développeurs à  l’écriture de code
qui accède uniquement aux procédures stockées, non au
SQL dynamique. L’une des principales exigences des attaques
par injection de code SQL est l’utilisation du SQL dynamique.
Les procédures stockées ne sont pas sujettes aux
mêmes risques que les requêtes en SQL dynamique car, à  la
différence de ces dernières qui sont interprétées à  la volée par SQL Server, une procédure stockée est partiellement interprétée
à  l’avance. Lorsque vous soumettez une requête
SQL dynamique, vous soumettez une chaîne que SQL Server
interprète intégralement. En revanche, une procédure stockée
fonctionne avec des variables nommées. Chacune d’elles
réserve un emplacement pour une valeur au sein du code de
la procédure stockée. Par conséquent, SQL Server peut isoler
les variables du code et éviter d’exécuter par inadvertance
des valeurs incorporées. Ainsi, si un utilisateur essaie de soumettre
une chaîne de commande incorporée comme l’un
des paramètres d’une procédure stockée, cette dernière
n’exécutera pas les commandes.

Le fait que les procédures stockées gèrent l’ensemble
des accès aux données constitue l’une des meilleures méthodes
pour protéger lesdites données des attaques par injection
de code SQL. Malheureusement, cette approche
n’est pas à  toute épreuve. Si votre code utilise la commande
EXEC avec la procédure stockée sp_ExecuteSQL, vous rouvrez
en fait la faille de sécurité car vous autorisez le passage
de chaînes interprétées ensuite par SQL Server.

Une dernière méthode destinée à  se prémunir contre les
risques d’attaques consiste à  s’assurer que votre base de données
ne renvoie pas aux intrus potentiels des messages d’erreur
pouvant les aider à  contourner votre logique par défaut.
Un message d’erreur du type Username is correct but password
is incorrect (Le nom d’utilisateur est correct, mais le
mot de passe est erroné) fournit de précieuses informations
à  un intrus. Un simple message Invalid Logon (Connexion
non valide) signale aux utilisateurs que les informations
d’identification ne sont pas valides, sans pour autant indiquer
à  un intrus si le nom d’utilisateur est correct.

A un niveau plus complexe, la gestion correcte des messages
d’erreur implique d’empêcher votre système de renvoyer
le texte réel de messages d’erreur SQL
Server. Par défaut, ASP.NET ne retourne pas de
tels messages vers des connexions distantes.
Votre application doit informer avec courtoisie
les utilisateurs qu’une erreur s’est produite,
mais ceux-ci ne doivent en aucun cas voir le
message original associé à  une requête non valide,
susceptible de contenir la requête soumise.
Les développeurs travaillant sur des projets
Web ajoutent parfois du code qui renvoie
une requête soumise dans le message d’erreur,
afin de pouvoir déboguer le dysfonctionnement de la
requête en question. Toutefois, le message d’erreur peut aider
un pirate à  identifier la manière d’attaquer votre système.

Les solutions présentées jusqu’ici mettent l’accent sur la
conception, la configuration et la mise en oeuvre de votre application
afin qu’elle n’expose pas votre base de données à 
une attaque. Examinons maintenant les solutions à  mettre en
oeuvre au niveau de la configuration de votre base de données.

Téléchargez cette ressource

Comment sécuriser une PME avec l’approche par les risques ?

Comment sécuriser une PME avec l’approche par les risques ?

Disposant de moyens financiers et humains contraints, les PME éprouvent des difficultés à mettre en place une véritable stratégie de cybersécurité. Opérateur de services et d’infrastructures, Naitways leur propose une approche pragmatique de sécurité « by design » en priorisant les risques auxquelles elles sont confrontées.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010