L’analyse statique du code consiste à l’analyser SANS le lancer.
Petite définition
L’analyse du code statique, appelée aussi analyse du code source ou révision du code statique, est le processus consistant à détecter les mauvaises habitudes de codage, les vulnérabilités potentielles et les défauts de sécurité dans le code source d’un logiciel, sans pour autant exécuter ce dernier. Il s’agit d’une forme de testing en boîte blanche.
Ce type d’analyse permet à vos équipes de repérer les bugs ou vulnérabilités que les autres outils et méthodes de test, par exemple les révisions de code manuelles et les compilateurs, ne relèvent généralement pas.
Quel objectif ?
Se prémunir de problèmes d’execution à venir sur un code écrit, sans avoir a l’executer à partir d’un sous set de règles, de bonnes pratiques et de contrôles sur le code.
Linting

Pour tous les languages en particulier les languages non fortement typés, il est souvent assez utile d’établir des conditions d’acceptation du code source. Pour cela, on utilise en général des outils de validation ou linter.
En python on utilisera parmi par exemple : flake8
pylint
autopep8
Dans ces conditions on retrouvera aussi bien des conditions purement stylistiques : utilisation d’espaces plutôt que de tabulations, nommage des méthodes, …
Quelques règles sont édictées dans des propostions d’amélioration et d’uniformisation de code de python PEP :
Les règles sont modulables par projet et vous êtes libre de configurer pour votre projet les règles qu’il vous semble pertinent ou non de garder.
Fun Fact : Vous utilisez déjà un linter sans le savoir dans les IDE mais non configurés
Mais également la vérification de certaines règles sur le code :
- Vérification de la présence du package pour réaliser l’import
- Vérification de la validité de l’usage des fonctions par rapport a la signature des méthodes
Exemple d’usages :
# exemple avec black
pip3 install pylint
# puis
pylint ./app
# Vous pouvez le lancer depuis partout avec la commande :
pylint $(git ls-files '*.py')
Quel intêret me diriez vous :
Pour le style : La cohérence du code, permettre de se fixer des règles entre développeurs as code
qui ensuite sont péreinnes et factuelles.
Pour la vérification : Eviter les erreurs au lancement du code, et donc anticiper les bugs 🐛
L'usage et les règles appliquées sont bien entendues paramétrables : ex : https://www.codeac.io/documentation/pylint-configuration.html
Formatting

Pour répondre aux besoins de bon respect des règles établies en amont (voir linting). Il peut être pertinent de s’équiper d’un formatter, associé généralement a l’IDE (Visual studio code / Pycharm).
Les formatters classiques pour python sont : black
yapf
Python-autopep8
isort
Voir aussi : https://github.com/life4/awesome-python-code-formatters
Exemple d’usages :
# exemple avec black
pip3 install black
# puis
black --check app
Quel intêret me diriez vous :
Etablir des changements seulement de contenu et fonctionnels dans le code permet réellement de ne garder que les changements fonctionnels et non de format lors de l’ajout de fonctionnalité. La relecture est donc facilitée. Et les règles établies lors du linting sont appliquées par défaut.
Voir aussi : https://github.com/life4/awesome-python-code-formatters
Une liste bien plus exhaustive de linters en python en fonction des besoins : https://github.com/vintasoftware/python-linters-and-code-analysis
Security testing (SAST : Static application security testing)

Les Static Application Security Testing (SAST) sont des outils et des techniques utilisés dans le domaine de la sécurité informatique pour identifier les vulnérabilités potentielles dans le code source des applications.
Ils permettent de détecter des problèmes de sécurité dans le code sans l’executer.
Les SAST peuvent repérer des vulnérabilités telles que les injections SQL, les failles XSS, les erreurs de gestion de la mémoire, etc. Leur utilisation régulière permet de renforcer la sécurité des applications dès leur conception et de réduire les risques de failles de sécurité.
Securité : quelques rappels
Pour ce cours nous utiliserons l’outil Snyk mais de nombreux outils permettent de couvrir l’analyse de la sécurité des applications.
Différent types d’attaque en sécurité informatique:
- Injection (SQL, texte, ..) ~50% : on manipule les entrants de l’application pour dépasser les fonctionnalités prévues.
- Cross Site Scripting : On injecte un script dans une application pour qu’elle l’execute ensuite pour effectuer des actions malveillantes
- Failles de sécurité - CVE : Bugs connus contenus dans des librairies et versions des systèmes qui sont ensuites exploités.
- Attaque par déni de service - DDOS: attaque pour surcharger l’usage d’un service au niveau réseau / mémoire pour empêcher tout ou partie de ses usages possibles.
- Man in the middle : récupération des informations utilisateurs pour usurper son identité et donc corrompre un système d’information
TP : Mise en place de ces outils sur une base de code

Pour ce TP on partira cette fois ci d’un projet déjà élaboré par une équipe au sein du ssplab. Prédicat.
https://github.com/InseeFrLab/predicat.git => disponible forké ici : https://github.com/conception-logicielle-ensai/predicat
Pour faciliter la vie des gens, j’ai forké ce projet dans le groupe conception logicielle ensai
sur github, si vous ne voulez pas notifier la personne que vous forkez son projet.
https://github.com/conception-logicielle-ensai/predicat.git
Exercice 1 : Mise en place
(Wait it’s git again ? :OOO)
Forkez le projet : https://github.com/conception-logicielle-ensai/predicat.git, pour les gens qui ne sont pas sur github, clonez le directement (passez donc la partie 2)
Cloner le repository dans un sous dossier de votre TP, dans votre environnement de travail préféré
Depuis le dépot récupéré, suivre les instructions pour l’installation via le README.md, veuillez toutefois a bien faire cela dans le repertoire app du dépot git, par défaut : predicat/app
Lancez l’application via la commande
uvicorn main:app
, pensez bien a installer les dépendances au préalable, et vous pouvez utiliser un environnement virtuel.
AIDE 1 (clickable): Comment savoir les dépendances nécessaires à l'exécution de l'application ?
Rappel :
Pour un projet python, les dépendances sont en général gérées par pip (https://packaging.python.org/tutorials/installing-packages/) et sont listées dans le fichier requirements.txt
pip install -r requirements.txt
AIDE 2 (clickable) : Comment débugguer si l'application qui ne se lance pas / crash ?
Vous avez probablement mal lu le README.md.
Pour résoudre le problème, vous aurez besoin d’un modèle. On pourra utiliser le modèle de test disponible ici : https://minio.lab.sspcloud.fr/conception-logicielle/model_na2008.bin
Vous devez ensuite enlever du fichier de configuration yaml, les lignes concernant les modèles qui ne sont pas le modèle 2020_old.
Une fois l’application lancée, vous pouvez la requêter avec votre c lient HTTP préféré et adapté à votre environnement de travail (curl, navigateur web, insomnia …) : http://localhost:8000/label?q=confiture ou encore http://localhost:8000/label?q=omelette%20du%20fromage
Si ça ne resoud pas, cherchez par rapport a l’erreur renvoyée par la console.
Exercice 2 : Analyse statique du code - Linting / Formatting
Pour cette partie on va analyser le code de l’application prédicat.
Installons les paquets black, isort et pylint.
=> pip3 install black isort pylint
- Lancez pylint sur le projet (il applique par défaut la config de la PEP8)
pylint app
(app étant le dossier de l’appli, si vous y êtes déjà pylint *.py
)
Que constatez vous ? Est ce qu’il y a des erreurs? De quel type ?
=> Petit tour d’horizon des erreurs possibles : <a href=“https://pylint.readthedocs.io/en/stable/user_guide/messages/messages_overview.html"
- Appliquez le formattage avec black et isort
black app
et isort --profile black app
Réappliquez votre linter sur l’application. Constatez vous un changement dans la notation du code ?
Pour valider un dépôt de code on peut par exemple se dire qu’on n’autorise pas une note inférieure a 7 pour le projet et s’y tenir.
pylint --fail-under=7
- Vous pouvez également configurer un fichier
.pylintrc
(formaté en TOML):
Ce fichier est appliqué pour configurer les règles de pylint sur le projet (donc depuis le repertoire où on l’execute).
Exemple :
[MESSAGES CONTROL]
# Activer ou désactiver certains types de messages
disable =
missing-module-docstring, # Pas de docstring pour les modules
missing-function-docstring, # Pas de docstring pour les fonctions
[DESIGN]
# Configuration pour les lignes longues
max-line-length = 120 # Limiter à 120 caractères par ligne
[FORMAT]
# Configuration de formatage
good-names = i,j,k,e,x,run,_) # Noms "bons" pour les variables
[REPORTS]
# Format de sortie pour les résultats de Pylint
output-format = text # Format de sortie en texte
Vous pouvez en ajouter un et constater que cela réduit drastiquement le nombre d’erreurs.
Exercice 3 : Analyse de la sécurité du code et de ses dépendances
- Créez un compte sur Snyk
- Paramétrez l’accès a votre projet sur l’application par l’onglet :
Projects => Github =>
{user}/predicat
- Profit !
Si vous avez du temps vous pouvez regarder un peu les résultats sur le projet.
Exercice 4 : Votre projet
En attendant la fin de la séquence, mettez en place les outils sur votre projet. (ou réfléchissez sur votre projet)