Comment ne pas gérer la sécurité des informations sur un formulaire de création de compte

Il y a quelques semaines, j’ai fait part d’une désagréable expérience d’achat où mon mot de passe m’a été envoyé par courriel suite à la création de mon compte. Comme je l’ai écrit, il s’agit d’une pratique irresponsable et qui met en danger la sécurité en ligne des usagers de ce site web. À proscrire!

Dernièrement, j’ai fait un achat de billets de spectacle pour une salle de spectacle à Laval. Vous me voyez venir? Par contre, cette fois-ci, j’étais plus fâché qu’horrifié par la situation.

Une image vaut mille mots (ou maux, comme vous voulez)

motdepasse

C’est bien ça. Quand j’ai vu le message d’erreur passer, je suis resté bouche bée. Le mot de passe que j’ai tenté d’utiliser contenait des caractères spéciaux. Vraiment?!

Êtes-vous surpris de vous que je vous dise que la majorité de mes mots de passe ne rentre pas dans l’une ou l’autre de ses catégories? Voyons donc! Un mot de passe valide doit être composé uniquement de chiffres et de lettres. J’aurais bien aimé être un oiseau et assister à la rencontre technique où cette règle s’est décidée.

Par curiosité, même si je m’en doutais un peu, j’ai été voir par quel moyen le champ du mot de passe était validé. Vu que c’était du .NET et qu’un validateur Regex côté client est utilisé, j’ai pu constater l’horreur de mes yeux vus.

Oui, oui. Vous avez bien lu. Le mot de passe est validé à l’aide d’une Regex qui prend la forme suivante: ^[a-zA-Z0-9]\\w{5,11}$.

Ironiquement, dans ma prospection de liens de la semaine, j’étais tombé sur l’article Stop forcing your arbitrary password rules on me. Drôlement à propos avec le billet de cette semaine.

La Regex utilisée est tellement mauvaise qu’elle impose l’utilisation de mots de passe pouvant être craqués en quelques secondes, au pire. C’est surtout ça le nœud du problème, en fait.

En bout de compte

J’ai cité ce formulaire en exemple pour démontrer que la sécurité des données sur le web est souvent tournée à la légère alors que ce devrait être quelque chose de pris très sérieusement. Certes, ce cas-ci est significativement moins mauvais que l’exemple cité en introduction.

Le point que je soulève n’est pas une inquiétude dramatique. Toutefois, il s’avère que, en tant que consommateur et développeur web, je suis déçu lorsqu’un site web comme celui-ci propose une solution proposant une gestion aussi faible de ma sécurité de mes informations.

La cerise sur le Sundae était la chose suivante. Le formulaire était incrusté dans une page web à l’aide d’un IFrame. Ni la page hôte et ni la page hébergée sur le site du fournisseur était sécurisée à l’aide d’un certificat SSL (HTTPS). Ça donne une idée du problème, non?

Publicité

Les liens de la semaine – Édition #155

Développement

JavaScript

.NET

Technologie

Web

Science et autres

Réviser du code? Comment est-ce que je m’assure que ce que je révise a du sens?

La revue de code doit être un aspect obligatoire de l’évolution d’une base logicielle en évolution. La lecture du code doit être au centre du processus d’assurance qualité entre les membres d’une équipe de développement.

Avec le temps, j’ai appris à apprécier la révision de code écrit par d’autres développeurs. Il s’agit d’une d’une excellente opportunité pour apprendre de nouvelles techniques de programmation et surtout comprendre le schéma de pensée de vos camarades.

Pour réviser du code, il faut avoir une idée de ce qu’il faut passer en revue. Souvent, j’aime bien prendre un changeset et en faire une première lecture rapide. Lors de cette première étape, je prends des notes. Des fois, il y a des éléments que je souhaite revoir plus en détail. Cette revue rapide me permet d’identifier des aspects visuels qui vont attirer mon attention pour une deuxième étape.

Lors d’une lecture subséquente, c’est là que je vais regarder un peu plus en détail les aspects syntaxiques et algorithmiques de la solution proposée. Certaines questions à poser à cette étape:

  • La solution a-t-elle du sens?
  • Y a-t-il des éléments de code pouvant être simplifiés? (ex.: conditions if, structures décisionnelles imbriquées dans les boucles, etc.)

La première question est vraiment une question de feeling. Je crois, cependant, qu’elle est très importante. Si elle ne fait pas de sens maintenant, elle n’en fera pas plus dans six mois ou, même, un an.

Lorsqu’il est temps d’avoir du sens à propos de solutions programmées, il y a quelques exemples qui me viennent en tête.

Nommer les conditions

Qu’une condition dans un if ou même dans une méthode LINQ, lorsqu’elle devient un peu trop compliquée, il est bien de considérer les actions suivantes:

  1. Fractionner la condition en une série de plus petite
  2. Extraire la condition en question dans une méthode afin de lui donner un nom plus concret.

Le principal contre-argument de cette façon de faire est que cela rend le code plus long. Vrai. Cependant, si la condition est bien nommée et fait bien son travail, je n’aurai pas besoin d’aller lire et relire à plusieurs reprises ce qu’elle est supposée valider. Son nom devrait suffire.

Une méthode vaut dix commentaires.

Préférer les méthodes LINQ chaînées

Il y a deux façons de faire des opérations LINQ avec C#. La blague serait de dire la bonne ou la mauvaise. Je vais m’abstenir, cette fois-ci

La syntaxe « requête »


var names = from item in collection
where item.Name == "Fred"
order by item.Age
select item.Name;

view raw

linq-query.cs

hosted with ❤ by GitHub

La syntaxe « méthode »


var names = collection
.Where(item => item.Name == "Fred")
.OrderBy(item => item.Age)
.Select(item => item.Name)

view raw

linqmethod.cs

hosted with ❤ by GitHub

 

Généralement, j’essaie de m’éloigner de la syntaxe requête. Je trouve qu’au niveau du style, elle s’éloigne de la syntaxe générale du C#. Qu’elle ressemble trop au SQL, en fait, et ça contribue à diminuer l’homogénéité d’une classe lorsqu’elle est présente.

Éviter les multiples classes dans un seul fichier C#

Cette règle est simple. Il n’y a pas de raison valide pour faire en sorte d’imbriquer plusieurs classes dans le même fichier .cs. Lorsque je regarde la structure d’une solution Visual Studio, je veux être en mesure de voir la structure et l’organisation des différents fichiers d’un seul coup.

Alors, la règle est simple. Pas de mauvaises surprises. Un fichier .cs est égal à une classe concrète. La même chose s’applique aux classes utilitaires ou même les interfaces. Chacun dans son coin!

 

Billets de code

Ce n’est pas la première fois que j’écris un billet au sujet du développement logiciel. Si vous avez apprécié ce billet, vous apprécierez probablement ceux-ci aussi. Bonne lecture!

Les liens de la semaine – Édition #154

Développement

.NET

Web

Technologie

Science et autres

Une revue de code autour de l’utilisation d’une boucle for

Pour un développeur, la lecture de code fait partie d’un régime sain et équilibré afin de pouvoir apprendre de nouvelles façons de faire et d’améliorer sa technique au clavier. Ce n’est pas compliqué: c’est en regardant qu’on apprend!

Or, lors de l’écriture de L’histoire d’un rubberducking et ASP.NET MVC, je me suis adonné sur le repository d’ASP.NET 5 sur GitHub. J’étais à la recherche de la façon qu’ASP.NET s’y prenait pour faire le mappage entre les données arrivant d’une requête HTTP et un type utilisé comme modèle.

Dans mes recherches, il y a un petit bout de code qui a attiré mon attention. Surtout parce qu’il était composé d’une façon que je n’avais jamais vue auparavant.


foreach (ModelError error in modelState.Errors.Where(err => String.IsNullOrEmpty(err.ErrorMessage) && err.Exception != null).ToList())
{
for (Exception exception = error.Exception; exception != null; exception = exception.InnerException)
{
// We only consider "known" type of exception and do not make too aggressive changes here
if (exception is FormatException || exception is OverflowException)
{
string displayName = propertyMetadata.GetDisplayName();
string errorMessageTemplate = GetValueInvalidResource(controllerContext);
string errorMessage = String.Format(CultureInfo.CurrentCulture, errorMessageTemplate, modelState.Value.AttemptedValue, displayName);
modelState.Errors.Remove(error);
modelState.Errors.Add(errorMessage);
break;
}
}
}

view raw

binding.cs

hosted with ❤ by GitHub

Seriez-vous en mesure de deviner de quoi il est question, au juste? Non? Vous donnez votre langue aux chats? D’accord. Jetez un coup d’oeil à la ligne 4 de l’exemple de code.

for (Exception exception = error.Exception; exception != null; exception = exception.InnerException)

Ce n’est pas une boucle for sous sa forme classique, n’est-ce pas?

À la première lecture, j’étais un peu confus sur ce que devait accomplir cette boucle. Après quelques lectures et une exécution dans une petite classe maison, j’ai compris. En fait, c’est un bout de code assez élégant pour deux raisons.

  1. Il s’agit d’une façon de faire de la récursion tout un bloc d’exécution « classique ».
  2. D’un point de vue de la clarté, si vous savez que vous allez vouloir court-circuiter l’exécution d’une boucle avec un break, je crois qu’il est effectivement préférable d’utiliser une boucle sous cette forme.

Dans le passé, par paresse, lorsque j’avais besoin d’itérer une collection, je passais par foreach. De plus, j’aurais eu recours à de la récursion pour traverser la pile d’erreurs imbriquées.

Après coup, je crois qu’il y a effectivement une différence fondamentale entre le for et le foreach. Les deux permettent, en effet, d’itérer une collection d’éléments. Par contre, au niveau de la syntaxe, un for a une portée bien délimitée. Il faut lui indiquer à quel moment s’arrêter et comment procéder pour l’itération. Tandis que, pour le foreach, il traverse une collection du début à la fin.

Alors, à la lumière de ceci, pourquoi devrais-je utiliser une boucle foreach alors que je vais devoir l’interrompre dans le parcours de la collection selon une condition donnée? À présent, sachant que cette technique existe, je serai possiblement plus attentif à tenter de l’utiliser dans mon quotidien.

Au niveau de la revue de code, je crois que cela peut aider à rendre le code plus clair et l’intention mieux définie.