Sécuriser votre code Python est essentiel pour vous assurer qu’il fonctionne de manière optimale et sans faille. Il existe de nombreuses approches que vous pouvez adopter pour protéger votre code, telles que l’application d’analyses logicielles qui suivent l’état de sécurité de votre projet logiciel.
Il existe plusieurs moyens de sécuriser son code Python, voici quelques exemples :
- Validation des entrées : Il est important de vérifier que les entrées à votre programme sont valides et attendues. Par exemple, si votre programme accepte une adresse IP en entrée, assurez-vous qu’elle est bien au format IP valide avant de l’utiliser.
- Échappement des caractères sensibles : Si vous utilisez des entrées dans des commandes système ou SQL, assurez-vous de les échapper correctement pour éviter les attaques par injection.
- Utilisation de bibliothèques de confiance : Utilisez des bibliothèques de confiance qui ont été largement testées et approuvées par la communauté. Évitez d’utiliser des bibliothèques non fiables ou non mises à jour.
- Cryptage des données sensibles : Si vous traitez des informations sensibles telles que des mots de passe ou des numéros de carte de crédit, assurez-vous de les crypter avant de les stocker ou de les transmettre.
- Utilisez des outils de protection de la mémoire : Utilisez des outils pour protéger contre les fuites de mémoire et les accès non autorisés à la mémoire.
- Utilisez des outils de détection de vulnérabilités : Utilisez des outils pour détecter les vulnérabilités dans votre code, comme par exemple bandit pour Python, qui peut aider à identifier les problèmes de sécurité potentiels dans votre code.
- Utiliser la gestion des exceptions: Utiliser des try/except pour capturer les exceptions et gérer les erreurs, permet d’éviter d’avoir des problème de sécurité lié à une utilisation non prévue de votre programme.
Il est important de noter que la sécurisation de code est un domaine en constante évolution et il est important de rester informé des dernières vulnérabilités et des meilleures pratiques pour sécuriser votre code.
Sécuriser son code Python en validant les entrées
Utilisation des expressions régulières
Vous pouvez utiliser la bibliothèque re
pour vérifier si une entrée correspond à un format spécifié en utilisant des expressions régulières. Par exemple, pour vérifier si une entrée est une adresse email valide :
import re def is_valid_email(email): pattern = re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$") return pattern.match(email) email = "user@example.com" if is_valid_email(email): print("Email est valide.") else: print("Email n'est pas valide.")
Utiliser une fonction de validation
def is_valid_integer(n): try: int(n) return True except ValueError: return False num = "123" if is_valid_integer(num): print("c'est un nombre entier.") else: print("ce n'est pas un nombre entier.")
Utiliser les bibliothèques pour la validation de vos données Python
from cerberus import Validator v = Validator() document = {"name": "John", "age": 30, "email": "john@example.com"} schema = {"name": {"type": "string"}, "age": {"type": "integer"}, "email": {"type": "string", "regex": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"}} if v.validate(document, schema): print("document est valide.") else: print("document n'est pas valide.")
Échapper les caractères sensibles dans votre code
Lorsque vous utilisez des entrées dans une requête SQL, il est important de les échapper pour éviter une injection. Pour cela, vous pouvez utiliser les méthodes quote()
ou escape()
fournies par les bibliothèques de base de données pour échapper les entrées.
import mysql.connector def execute_query(query): cnx = mysql.connector.connect(user='root', password='password', host='127.0.0.1', database='mydb') cursor = cnx.cursor() cursor.execute(query) cnx.commit() cursor.close() cnx.close() name = "John'; DROP TABLE users; --" query = "SELECT * FROM users WHERE name = '{}'".format(mysql.connector.escape(name)) execute_query(query)
Utiliser la bibliothèque shlex pour échapper vos entrées
import shlex import subprocess def execute_command(cmd): cmd = " ".join(shlex.quote(x) for x in cmd.split()) subprocess.run(cmd, shell=True, check=True) cmd = "rm -rf /; echo 'done'" execute_command(cmd)
Protéger votre code Python en cryptant vos données sensibles
La bibliothèque cryptography
La bibliothèque cryptography est souvent utilisée pour crypter ou décrypter des données en Python. Elle prend en charge une multitude d’algorithmes de chiffrement tel que AES, RSA etc … Cette bibliothèque crypte vos données de manière symetrique (clé identique pour le chiffrement / déchiffrement) ou asymétrique (une clé publique et une clé privée)
from cryptography.fernet import Fernet # generate a key key = Fernet.generate_key() print(f'key: {key}') cipher_suite = Fernet(key) cipher_text = cipher_suite.encrypt(b"This is a top secret message.") print(f'cipher_text: {cipher_text}') plain_text = cipher_suite.decrypt(cipher_text) print(f'plain_text: {plain_text}')
La bibliothèque pycrypto
pycrypte permet d’utiliser les fonctionnalités de chiffrement comme par exemple : AES, DES, RSA. Son utilisation permet le cryptage de données symétrique.
from Crypto.Cipher import AES import os key = os.urandom(AES.block_size) cipher = AES.new(key) plaintext = b'This is a top secret message.' ciphertext = cipher.encrypt(plaintext) print(f'ciphertext: {ciphertext}') # decryption cipher = AES.new(key) decryptedtext = cipher.decrypt(ciphertext) print(f'decryptedtext: {decryptedtext}')
La bibliothèque pyOpenSSL
Elle permet l’utilisation de fonctionnalités de chiffrement RSA,DSA,DH , cette dernière est utilisée pour le cryptage asymétrique
from OpenSSL import crypto private_key = crypto.PKey() private_key.generate_key(crypto.TYPE_RSA, 2048) public_key = private_key.publickey() # encrypt ciphertext = crypto.m2crypto.m2.rsa_public_encrypt(b'This is a top secret message.', public_key) print(f'ciphertext: {ciphertext}') # decrypt plaintext = crypto.m2crypto.m2.rsa_private_decrypt(ciphertext, private_key) print(f'plaintext: {plaintext}')
Protéger votre code Python des fuites de mémoire
La bibliothèque ctypes
permet de gérer les pointeurs et les types de données en C, ce qui vous permet de contrôler la mémoire de manière fine. Vous pouvez utiliser les fonctions de mémoire memset()
et memset_s()
pour remplir la mémoire avec des valeurs nulles, ce qui peut aider à protéger les données sensibles.
from ctypes import CDLL, POINTER, c_char, c_size_t libc = CDLL('libc.so.6') def memset_s(s, smax, c, n): libc.memset_s(s, smax, c, n) data = "my secret data" data_ptr = c_char.from_buffer(data) memset_s(data_ptr, len(data), 0, len(data)) print(f'data: {data}')
La bibliothèque numpy
numpy permet la création et la manipulation de tableaux de données. Il est possible d’utiliser numpy.memmap pour créer des tableaux mappés en mémoire
import numpy as np data = np.memmap('my_file', dtype='float32', mode='w+', shape=(100,100)) data[:] = np.random.randn(*data.shape) # clear data del data
Utiliser la librairie bandit pour sécuriser son code Python
Bandit est un outil de sécurité pour Python qui peut aider à identifier les problèmes de sécurité potentiels dans votre code. Il peut détecter les vulnérabilités telles que les injections SQL, les problèmes de gestion des erreurs, les fuites de mémoire et les problèmes de cryptographie. Il est open-source et maintenu par l’équipe de sécurité de OpenStack.
Installez Bandit en utilisant pip
python -m pip install bandit
Utilisez la commande bandit pour lancer une analyse sur un fichier ou un répertoire:
python -m bandit -r my_code_directory
Les résultats de l’analyse seront affichés dans le terminal, y compris le nom de la vulnérabilité détectée, sa gravité, et la ligne de code où elle a été détectée.
utiliser les options de Bandit Python
python -m bandit -r my_code_directory -ll -ii
-ll : permet de limiter les résultats à certains niveaux de gravité
-ii : permet de limiter les résultats à certains contextes d’analyse
Il est également possible d’intégrer Bandit dans des outils de construction ou de continuer l’intégration pour automatiser les tests de sécurité lors de chaque build.
Il est important de noter que Bandit ne garantit pas une sécurisation complète de votre code, mais il peut vous aider à identifier les problèmes potentiels de sécurité. Il est donc important de comprendre les résultats de l’analyse et de les corriger si nécessaire.