
Un marco pitónico para el modelado de amenazas
El modelado de amenazas tradicional con demasiada frecuencia llega tarde a la fiesta, o a veces no llega en absoluto. Además, crear flujos de datos y informes manuales puede llevar muchísimo tiempo. El objetivo de pytm es desplazar el modelado de amenazas hacia la izquierda, haciendo que el modelado de amenazas sea más automatizado y centrado en el desarrollador.
Basándose en su entrada y en la definición del diseño arquitectónico, pytm puede generar automáticamente los siguientes elementos:
El archivo tm.py es un modelo de ejemplo. Puede ejecutarlo para generar el informe y los archivos de imagen del diagrama a los que hace referencia:
mkdir -p tm
./tm.py --report docs/basic_template.md | pandoc -f markdown -t html > tm/report.html
./tm.py --dfd | dot -Tpng -o tm/dfd.png
./tm.py --seq | java -Djava.awt.headless=true -jar $PLANTUML_PATH -tpng -pipe > tm/seq.png
También hay un Makefile de ejemplo que envuelve todo esto en objetivos que se pueden compartir fácilmente para múltiples modelos. Si tienes GNU make instalado (disponible por defecto en las distribuciones de Linux pero no en OSX), simplemente ejecuta:
make MODEL=the_name_of_your_model_minus_.py
Debes tener plantuml.jar en el mismo directorio que tu modelo, o configurar PLANTUML_PATH.
Para evitar instalar todas las dependencias, como pandoc o Java, el script puede ejecutarse dentro de un contenedor:
# do this only once
export USE_DOCKER=true
make image
# call this after every change in your model
make
Para simplificar el uso de pytm, las dependencias del host pueden aislarse por completo
usando Devbox. Esta suele ser una
alternativa con menor sobrecarga y más conveniente que el enfoque de contenedor OCI.
curl -fsSL https://get.jetify.com/devbox | bashdevbox version update~/.config/nix/nix.conf: access-tokens = github.com=YOUR_TOKEN_HEREdevbox.json del proyecto: devbox shellpython en tu terminal mediante el comando which python. La salida debería ser la siguiente ruta: .devbox/nix/profile/default/bin/pythonsample.png: ./tm.py --dfd | dot -Tpng -o sample.pngexit"¡Pero pensé que ya habíamos terminado con esto de 'escribir código'!" - esta es para aquellos de nosotros que disfrutamos demasiado hablar con asistentes de IA: echa un vistazo a https://github.com/izar/tm_skills para conocer algunas formas de añadir OWASP pytm a tu asistente de programación (¡aún necesitarás tener una instalación funcional de pytm!).
Todos los argumentos disponibles:
usage: tm.py [-h] [--debug] [--dfd] [--report REPORT] [--exclude EXCLUDE]
[--seq] [--list] [--colormap] [--describe DESCRIBE]
[--list-elements] [--json JSON] [--levels LEVELS [LEVELS ...]]
[--stale_days STALE_DAYS]
options:
-h, --help show this help message and exit
--debug print debug messages
--dfd output DFD
--report REPORT output report using the named template file (sample
template file is under docs/basic_template.md)
--exclude EXCLUDE specify threat IDs to be ignored
--seq output sequential diagram
--list list all available threats
--colormap color the risk in the diagram
--describe DESCRIBE describe the properties available for a given element
--list-elements list all elements which can be part of a threat model
--json JSON output a JSON file
--levels LEVELS [LEVELS ...]
Select levels to be drawn in the threat model (int
separated by comma).
--stale_days STALE_DAYS
checks if the delta between the TM script and the code
described by it is bigger than the specified value in
days
El argumento stale_days intenta determinar cuántos días de diferencia hay entre el script del modelo (que estás escribiendo) y el código que implementa el sistema que se está modelando. Idealmente, deberían estar bastante cerca en la mayoría de los casos de un sistema en desarrollo activo. Puedes ejecutar esto periódicamente para medir el pulso de tu proyecto y la 'frescura' de tu modelo de amenazas.
Actualmente, los elementos disponibles son: TM, Element, Server, ExternalEntity, Datastore, Actor, Process, Dataflow, Boundary, Lambda, LLM y Agent.
Las propiedades disponibles de un elemento se pueden listar usando --describe seguido del nombre de un elemento: