Skip to main content

Generar datos de seguridad ficticios con Python y faker-security

Escrito por

Michael Aquilina

feature python code purple

26 de abril de 2022

0 minutos de lectura

Snyk publicó recientemente como código abierto nuestro paquete de Python faker-security para ayudar a quienes trabajan con datos de seguridad. En esta publicación, repasaremos brevemente qué es este paquete de Python y cómo usarlo. Pero primero, veremos algo de contexto sobre cómo se puede usar el paquete de Python factory_boy en combinación con faker-security para mejorar tu experiencia al escribir pruebas durante el desarrollo.

Nota: Tener algunos conocimientos de Python te ayudará a aprovechar al máximo esta publicación.

Pruebas con Faker y factory_boy

Antes de profundizar en faker-security, conviene empezar por conocer factory_boy y Faker, y cómo los usamos en Snyk.

En Snyk creemos firmemente que las pruebas automatizadas permiten mantener nuestro código. Las pruebas nos permiten iterar y desarrollar funcionalidades rápidamente, y hacer cambios en nuestro código con confianza, sin temor a que podamos afectar por accidente las funcionalidades existentes.

Nuestro compromiso con las pruebas nos impulsa a buscar nuevas formas de simplificar la experiencia de quienes escriben y leen pruebas en nuestros equipos. Faker y factory_boy son dos de nuestros paquetes favoritos para probar proyectos de Python. Juntos, generan instancias ficticias de los modelos que usamos en las pruebas.

Faker es un paquete de Python que te permite generar datos ficticios para muchos tipos de campos, como nombres de usuario, fechas y URL. factory_boy es otro paquete de Python que ayuda a integrar la generación de datos de Faker en tu código mediante la definición de clases de fábrica.

Lo que más nos gusta de factory_boy es que permite a quien escribe una prueba enfocarse en fijar los datos que le interesan, mientras deja que Faker genere el resto de los datos que no son relevantes para la prueba. Esto mejora mucho la legibilidad de las pruebas, ya que reduce las líneas de código necesarias y elimina el ruido de los campos que no necesitas considerar.

Para ver la diferencia en la práctica, compara en los siguientes ejemplos una prueba escrita con factory_boy con otra que no lo usa.

Sin fábricas:

from django.contrib.auth.models import User

def test_correct_email_address():
    user = User(
        first_name="Sherlock",
        last_name="Holmes", 
        username="sherlock.holmes",
        email="sherlock.holmes@baker.street",
        is_admin=False,
    )

    assert has_valid_email(user) is True

Con fábricas:

from tests.factories import UserFactory

def test_correct_email_address():
    user = UserFactory(email="sherlock.holmes@baker.street")
    assert has_valid_email(user) is True

La prueba que importa UserFactory es exactamente equivalente a la que no lo hace. Sin embargo, es más corta, más fácil de leer y muestra claramente los campos importantes para la prueba. En cambio, la prueba sin fábricas es más larga y dificulta entender qué campos son realmente importantes para la prueba. Este es un ejemplo bastante sencillo, pero la diferencia se hace aún más evidente a medida que aumenta la complejidad de las pruebas.

La clase UserFactory se puede definir una sola vez en tests/factories.py y volver a usar en todas tus pruebas:

import factory
from django.contrib.auth.models import User
from factory.django import DjangoModelFactory

class UserFactory(DjangoModelFactory):
    class Meta:
        model = User

    username = factory.Faker("slug")
    first_name = factory.Faker("first_name")
    last_name = factory.Faker("last_name")
    email = factory.Faker("email")
    is_admin = False

Al trabajar con datos de seguridad, a menudo necesitamos generar datos para campos de seguridad como vectores CVSSv3 e identificadores CVE. Faker no ofrece una forma directa de proporcionar estos datos de manera predeterminada, pero sí te permite agregar tus propios proveedores; ahí es donde entra en juego faker-security.

¿Qué es faker-security?

faker-security es un paquete de Python que funciona como proveedor de Faker y te permite generar datos relacionados con la seguridad de forma aleatoria para tus proyectos. Actualmente, faker-security permite generar:

  • vectores CVSSv3

  • vectores CVSSv2

  • versiones semver

  • rangos de versiones semver de NPM

  • CVE

  • CWE

En el futuro, esperamos incluir más métodos de generación y tipos de rangos de versiones, como el semver de Maven.

A partir de los ejemplos anteriores, si queremos crear algún tipo de VulnerabilityFactory para generar datos ficticios, la definiríamos de la siguiente manera:

import factory
from factory.django import DjangoModelFactory
from faker_security.providers import SecurityProvider
from myproject.models import Vulnerability

factory.Faker.add_provider(SecurityProvider)

class VulnerabilityFactory(DjangoModelFatory):
    class Meta:
        model = Vulnerability

    cvss_v3_vector = factory.Faker("cvssv3")
    cve_id = factory.Faker("cve")
    cwe_id = factory.Faker("cwe")

Cómo usar faker-security

faker-security se puede instalar mediante pip:

pip install faker-security

Si quieres usarlo en tu proyecto, agrégalo al archivo de dependencias que prefieras. Por lo general, este es el archivo requirements.txt de tu proyecto. Si usas un administrador de paquetes de nivel superior, como poetry o pipenv, sigue sus instrucciones para agregar paquetes nuevos.

Una vez instalado, solo tienes que configurar Faker o factory_boy para que use faker-security.

Si ejecutas pruebas con pytest, te recomendamos configurar faker-security para factory_boy en tu archivo conftest.py de la siguiente manera:

import factory
from faker_security.providers import SecurityProvider

def pytest_configure():
    factory.Faker.add_provider(SecurityProvider)

Cómo avanzar con faker-security

Usar factory_boy y Faker es una excelente forma de simplificar tus pruebas, y con faker-security ahora tienes una manera rápida y sencilla de generar datos de seguridad ficticios para todos tus proyectos.

Esperamos que este paquete te resulte tan útil como a nosotros y nos encantaría que contribuyeras. Dale una estrella a nuestro repositorio de GitHub y envía pull requests y contribuciones. ¡Que disfrutes las pruebas!

Publicado en: