Python

Outils

Bandit

Bandit est un scanner de vulnérabilité pour applications python.

Utilisation:

$ bandit exemple.py

ressource: https://github.com/PyCQA/bandit

Safety

Safety est un scanner de vulnérabilité de dépendances python.

ressource: https://github.com/pyupio/safety

Identifier les entrées utilisateur

Vérifier que les entrées utilisateurs sont bien filtrées et sanitize

Flask => flask.escape()

Django => django.utils.html.escape()

autres dépendances => bleach par exemple avec bleach.clean()

Vérifier si une fonction custom a été faite pour cela.

Vérifier que les requêtes SQL utilisent des named-parameters

Exemple:

# Non sécurisé
cursor.execute(f"SELECT admin FROM users WHERE username = '(username)'");
# Sécurisé
cursor.execute("SELECT admin FROM users WHERE username = %(username)s", {'username': username});

Vérifier la présence de SSRF

Si une requête est envoyée vers une URL / un domaine / une IP fournie par l'utilisateur, vérifier que l'application valide le format de celle-ci (avec "validators" ou "urlparse" par exemple) et utilise une whiteliste de destinations de confiance.

Vérifier la présence de secrets codés en dur

Vérifier si l'application utilise un gestionnaire de secret ou des variables d'environnement pour stocker ses secrets et si ce n'est pas le cas, rechercher des secrets codés en dur.

Vérifier la présence de messages d'erreurs verbeux

Si l'application utilise un framework populaire, verifier que les messages d'erreurs verbeux sont désactivés ( Pour Django par exemple DEBUG = False dans le fichier settings.py).

Si l'application n'utilise pas de framework populaire, vérifier si une fonction permettant de gérer les exceptions existe et vérifier si ces exceptions ne font pas fuiter d'informations sensibles.

Vérifier la présence de journaux

Vérfier que l'application journalise bien les actions et événements importants et qu'elle ne journalise pas d'informations sensibles tels que des identifiants, des tokens, des clés de chiffrements / d'API ou encore des informations personnelles susceptibles de causer une infraction aux réglementations du RGPD. (la dépendance logging est usuellement utilisée pour cela)

Vérifier que l'application utilise des formats de chaînes de caractères appropriées

Python3 possède quatre chaînes de caractères différentes, voici comment les choisir en fonction de l'usage que l'on souhaite en faire.

Old Style string format avec l'opérateur "%" (#1)

Ce format n'est plus utilisé et a été remplacé par le format #2 sur Python3.

name = "John"
print('Hello, ' %s name)

Hello, John

New Style str.format (#2)

Ce format a été remplacé par le format #3 sur Python 3.6+

name = "John"
print('Hello, {}'.format(name))

Hello, John

Literal string interpolation format (#3)

Très puissant et facile d'utilisation, il offre beaucoups de possibilités.

name = "John"
print(f'Hello, {name}')

Hello, John

Template string format (#4)

Particulierement utile pour les entrées utilisateurs car ce format n'a pas accès au contenu des variables globales et est plus léger en terme de consomation de ressources que les autres formats.

from string import Template
name = "John"
t = Template('Hello, $name')
result = t.substitute(name=name)
print(result)

Hello, John
Mindmap du choix des formats de chaînes de caractères par besoin

Dependances et calls dangereux

Name

Calls

Severity

Comment

pickle

  • pickle.loads

  • pickle.load

  • pickle.Unpickler

  • dill.loads

  • dill.load

  • dill.Unpickler

  • shelve.open

  • shelve.DbfilenameShelf

  • jsonpickle.decode

  • jsonpickle.unpickler.decode

  • jsonpickle.unpickler.Unpickler

  • pandas.read_pickle

Medium

Risques d'insecure deserialization

marshal

  • marshal.load

  • marshal.loads

Medium

Risques d'insecure deserialization

PyYAML

yaml.load

Medium

Risques d'insecure deserialization

md5

  • hashlib.md5

  • hashlib.sha1

  • Crypto.Hash.MD2.new

  • Crypto.Hash.MD4.new

  • Crypto.Hash.MD5.new

  • Crypto.Hash.SHA.new

  • Cryptodome.Hash.MD2.new

  • Cryptodome.Hash.MD4.new

  • Cryptodome.Hash.MD5.new

  • Cryptodome.Hash.SHA.new

  • cryptography.hazmat.primitives .hashes.MD5

  • cryptography.hazmat.primitives .hashes.SHA1

Medium

Utilisation de hashage obsolètes

ciphers

  • Crypto.Cipher.ARC2.new

  • Crypto.Cipher.ARC4.new

  • Crypto.Cipher.Blowfish.new

  • Crypto.Cipher.DES.new

  • Crypto.Cipher.XOR.new

  • Cryptodome.Cipher.ARC2.new

  • Cryptodome.Cipher.ARC4.new

  • Cryptodome.Cipher.Blowfish.new

  • Cryptodome.Cipher.DES.new

  • Cryptodome.Cipher.XOR.new

  • cryptography.hazmat.primitives .ciphers.algorithms.ARC4

  • cryptography.hazmat.primitives .ciphers.algorithms.Blowfish

  • cryptography.hazmat.primitives .ciphers.algorithms.IDEA

High

Utilisation de chiffrements obsolètes

cipher_modes

cryptography.hazmat.primitives .ciphers.modes.ECB

Medium

Utilisation de chiffrements obsolètes

mktemp_q

tempfile.mktemp

Medium

fonction non sécurisée et dépréciée

eval

eval

Medium

Utilisation d’une fonction potentiellement non sécurisée - envisager d’utiliser ast.literal_eval plus sûr

mark_safe

django.utils.safestring.mark_safe

Medium

Peut entraîner des risques d'injection XSS

httpsconnection

  • httplib.HTTPSConnection

  • http.client.HTTPSConnection

  • six.moves.http_client .HTTPSConnection

Medium

L’utilisation de HTTPSConnection sur les anciennes versions de Python antérieures à 2.7.9 et 3.4.3 ne fournit pas de sécurité

urllib_urlopen

  • urllib.urlopen

  • urllib.request.urlopen

  • urllib.urlretrieve

  • urllib.request.urlretrieve

  • urllib.URLopener

  • urllib.request.URLopener

  • urllib.FancyURLopener

  • urllib.request.FancyURLopener

  • urllib2.urlopen

  • urllib2.Request

  • six.moves.urllib.request.urlopen

  • six.moves.urllib.request .urlretrieve

  • six.moves.urllib.request .URLopener

  • six.moves.urllib.request .FancyURLopener

Medium

Permet l'utilisation de schémas non sécurisés tel que "file:"

random

  • random.Random

  • random.random

  • random.randrange

  • random.randint

  • random.choice

  • random.choices

  • random.uniform

  • random.triangular

Medium

Les générateurs pseudo-aléatoires standard ne conviennent pas à des fins de sécurité/cryptographie. Envisagez d’utiliser le module secrets à la place

telnetlib

telnetlib.*

High

Telnet est considéré comme non sécurisé. Utilisez SSH ou un autre protocole chiffré.

xml

  • xml.etree.cElementTree.parse

  • xml.etree.cElementTree.iterparse

  • xml.etree.cElementTree.fromstring

  • xml.etree.cElementTree.XMLParser

  • xml.etree.ElementTree.parse

  • xml.etree.ElementTree.iterparse

  • xml.etree.ElementTree.fromstring

  • xml.etree.ElementTree.XMLParser

  • xml.sax.expatreader.create_parser

  • xml.dom.expatbuilder.parse

  • xml.dom.expatbuilder.parseString xml.sax.parse

  • xml.sax.parseString

  • xml.sax.make_parser

  • xml.dom.minidom.parse

  • xml.dom.minidom.parseString

  • xml.dom.pulldom.parse

  • xml.dom.pulldom.parseString

  • lxml.etree.parse

  • lxml.etree.fromstring

  • lxml.etree.RestrictedElement

  • lxml.etree.GlobalParserTLS

  • lxml.etree.getDefaultParser

  • lxml.etree.check_docinfo

Medium

L’utilisation de diverses méthodes XLM pour analyser des données XML non fiables est connue pour être vulnérable aux attaques XML. Les méthodes doivent être remplacées par leurs équivalents defusedxml.

ftplib

ftplib.*

High

FTP est considéré comme non sécurisé. Utilisez SSH/SFTP/SCP ou un autre protocole chiffré.

unverified_context

_create_unverified_context

Medium

Par défaut, Python créera un contexte ssl sécurisé et vérifié pour une utilisation dans des classes telles que HTTPSConnection. Toutefois, il permet toujours d’utiliser un contexte non sécurisé via le _create_unverified_context qui revient au comportement précédent qui ne valide pas les certificats ou n’effectue pas de vérifications de nom d’hôte.

tempnam

  • os.tempnam

  • os.tmpnam

Medium

L’utilisation de os.tempnam() et os.tmpnam() est vulnérable aux attaques de liens symboliques. Envisagez d’utiliser tmpfile() à la place.

subprocess

  • subprocess.Popen

  • subprocess.call

  • subprocess.check_call

  • subprocess.check_output

High

Risque de RCE

OS

  • os.system

  • os.popen

  • os.popen2

  • os.popen3

  • os.popen4

  • commands.getoutput

  • command.getstatusoutput

High

Risque de RCE

Dernière mise à jour