diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62107d36..49ec5198 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/tox-dev/pyproject-fmt - rev: 3632ea90e7641b574983ddf3a11ccedefff3c881 # frozen: v2.25.3 + rev: d600c142bb19f521ae6a6a345f94a2efd7937759 # frozen: v2.26.0 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject @@ -32,7 +32,7 @@ repos: hooks: - id: validate-pyproject - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 01a675ea018f2fb714478a5ffb83fcea8374bb06 # frozen: v0.15.21 + rev: 39d9ac5938dadb73df0564a45f163e25ff9fa6e2 # frozen: v0.16.1 hooks: - id: ruff-check args: [--fix, --exit-non-zero-on-fix] @@ -43,14 +43,14 @@ repos: - id: sphinx-lint types: [rst] - repo: https://github.com/adamchainz/blacken-docs - rev: fda77690955e9b63c6687d8806bafd56a526e45f # frozen: 1.20.0 + rev: dda8db18cfc68df532abf33b185ecd12d5b7b326 # frozen: 1.20.0 hooks: - id: blacken-docs args: [--line-length=79] additional_dependencies: - black - repo: https://github.com/codespell-project/codespell - rev: 2ccb47ff45ad361a21071a7eedda4c37e6ae8c5a # frozen: v2.4.2 + rev: 57b21406f092110c18776e39b0bda50d37c945c8 # frozen: v2.4.3 hooks: - id: codespell args: [--toml pyproject.toml] diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f54d9d92..fe955875 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,6 +27,7 @@ Added Changed ~~~~~~~ +* 📝 Extend seccurity section * 👷🔧📝 Switch to prek * Remove pre-commit diff --git a/docs/productive/qa/pysa.rst b/docs/productive/qa/pysa.rst index e77206d2..2d3c8bf5 100644 --- a/docs/productive/qa/pysa.rst +++ b/docs/productive/qa/pysa.rst @@ -13,10 +13,10 @@ Ursprung zu ihrem Endpunkt und identifiziert dabei anfälligen Code. .. seealso:: * `What Is Taint Analysis and Why Should I Care? `_ - * `How Pysa works `_ + * `How Pysa works `_ * `Running Pysa `_ * `Pysa Tutorial - `_ + `_ Konfiguration ------------- diff --git a/docs/productive/security/dependencies.rst b/docs/productive/security/dependencies.rst index fb583ff1..f3b5f876 100644 --- a/docs/productive/security/dependencies.rst +++ b/docs/productive/security/dependencies.rst @@ -2,19 +2,22 @@ .. .. SPDX-License-Identifier: BSD-3-Clause -Abhängigkeiten verwalten -======================== +Abhängigkeiten +============== Genau hier finden Angriffe auf die Software-Lieferkette statt. Das `OpenSSF Secure Supply Chain Consumption Framework (S2C2F) `_ bietet ein strukturiertes Reifegradmodell -dafür, wie Unternehmen Open-Source-Software nutzen sollten. +dafür, wie Unternehmen Open-Source-Software nutzen sollten. Bedauerlicherweise +ist das :abbr:`S2C2F (Secure Supply Chain Consumption Framework)` jedoch +beschränkt auf GitHub-Projekte. Daher suchten wir nach vergleichbaren Lösungen +für unsere Python-Projekte, die ohne GitHub auskommen. .. seealso:: - Für ein umfassenderes Bedrohungsmodell über alle Ökosysteme hinweg ist das - `CNCF Software Supply Chain Security Whitepaper - `_ - eine gute Einführung. + * `OpenSSF Scorecard `_ + * :ref:`open_chain` + * `CNCF Software Supply Chain Security Whitepaper + `_ Wählt eure Abhängigkeiten sorgfältig aus ---------------------------------------- @@ -22,18 +25,152 @@ Wählt eure Abhängigkeiten sorgfältig aus Bevor ihr eine Abhängigkeit hinzufügt, solltet ihr prüfen, ob ihr diese überhaupt benötigt, denn jede Abhängigkeit vergrößert eure Angriffsfläche. Weniger oder kleinere Abhängigkeiten bedeuten weniger Angriffsmöglichkeiten. -Wenn ihr eine Abhängigkeit hinzufügt, bewertet die Sicherheitslage mithilfe der -`OpenSSF-Scorecard `_, die Projekte bewertet -hinsichtlich - -* :doc:`Branch<../git/branch>`-Protection -* signierte Releases -* Tools zur Aktualisierung von Abhängigkeiten -* Vulnerability Disclosure +Wenn ihr eine Abhängigkeit hinzufügt, könnt ihr die Sicherheitslage mithilfe der +`OpenSSF-Scorecard `_ bewerten: Eine niedrige Punktzahl gibt euch Aufschluss darüber, wie viel Vertrauen ihr in ein Projekt mit eingeschränkter Sicherheitshygiene setzen solltet. +Gibt es ein Sicherheitskonzept? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Idealerweise sollte mit der Abhängigkeit eine +:ref:`python-basics:security`-Datei :abbr:`o. ä. (oder ähnliches)` +veröffentlicht worden sein. Diese Datei sollte Informationen enthalten, + +* wie eine Sicherheitslücke gemeldet werden kann ohne dass sie öffentlich + sichtbar wird, +* über den Ablauf und den Zeitplan für die Offenlegung der Schwachstelle, +* zu Links, :abbr:`z. B. (zum Beispiel)` URLs und E-Mails, unter denen + Unterstützung angefragt werden kann. + +.. seealso:: + * `Guide to implementing a coordinated vulnerability disclosure process for + open source projects + `_ + * `Adding a security policy to your repository + `_ + * `Runbook + `_ + +Werden CI-Tests durchgeführt? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Bevor Code in Pull- oder Merge-Requests zusammengeführt wird, sollten Tests +durchgeführt werden, die dabei helfen, Fehler frühzeitig zu erkennen und die +Anzahl der Schwachstellen in einem Projekt zu reduzieren. + +.. seealso:: + * :ref:`coverage-github-actions` + +Werden Fuzzing-Tools verwendet? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fuzzing oder Fuzz-Testing übergibt unerwartete oder zufällige Daten an euer +Programm, um Fehler zu entdecken. Regelmäßiges Fuzzing ist wichtig, um +Schwachstellen aufzuspüren, die von anderen ausgenutzt werden können, zumal auch +bei einem Angriff Fuzzing genutzt werden kann, um dieselben Schwachstellen zu +finden. + +* Verwendet euer Projekt `Fuzzing `_? +* Ist der Name des Repository in der `OSS-Fuzz + `_-Projektliste enthalten? +* Wird `ClusterFuzzLite `_ im + Repository eingesetzt? +* Sind benutzerdefinierte sprachenspezifische Fuzzing-Funktionen im Repository + vorhanden, :abbr:`z. B. (zum Beispiel)` mit `atheris + `_? + +Werden Werkzeuge zur statischen Codeanalyse verwendet? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:term:`Statische Testverfahren` testen den Quellcode, bevor die Anwendung +ausgeführt wird. Dies kann verhindern, dass bekannte Fehlerklassen versehentlich +in die Codebasis eingeführt werden. + +Ist der Quellcode frei von eingecheckten Binärdateien? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Generierte ausführbare Dateien im Quellcode-Repository (:abbr:`z. B. (zum +Beispiel)` Python :file:`.pyc` Dateien) erhöhen das Risiko, da sie schwer +überprüft werden können, so dass sie veraltet oder böswillig manipuliert sein +können. Diesen Problemen kann mit verifizierten, reproduzierbaren Builds +begegnet werden, deren ausführbare Dateien jedoch nicht wieder im +Quellcode-Repository landen sollten. + +.. seealso:: + * `Reproducible Builds `_ + * `Python 3.12.0 from a supply chain security perspective + `_ + * `Defending against the PyTorch supply chain attack PoC + `_ + +Kann bösartigem Code eingeschleust werden? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mit :ref:`geschützten Git-Zweigen ` können Regeln für die +Übernahme von Änderungen in Standard- und Veröffentlichungszweige definiert +werden, :abbr:`z. B. (zum Beispiel)` automatisierte `statische Code-Analysen +`_ mit +:doc:`../qa/ruff`, :doc:`../qa/pysa`, :doc:`../qa/wily` und :ref:`Code-Reviews +` über :abbr:`sog. (sogenannte)` +:doc:`../git/advanced/gitlab/merge-requests`. + +.. _code_reviews: + +Werden Code-Reviews durchgeführt? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mit Code-Reviews lassen sich unbeabsichtigte Schwachstellen oder das mögliche +Einschleusen von bösartigem Code erkennen. :abbr:`Ggf. (Gegebenenfalls)` können +so Angriffe aufgespürt werden, bei denen das Konto eines Teammitglieds +unterwandert wurde. + +Wirken Personen aus mehreren Organisationen mit? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Dies wird als Indiz für eine geringere Anzahl von vertrauenswürdigen +Code-Reviewers gewertet. Hierfür kann in den Profilen nach unterschiedlichen +Einträgen im Feld *Unternehmen* gesucht werden. Wünschenswert sind mindestens +drei verschiedene Unternehmen in den letzten 30 Commits, wobei jedes dieser +Teammitglieder mindestens fünf Commits gemacht haben sollte. + +.. _lock-dependencies: + +Werden Abhängigkeiten deklariert und festgeschrieben? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In eurem Projekt sollten Abhängigkeiten, die während des Build- und +Release-Prozesses verwendet werden, festgeschrieben werden. Dabei sollte eine +*gepinnte Abhängigkeit* explizit auf einen bestimmten Hash gesetzt sein und +nicht nur auf eine veränderbare Version oder einen Versionsbereich. + +:doc:`../envs/spack/index` schreibt für die jeweilige Umgebung diese Hashes in +:ref:`spack_lock`, :doc:`../envs/uv/index` in :ref:`uv_lock` fest. + +.. tip:: + Üblicherweise verwalte ich diese Dateien jedoch nur bei + :doc:`python-basics:packs/apps` in :doc:`Git <../git/index>`. Bei + :doc:`python-basics:libs/index` schränke ich üblicherweise lediglich den + Versionsbereich der Abhängigkeiten in der :file:`pyproject.toml`-Datei ein. + +Für :doc:`python-basics:packs/apps` können sich dadurch die folgenden +Sicherheitsrisiken verringern: + +* Die Prüfung und Bereitstellung erfolgt mit derselben Software, was die Risiken + beim Deployment verringert, die Fehlersuche vereinfacht und Reproduzierbarkeit + ermöglicht. +* Kompromittierte Abhängigkeiten untergraben nicht die Sicherheit des Projekts. +* Substitutionsangriffe, also Angriffe, die auf die Verwechslung von + Abhängigkeiten abzielen, kann so entgegengewirkt werden. + +Das Festschreiben der Abhängigkeiten sollte jedoch Software-Updates nicht +verhindern. Ihr könnt dieses Risiko verringern durch + +* automatisierte Werkzeuge, die euch benachrichtigen, wenn Abhängigkeiten in + eurem Projekt veraltet sind +* Anwendungen, die Abhängigkeiten festhalten, schnell aktualisieren. + Schreibt die Abhängigkeiten fest -------------------------------- @@ -65,14 +202,24 @@ Releases für eine Version innerhalb von 14 Tagen erlaubt Hash-Pinning ist sicherer – es erstellt einen kryptografischen Fingerabdruck der Paketdatei, der mit :term:`uv` in der :file:`uv.lock`-Datei festgeschrieben -wird. Alternativ könnt ihr auch die ``--require-hashes``-Option von :term:`pip` -verwenden. Ihr solltet jedoch nicht nur für eure Python-Abhängigkeiten -Hash-Pinning verwenden, sondern :abbr:`z. B. (zum Beispiel)` auch für eure -:doc:`pre-commit Checks <../git/advanced/hooks/checks>` und GitHub Actions. +wird. Alternativ könnt ihr auch ``pip-compile --generate-hashes`` der `pip-tools +`_ verwenden: + +.. code-block:: console + + $ python -m pip install pip-tools + $ pip-compile --generate-hashes pyproject.toml -o requirements.txt + +.. seealso:: + * `Secure installs `_ + +Ihr solltet jedoch nicht nur für eure Python-Abhängigkeiten Hash-Pinning +verwenden, sondern :abbr:`z. B. (zum Beispiel)` auch für eure :doc:`pre-commit +Checks <../git/advanced/hooks/checks>` und :ref:`GitHub Actions `. Hash-Pinning schützt jedoch nicht davor, ein schädliches Paket zum ersten Mal zu installieren; in diesem Fall würdet ihr nur den Hash des schädlichen Pakets -festlegen. Daher solltet ihr das Hash-Pinning mit Schwachstellenscans und +festlegen. Daher solltet ihr das Hash-Pinning mit Schwachstellen-Scans und verzögerter Übernahme kombinieren. .. seealso:: @@ -114,7 +261,7 @@ könnt ihr regelmäßig eure :file:`uv.lock`-Datei aktualisieren: .. seealso:: * :ref:`Update uv.lock ` -Alternativ könnt ihr euch auch von :doc:`../envs/uv/renovate>` unterstützen +Alternativ könnt ihr euch auch von :doc:`../envs/uv/dependency-bot` unterstützen lassen. .. _vulnerability_scans: @@ -123,7 +270,7 @@ Schwachstellen-Scans -------------------- *Dependency Pinning* verhindert unbefugte Änderungen – doch was passiert, wenn -ihr eine Version gestgeschrieben habt, die eine bekannte Sicherheitslücke +ihr eine Version festgeschrieben habt, die eine bekannte Sicherheitslücke aufweist? Forschende entdecken immer wieder neue :abbr:`CVEs (Common Vulnerabilities and Exposures)` in Paketen. Ein Paket, das gestern noch problemlos war, könnte heute schon eine kritische Sicherheitslücke aufweisen. @@ -183,7 +330,7 @@ oder besser: * `ignore-until-fixed `_ -Ihr könnt die Schwachstellenanalyse mit ``uv-audit`` auch in eure :doc:`prek +Ihr könnt die Schwachstellen-Analyse mit ``uv-audit`` auch in eure :doc:`prek <../git/advanced/hooks/prek>`-Checks übernehmen: .. code-block:: yaml @@ -195,7 +342,7 @@ Ihr könnt die Schwachstellenanalyse mit ``uv-audit`` auch in eure :doc:`prek files: ^(uv\.lock|pyproject\.toml)$ Sicherheitsprüfungen sollten automatisiert durchgeführt werden. Hierzu könnt ihr -``uv audit`` :abbr:`z.B . (zum Beispiel)` in einer GitHub Action verwenden: +``uv audit`` :abbr:`z. B. (zum Beispiel)` in einer GitHub Action verwenden: .. code-block:: yaml @@ -219,7 +366,9 @@ oder in einer GitLb CI/CD-Pipeline: Alternativ zu ``uv audit`` könnt ihr hierfür auch `osv `_ oder `pip-audit -`_ verwenden. +`_ verwenden. Es gibt auch eine +entsprechende GitHub-Action: `pypa/gh-action-pip-audit +`_. Vermeidet Abhängigkeitskonflikte -------------------------------- @@ -235,7 +384,7 @@ Angriff wie folgt: {https://EXAPMPLE.COM/simple MYPACKAGE}` :abbr:`o. ä. (oder ähnlichem)` würdet ihr vermutlich erwarten, dass :samp:`{MYPACKAGE}` von eurem Index :samp:`https://{EXAPMPLE.COM}/simple` geladen würde. -#. ``pip`` schaut jeddoch in allen Indexen nach und wählt die höchste Version +#. ``pip`` schaut jedoch in allen Indexen nach und wählt die höchste Version aus. #. Liegt also auf :term:`PyPI` eine höhere Version von :samp:`{MYPACKAGE}` mit bösartigem Code, wird diese installiert. @@ -257,7 +406,8 @@ aufzudecken, indem sie eine Bestandsliste zur Überprüfung bereitstellen; es handelt sich dabei jedoch um nachträgliche Kontrollmaßnahmen – sie zeigen euch also erst im Nachhinein, was ihr installiert habt. -:term:`uv` verwendet hingegen üblicherweise die ``first-index``-Strategie, nimmtalso den erstgenannten Index, in dem ein Paket gefunden wird. Dadurch werden die +:term:`uv` verwendet hingegen üblicherweise die ``first-index``-Strategie, nimmt +also den erstgenannten Index, in dem ein Paket gefunden wird. Dadurch werden die oben beschriebenen Abhängigkeitskonflikte vermieden: .. code-block:: toml @@ -279,294 +429,195 @@ Zeile 4: `Searching across multiple indexes `_ ----- - -Im folgenden schauen wir uns nun an, wie die Abhängigkeiten in unseren -Python-Projekten abgesichert werden kann. Dabei orientieren wir uns an der -`OpenSSF Scorecard `_. Alternativ könnt ihr -euch auch an :ref:`open_chain` orientieren. - -In einem früheren Abschnitt haben wir schon einige Hinweise gegeben, wie die -Veröffentlichung von Python-Paketen auf :term:`PyPI` abgesichert werden kann: - -.. seealso:: - * :ref:`secure-release-workflow` - * :ref:`add_2fa` - -.. seealso:: - Für ein umfassenderes Bedrohungsmodell über alle Ökosysteme hinweg ist das - `CNCF Software Supply Chain Security Whitepaper - `_ - eine gute Einführung. - -Nun wollen wir uns anschauen, wie Python-Projekte weiter abgesichert werden -können. Dabei orientieren wir uns an der `OpenSSF Scorecard -`_. Alternativ könnt ihr euch auch an -:ref:`open_chain` orientieren. - -Wartung -------- - -Werden die Abhängigkeiten noch gewartet? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Hoch - -Dies weist auf möglicherweise ungepatchte Sicherheitslücken hin. Daher sollte -regelmäßig überprüft werden, ob ein Projekt archiviert wurde. Umgekehrt wird bei -der OSSF-Scorecard davon ausgegangen, dass bei mindestens einem Commit in der -Woche über 90 Tage hinweg das Projekt sehr aktiv gewartet wird. Ein Mangel an -aktiver Wartung ist jedoch nicht unbedingt immer ein Problem: insbesondere -kleinere Dienstprogramme müssen normalerweise nicht oder nur sehr selten -gewartet werden. Fehlende aktive Wartung weist euch also nur darauf hin, dass -ihr die Situation genauer untersuchen solltet. - -Ihr könnt euch die Aktivitäten eines Projekts auch mit Badges anzeigen lassen, -:abbr:`z.B. (zum Beispiel)`: - -.. image:: https://img.shields.io/github/commit-activity/y/veit/python4datascience - :alt: Jährliche Commit-Aktivität -.. image:: https://img.shields.io/github/commit-activity/m/veit/python4datascience - :alt: Monatliche Commit-Aktivität -.. image:: https://img.shields.io/github/commit-activity/w/veit/python4datascience - :alt: Wöchentliche Commit-Aktivität - -Gibt es ein Sicherheitskonzept für das Projekt? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Mittel - -Idealerweise sollte mit dem Projekt eine :ref:`python-basics:security`-Datei -:abbr:`o.ä. (oder ähnliches)` veröffentlicht worden sein. Diese Datei sollte -Informationen enthalten, - -* wie eine Sicherheitslücke gemeldet werden kann ohne dass sie öffentlich - sichtbar wird, -* über den Ablauf und den Zeitplan für die Offenlegung der Schwachstelle, -* zu Links, :abbr:`z.B. (zum Beispiel)` URLs und E-Mails, unter denen - Unterstützung angefragt werden kann. - -.. seealso:: - * `Guide to implementing a coordinated vulnerability disclosure process for - open source projects - `_ - * `Adding a security policy to your repository - `_ - * `Runbook - `_ - -Enthält das Projekt eine verwendbare Lizenz? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Niedrig - -Eine :doc:`Lizenz ` weist darauf hin, wie der Quellcode -verwendet werden darf oder nicht. Das Fehlen einer Lizenz erschwert jede Art von -Sicherheitsüberprüfung oder Audit und stellt ein rechtliches Risiko für die -potenzielle Nutzung dar. - -OpenSSF-Scorecard verwendet die `GitHub License API -`_ -für auf GitHub gehostete Projekte, ansonsten eine eigene Heuristik, um eine -veröffentlichte Lizenzdatei zu erkennen. Dateien in einem -:file:`LICENSES`-Verzeichnis sollten mit ihrem :ref:`SPDX -`-Lizenzbezeichner benannt werden, gefolgt von einer -entsprechenden Dateierweiterung, wie in der :ref:`REUSE `-Spezifikation -beschrieben. - -OpenSSF Best Practices Badge -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Niedrig - -Mit dem `OpenSSF Best Practices Badge Programm -`_ könnt ihr euch auch ein entsprechendes -Badge holen. - -Kontinuierliches Testen ------------------------ - -Werden im Projekt CI-Tests durchgeführt? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Niedrig - -Bevor Code in Pull- oder Merge-Requests zusammengeführt wird, sollten Tests -durchgeführt werden, die dabei helfen, Fehler frühzeitig zu erkennen und die -Anzahl der Schwachstellen in einem Projekt zu reduzieren. - -.. seealso:: - * :ref:`coverage-github-actions` - -Verwendet das Projekt Fuzzing-Tools? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Mittel - -Fuzzing oder Fuzz-Testing übergibt unerwartete oder zufällige Daten an euer -Programm, um Fehler zu entdecken. Regelmäßiges Fuzzing ist wichtig, um -Schwachstellen aufzuspüren, die von anderen ausgenutzt werden können, zumal auch -bei einem Angriff Fuzzing genutzt werden kann, um dieselben Schwachstellen zu -finden. - -* Verwendet euer Projekt `Fuzzing `_? -* Ist der Name des Repository in der `OSS-Fuzz - `_-Projektliste enthalten? -* Wird `ClusterFuzzLite `_ im - Repository eingesetzt? -* Sind benutzerdefinierte sprachenspezifische Fuzzing-Funktionen im Repository - vorhanden, :abbr:`z.B. (zum Beispiel)` mit `atheris - `_? - -Verwendet euer Projekt Werkzeuge zur statischen Codeanalyse? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Mittel - -:term:`Statische Testverfahren` testen den Quellcode, bevor die Anwendung -ausgeführt wird. Dies kann verhindern, dass bekannte Fehlerklassen versehentlich -in die Codebasis eingeführt werden. - -.. _bandit: - -Mit `Bandit `__, das ihr mit :doc:`../qa/ruff` -verwenden könnt lassen sich :abbr:`u. a. (unter anderem)` folgende -Schwachstellen überprüfen: - -+--------+-----------------------------------------------------------------------+ -| Regel | Beschreibung | -+--------+-----------------------------------------------------------------------+ -| `S105`_| fest codierte Geheimnisse | -+--------+-----------------------------------------------------------------------+ -| `S301`_| :doc:`/data-processing/serialisation-formats/pickle/index` und andere | -| | unsichere Deserialisierung | -+--------+-----------------------------------------------------------------------+ -| `S307`_| Verwendung von :func:`eval` mit nicht vertrauenswürdigen Eingaben | -+--------+-----------------------------------------------------------------------+ -| `S113`_| fehlende Zeitüberschreitungen | -+--------+-----------------------------------------------------------------------+ -| `S324`_| schwache Kryptografie wie :abbr:`z. B. (zum Beispiel)` MD5-Kollisionen| -+--------+-----------------------------------------------------------------------+ -| `S608`_| SQL-Injection über Zeichenfolgenformatierung | -+--------+-----------------------------------------------------------------------+ - -.. seealso: - `flake8-bandit `_ - -Bandit könnt ihr auch in Jupyter Notebooks, IDEs und -:doc:`../git/advanced/hooks/prek` integrieren. - -Zudem könnt ihr :doc:`../qa/pysa` für `Taint -`_-Analysen verwenden. - -Für GitHub-Repositories könnt ihr alternativ auch `CodeQL -`_ verwenden; :abbr:`s.a. (siehe auch)` -`codeql-action -`_. - -Risikobewertung des Quellcodes +Überprüft Package Attestations ------------------------------ -Ist das Projekt frei von eingecheckten Binärdateien? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Hoch - -Generierte ausführbare Dateien im Quellcode-Repository (:abbr:`z.B. (zum -Beispiel)` Java :file:`.class`-Dateien, Python :file:`.pyc` Dateien) erhöhen das -Risiko, da sie schwer überprüft werden können, so dass sie veraltet oder -böswillig manipuliert sein können. Diesen Problemen kann mit verifizierten, -reproduzierbaren Builds begegnet werden, deren ausführbare Dateien jedoch nicht -wieder im Quellcode-Repository landen sollten. +:term:`PyPI` :ref:`Package Attestations ` liefern mithilfe +von `Sigstore `_ einen kryptografischen Nachweis über +die Herkunft eines Pakets gemäß :pep:`740`. Seit `gh-action-pypi-publish v1.11.0 +`_ werden +die Bescheinigungen auch automatisch generiert. Bis Ende 2025 nutzten mehr als +50-Tsd. Projekte *Trusted Publishing*, und 17 % der Uploads enthielten +Attestations. *Trusted Publishing* wurde zudem auf Organisationen und +selbstverwaltete GitLab-Instanzen ausgeweitet. .. seealso:: - * `Reproducible Builds `_ - * `Python 3.12.0 from a supply chain security perspective - `_ - * `Defending against the PyTorch supply chain attack PoC - `_ + * `PyPI in 2025: A Year in Review + `_ + * `Are we PEP 740 yet? 🔏 + `_ + +:pep:`740` definiert neben *Package Attestations* auch :abbr:`SLSA (Supply-chain +Levels for Software Artifacts)`-Provenance-Attestations. Für Anwendungsfälle +außerhalb von :term:`PyPI` kann `actions/attest +`_ diese SLSA-Provenienz- und +:doc:`SBOM `-Bescheinigungen für jedes Artefakt generieren. + +Im Fall des Angriffs auf :ref:`Ultralytics ` hätte mit den +Attestations erkannt werden können, welche Versionen aus einem kompromittierten +Workflow stammten und welche legitim waren – ganz ohne manuelle forensische +Analyse. Die Transparency-Logs von Sigstore bieten einen unabhängigen Prüfpfad +mit exakten Zeitstempeln und Angaben zur Herkunft jedes veröffentlichten +Artefakts. + +Fügt zeitbasierte Abwehrmaßnahmen hinzu +--------------------------------------- + +Wenn ein bösartiges Paket auf :term:`PyPI` veröffentlicht wird, ist es sofort +weltweit verfügbar. Die Erkennungszeiten variieren – manche Angriffe werden +innerhalb weniger Stunden entdeckt, während andere wochen- oder monatelang +unbemerkt bleiben. 2025 gab es über 2.000 Malware-Meldungen, wovon 66 % +innerhalb von vier Stunden bearbeitet wurden. + +Mit dem Abwarten vor der Verwendung neu veröffentlichter Pakete erhaltet ihr +zwar keine Garantie, aber das Risiko wird vermindert, da die Community +vermutlich innerhalb kurzer Zeit offensichtliche Bedrohungen aufdeckt. + +Moderne Paketmanager unterstützen zeitbasierte Filterung. :term:`uv` verfügt +über die Option ``--exclude-newer``, und pip ≥ v26 hat die Option +``--uploaded-prior-to`` mit demselben Zweck eingeführt wobei beide sich gemäß +:pep:`700` auf Metadaten zur Upload-Zeit stützen. + +Verwendet interne Paket-Repositories in euren Organisationen +------------------------------------------------------------ + +In kleineren Organisationen kann ein einfacher Spiegel des :term:`PyPI`, der +Pakete um eine Woche verzögert bereitstellt, bereits das Sicherheitsrisiko für +die Organisation vermindern. Ihr solltet dann jedoch darauf achten, dass ihr für +kritische Sicherheits-Patches die Verzögerung aufheben könnt. Sofern ihr in +eurer Organisation interne Paket-Repositories verwendet, könnt ihr darüberhinaus +noch weitere Sicherheitsmaßnahmen treffen: + +#. Automatisierte Security-Scans der Pakete +#. Automatisiertes Bauen der Pakete mit *Trusted Publishing* und SLSA-Provenienz + +Reagiert schnell, wenn ihr ein schädliches Paket entdeckt +--------------------------------------------------------- + +Wenn ihr ein kompromittiertes Paket bei euch entdeckt, könnt ihr mit schnellem +Handeln häufig größeren Schaden vermeiden. + +#. Isoliert das Paket unverzüglich + + Stoppt alle Deployments, die diese Abhängigkeit nutzen, und sperrt die + Paketversion in eurem internen Mirror, falls ihr einen solchen betreibt. Ziel + ist es, weitere Installationen zu verhindern, während ihr die Ursache weiter + untersuchen könnt. + +#. Bewertet den Schaden + + Überprüft anhand von Logs und Prozessdaten, ob der Schadcode ausgeführt + wurde. Ermittelt, auf welche vertraulichen Daten das Paket möglicherweise + zugegriffen hat: Umgebungsvariablen, Anmeldedaten, Cloud-Token :abbr:`etc. + (et cetera)`. Nutzt eure :doc:`SBOM `, um alle betroffenen Projekte bei + euch im Unternehmen zu identifizieren. + +#. Begrenzt den Schaden + + Ändert alle Anmeldedaten, auf die das Paket möglicherweise zugegriffen hat: + API-Schlüssel, Datenbankpasswörter, Cloud-Anmeldedaten. Scannt Systeme auf + Anzeichen einer Kompromittierung und überprüft ausgehende + Netzwerkverbindungen auf Anzeichen von Datenexfiltration. + +#. Entfernt die Abhängigkeit vollständig + + Fixiert eine bekanntermaßen fehlerfreie Version und entfernt die Abhängigkeit + vollständig. Führt ``pip-audit`` aus, um sicherzustellen, dass keine weiteren + Schwachstellen eingeführt wurden. Aktualisiert anschließend eure Lockfiles + mit der korrigierten Version. + +#. Meldet das schädliche Paket + + Über `PyPI’s security reporting system `_ könnt + ihr das schädliche Paket melden. Benachrichtigt auch Verantwortliche eurer + Organisation und potenziell betroffene Kunden. Dokumentiert den Vorfall: Was + ist passiert? Wie wurde das Paket entdeckt? Welche Änderungen habt ihr + vorgenommen, um eine Wiederholung zu verhindern? + +Überprüft, ob eure Abhängigkeiten noch gewartet werden? +------------------------------------------------------- + +Es sollte regelmäßig überprüft werden, ob eine Abhängigkeit archiviert wurde. +Die Checks der OSSF-Scorecard sind jedoch nur erfolgreich, wenn das Projekt +älter als 90 Tage ist. Ein Mangel an aktiver Wartung ist jedoch nicht unbedingt +immer ein Problem: insbesondere kleinere Dienstprogramme müssen normalerweise +nur sehr selten gewartet werden. Fehlende aktive Wartung weist euch also nur +darauf hin, dass ihr die Situation genauer untersuchen solltet. + +Mit `pypi-changes `_ gibt es ein +CLI-Tool, das die für einem Python-Interpreter installierten Pakete überprüft +und mit den neuesten Versionen auf :term:`PyPI` vergleicht. Es zeigt an, welche +Pakete veraltet sind, wie lange die Veröffentlichung der jeweiligen Version +zurückliegt, und hebt wichtige Versionssprünge hervor, damit ihr fundierte +Entscheidungen bezüglich Upgrades treffen können, :abbr:`z. B. (zum Beispiel)`: + +.. figure:: pypi-changes.png + :alt: Kommandozeilenaufruf uvx pypi-changes mit der Auflistung aller in einem + Projekt verwendeten Python-Bibliotheken, deren Version und + Veröffentlichungsdatum -Ist der Entwicklungsprozess anfällig für das Einschleusen von bösartigem Code? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Hoch - -Mit :ref:`geschützten Git-Zweigen ` können Regeln für die -Übernahme von Änderungen in Standard- und Veröffentlichungszweige definiert -werden, :abbr:`z.B. (zum Beispiel)` automatisierte `statische Code-Analysen -`_ mit -:doc:`../qa/flake8`, :doc:`../qa/pysa`, :doc:`../qa/wily` und :ref:`Code-Reviews -` über -:abbr:`sog. (sogenannte)` :doc:`../git/advanced/gitlab/merge-requests`. - -.. _code_reviews: - -Werden Code-Reviews durchgeführt? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Hoch - -Mit Code-Reviews lassen sich unbeabsichtigte Schwachstellen oder das mögliche -Einschleusen von bösartigem Code erkennen. :abbr:`Ggf. (Gegebenenfalls)` können -so Angriffe aufgespürt werden, bei denen das Konto eines Teammitglieds -unterwandert wurde. - -Wirken an dem Projekt Personen aus mehreren Organisationen mit? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Niedrig - -Dies wird als Indiz für eine geringere Anzahl von vertrauenswürdigen -Code-Reviewers gewertet. Hierfür kann in den Profilen nach unterschiedlichen -Einträgen im Feld *Unternehmen* gesucht werden. Wünschenswert sind mindestens -drei verschiedene Unternehmen in den letzten 30 Commits, wobei jedes dieser -Teammitglieder mindestens fünf Commits gemacht haben sollte. - -Risikobewertung der Builds --------------------------- - -.. _lock-dependencies: - -Werden im Projekt Abhängigkeiten deklariert und festgeschrieben? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Risiko: Mittel - -In eurem Projekt sollten Abhängigkeiten, die während des Build- und -Release-Prozesses verwendet werden, festgeschrieben werden. Dabei sollte eine -*gepinnte Abhängigkeit* explizit auf einen bestimmten Hash gesetzt sein und -nicht nur auf eine veränderbare Version oder einen Versionsbereich. - -:doc:`../envs/spack/index` schreibt für die jeweilige Umgebung diese Hashes in -:ref:`spack_lock`, :doc:`../envs/uv/index` in :ref:`uv_lock` fest. - -.. tip:: - Üblicherweise verwalte ich diese Dateien jedoch nur bei - :doc:`python-basics:packs/apps` in :doc:`Git <../git/index>`. Bei - :doc:`python-basics:libs/index` schränke ich üblicherweise lediglich den - Versionsbereich der Abhängigkeiten in der :file:`pyproject.toml`-Datei ein. - -Für :doc:`python-basics:packs/apps` können sich dadurch die folgenden -Sicherheitsrisiken verringern: - -* Die Prüfung und Bereitstellung erfolgt mit derselben Software, was die Risiken - beim Deployment verringert, die Fehlersuche vereinfacht und Reproduzierbarkeit - ermöglicht. -* Kompromittierte Abhängigkeiten untergraben nicht die Sicherheit des Projekts. -* Substitutionsangriffe, also Angriffe, die auf die Verwechslung von - Abhängigkeiten abzielen, kann so entgegengewirkt werden. - -Das Festschreiben der Abhängigkeiten sollte jedoch Software-Updates nicht -verhindern. Ihr könnt dieses Risiko verringern durch - -* automatisierte Werkzeuge, die euch benachrichtigen, wenn Abhängigkeiten in - eurem Projekt veraltet sind -* Anwendungen, die Abhängigkeiten festhalten, schnell aktualisieren. +.. + $ uvx pypi-changes + Installed 26 packages in 18ms + 🐍 Distributions within + /Users/veit/.cache/uv/archive-v0/soguBMAn2UOVYxDU/bin/python + ├── annotated-types 0.8.0 7 days + ├── certifi 2026.7.22 9 days + ├── soupsieve 2.9.1 9 days + ├── pypi-changes 1.6.0 9 days + ├── platformdirs 4.11.0 9 days + ├── charset-normalizer 3.4.9 a month + ├── requests-cache 1.3.3 a month + ├── typing_extensions 4.16.0 a month + ├── humanize 4.16.0 a month + ├── beautifulsoup4 4.15.0 2 months + ├── idna 3.18 2 months + ├── pydantic_core 2.46.4 3 months remote 2.47.0 2 months + ├── requests 2.34.2 3 months + ├── urllib3 2.7.0 3 months + ├── markdown-it-py 4.2.0 3 months + ├── pydantic 2.13.4 3 months + ├── url-normalize 3.0.0 3 months + ├── packaging 26.2 3 months + ├── rich 15.0.0 4 months + ├── Pygments 2.20.0 4 months + ├── attrs 26.1.0 4 months + ├── cattrs 26.1.0 5 months + ├── mailbits 0.2.3 8 months + ├── typing-inspection 0.4.2 10 months + ├── pypi-simple 1.8.0 11 months + └── mdurl 0.1.2 3 years + +Alternativ könnt ihr euch auch die PyPI-Versionen eines Projekts mit Badges +anzeigen lassen, :abbr:`z. B. (zum Beispiel)`: + ++---------------+-------------------------------------------------------+ +| Paketname | aktuelle PyPI-Version | ++===============+=======================================================+ +| pypi-simple | .. image:: https://img.shields.io/pypi/v/pypi-simple | +| | :alt: PyPI Version | +| | :target: https://pypi.org/project/pypi-simple | ++---------------+-------------------------------------------------------+ +| mdurl | .. image:: https://img.shields.io/pypi/v/mdurl | +| | :alt: PyPI Version | +| | :target: https://pypi.org/project/mdurl | ++---------------+-------------------------------------------------------+ + +.. tab:: reST + + .. code-block:: rst + + +---------------+-------------------------------------------------------+ + | Paketname | aktuelle PyPI-Version | + +===============+=======================================================+ + | pypi-simple | .. image:: https://img.shields.io/pypi/v/pypi-simple | + | | :alt: PyPI Version | + | | :target: https://pypi.org/project/pypi-simple | + +---------------+-------------------------------------------------------+ + | mdurl | .. image:: https://img.shields.io/pypi/v/mdurl | + | | :alt: PyPI Version | + | | :target: https://pypi.org/project/mdurl | + +---------------+-------------------------------------------------------+ -.. _S105: https://docs.astral.sh/ruff/rules/hardcoded-password-string/ -.. _S301: https://docs.astral.sh/ruff/rules/suspicious-pickle-usage/ -.. _S307: https://docs.astral.sh/ruff/rules/suspicious-eval-usage/ -.. _S113: https://docs.astral.sh/ruff/rules/request-without-timeout/ -.. _S324: https://docs.astral.sh/ruff/rules/hashlib-insecure-hash-function/ -.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/ -.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/ +.. seealso:: + * `Is it maintained? `_ diff --git a/docs/productive/security/environments.rst b/docs/productive/security/environments.rst index a64b0642..58e2f44e 100644 --- a/docs/productive/security/environments.rst +++ b/docs/productive/security/environments.rst @@ -54,7 +54,7 @@ die Entwicklungsumgebung enthält alle Abhängigkeiten. So wie eure Python-Umgebung mit unveränderbaren Referenzen aktuell gehalten werden sollte, sollten auch eure :doc:`../git/advanced/hooks/checks` und GitHub Actions regelmäßig aktualisiert -werdenn. +werden. In der :file:`.pre-commit-config.yaml` sollten die Versionen der Checks mit ihren Hashes regelmäßig aktualisiert werden, :abbr:`z. B. (zum Beispiel)` mit: @@ -68,19 +68,25 @@ ihren Hashes regelmäßig aktualisiert werden, :abbr:`z. B. (zum Beispiel)` mi .. seealso:: :doc:`../git/advanced/hooks/prek` -GitHub Actions könnt ihr `pinact `_ -verwenden, :abbr:`z. B. (zum Beispiel)` mit: +.. _pinact: + +Überprüft eure GitHub-Actions +----------------------------- + +Für GitHub Actions könnt ihr `pinact +`_ verwenden, :abbr:`z. B. (zum +Beispiel)` mit: .. code-block:: console $ pinact run -u --min-age 7 -Überprüft eure GitHub-Actions ------------------------------ +`zizmor `_ ist ein Tool zur statischen Analyse, das +Sicherheitslücken in GitHub-Actions-Workflows aufspürt – darunter +Template-Injection, nicht fixierte Aktionen, übermäßige Berechtigungen, das +Offenlegen von Anmeldedaten sowie `mehr als 30 weitere Prüfregeln +`_. ``zizmor`` erkennt Schwachstellen wie +diejenigen, die durch :ref:`token_exfiltration` ausgenutzt wurden. -:ref:`zizmorcore` ist ein Tool zur statischen Analyse, das Sicherheitslücken in -GitHub-Actions-Workflows aufspürt – darunter Template-Injection, nicht fixierte -Aktionen, übermäßige Berechtigungen, das Offenlegen von Anmeldedaten sowie `mehr -als 30 weitere Prüfregeln `_. ``zizmor`` erkennt -Schwachstellen wie diejenigen, die durch :ref:`token_exfiltration` ausgenutzt -wurden. +.. seealso:: + * :ref:`zizmorcore` diff --git a/docs/productive/security/index.rst b/docs/productive/security/index.rst index 93c8daee..94f579dd 100644 --- a/docs/productive/security/index.rst +++ b/docs/productive/security/index.rst @@ -55,16 +55,18 @@ Phishing-Angriff per E-Mail auf PyPI-User `PyPI Users Email Phishing Attack `_ -ZIP-Parser-Verwirrungsangriffe - Im August 2025 führte :term:`PyPI` Restriktionen ein, die verhindern sollen, - dass es bei Installations- und Prüfprogramme für Python-Pakete durch - unterschiedliche Implementierungen des ZIP-Parsers zu Verwechslungen kommen - kann. :term:`uv` zeigte ein anderes Entpackungsverhalten als viele - Python-basierte Installationsprogramme, die :mod:`zipfile` verwenden. +Shai-Hulud + Im November 2025 entwickelt sich ein Angriff auf das `npm + `_-Ökosystem weiter und nutzt kompromittierte Konten + aus, um schädliche Pakete zu veröffentlichen. Diese als *Shai-Hulud* + bezeichnete Kampagne hat eine große Anzahl von JavaScript-Paketen ins Visier + genommen und Zugangsdaten abgezogen, um sich weiter zu verbreiten. + :term:`PyPI` selbst wurde zwar nicht ausgenutzt, jedoch wurden einige + PyPI-Anmeldedaten in kompromittierten Repositories offengelegt. .. seealso:: - `uv security advisory: ZIP payload obfuscation - `_ + `PyPI and Shai-Hulud: Staying Secure Amid Emerging Threats + `_ .. _token_exfiltration: @@ -79,6 +81,19 @@ Token Exfiltration `Token Exfiltration Campaign via GitHub Actions Workflows `_ +ZIP-Parser-Verwirrungsangriffe + Im August 2025 führte :term:`PyPI` Restriktionen ein, die verhindern sollen, + dass es bei Installations- und Prüfprogramme für Python-Pakete durch + unterschiedliche Implementierungen des ZIP-Parsers zu Verwechslungen kommen + kann. :term:`uv` zeigte ein anderes Entpackungsverhalten als viele + Python-basierte Installationsprogramme, die :mod:`zipfile` verwenden. + + .. seealso:: + `uv security advisory: ZIP payload obfuscation + `_ + +.. _ultralytics: + Ultralytics Im Dezember 2024 wurde `ultralytics `_ Opfer eines Supply-Chain-Angriffs, @@ -90,19 +105,6 @@ Ultralytics `Supply-chain attack analysis: Ultralytics `_ -Shai-Hulud - Im November 2025 entwickelt sich ein Angriff auf das `npm - `_-Ökosystem weiter und nutzt kompromittierte Konten - aus, um schädliche Pakete zu veröffentlichen. Diese als *Shai-Hulud* - bezeichnete Kampagne hat eine große Anzahl von JavaScript-Paketen ins Visier - genommen und Zugangsdaten abgezogen, um sich weiter zu verbreiten. - :term:`PyPI` selbst wurde zwar nicht ausgenutzt, jedoch wurden einige - PyPI-Anmeldedaten in kompromittierten Repositoriess offengelegt. - - .. seealso:: - `PyPI and Shai-Hulud: Staying Secure Amid Emerging Threats - `_ - Das sind keine theoretischen Angriffe. Sie haben sich bei echten Projekten mit Millionen von Nutzer*innen ereignet. Wenn ihr ein bösartiges Paket auf PyPI entdeckt, könnt ihr es über das `Sicherheitsmeldesystem von PyPI @@ -137,6 +139,7 @@ seit Juli 2024 erstellten Berichte zu GitHub-Sicherheitshinweisen: :titlesonly: :maxdepth: 0 + own-code dependencies environments sbom diff --git a/docs/productive/security/own-code.rst b/docs/productive/security/own-code.rst new file mode 100644 index 00000000..845bab5a --- /dev/null +++ b/docs/productive/security/own-code.rst @@ -0,0 +1,165 @@ +.. SPDX-FileCopyrightText: 2023 cusy GmbH +.. +.. SPDX-License-Identifier: BSD-3-Clause + +Eigener Code +============ + +Angriffe auf die Lieferkette gehen nicht nur von :doc:`dependencies` aus, auch +euer eigener Code kann Angriffspunkte liefern. Ein fest im Quellcode +hinterlegtes PyPI-Token liefert, sobald es in ein öffentliches Repository +hochgeladen wurde, alles, was für einem Angriff benötigt wird und euer Konto zu +kompromittieren und bösartige Pakete unter eurem Namen zu veröffentlichen. +Abgesehen von Secrets verbergen sich häufige Sicherheitsfehler in alltäglichen +Codemustern, die bei einem Code-Review zunächst unbedenklich erscheinen und von +Menschen übersehen werden können. Diese mit einem Linter aufzuspüren, ist die +erste Verteidigungsstufe. + +Das ewige Geheimnis +------------------- + +Durchgesickerte Zugangsdaten sind der Ausgangspunkt für viele +Sicherheitsverletzungen in der Lieferkette. Ein offengelegtes :term:`PyPI`-Token +ermöglicht, mit Hintertüren versehene Versionen eurer Pakete zu veröffentlichen. +Eine offengelegte Datenbank-URL ermöglicht, Daten zu entwenden. Und doch ist ein +solches Muster weit verbreitet. Besser ist die Verwendung von +Umgebungsvariablen: + +.. code-block:: python + + import os + + DATABASE_KEY = os.environ["DB_KEY"] + DATABASE_URL = os.environ["DB_URL"] + +.. warning:: + Git vergisst nie: wenn ihr ein Secret einmal durch Git verwaltet habt, bleibt + es für immer in der Historie eures Repositories erhalten. Es in einem + späteren Commit einfach zu löschen, hilft nicht wirklich. Alle, die Zugriff + auf das Repository haben, können diese Anmeldedaten wieder extrahieren. Bei + Angriffen wird oft zunächst die Git-Historie nach Geheimnissen durchforstet, + und ein einmal veröffentlichts PyPI-Token oder Cloud-Anmeldedaten sind oft + der erste Schritt bei einer Kompromittierung der Lieferkette. + +Kryptografische Schwachstellen +------------------------------ + +Weitere häufige Sicherheitslücken sind kryptografische Schwachstellen wie +`MD5 `_ und `SHA-1 +`_. MD5-Kollisionen +wurden erstmals 2004 nachgewiesen und SHA1-Kollisionen 2017. Es können also +Kollisionen erzeugt werden durch andere Eingaben, die denselben Hash-Wert +ergeben. Dies ermöglicht die Fälschung von Zertifikaten, die Manipulation von +Downloads oder die Umgehung von Integritätsprüfungen. Verwendet daher keines der +beiden Verfahren für Sicherheitszwecke sondern stattdessen `SHA256 oder besser +`_: + +.. code-block:: python + + import hashlib + + digest = hashlib.sha256(payload).hexdigest() + +Hängende Verbindungen +--------------------- + +Das hier ist zwar subtil, aber dennoch gefährlich, da ein langsamer Server +euren Prozess auf unbestimmte Zeit zum Stillstand bringen kann. Ein Angriff über +einen solchen Server, mit dem eure Anwendung kommuniziert, kann jede Anfrage zum +Erliegen bringen, euren Thread-Pool erschöpfen und einen +Denial-of-Service-Angriff auslösen. Eure gesamte Anwendung kommt dann zum +Stillstand, weil ihr einen Parameter vergessen habt. Daher solltet ihr immer +einen Timeout angeben: + +.. code-block:: pycon + + >>> import httpx + >>> r = httpx.get("https://httpbin.org/get", timeout=30) + httpx.ReadTimeout: The read operation timed out + +.. _bandit: + +Erkennt Sicherheitslücken mit Ruff +---------------------------------- + +:doc:`../qa/ruff` ist ein schneller Python-Linter, der umfassende +Sicherheitsregeln von :ref:`Bandit ` enthält: + +.. code-block:: console + + $ uvx ruff check --select S . + +.. seealso:: + Weitere Informationen findet ihr in der `Dokumentation zu den + Ruff-Sicherheitsregeln + `_. + +Für zukünftige Checks könnt ihr ``ruff`` ihn in der :file:`pyproject.toml`-Datei +konfigurieren: + +.. code-block:: toml + + [tool.ruff] + lint.select = ["S"] + +Die Sicherheitsregeln ``["S"]`` mit den Bandit-Prüfungen.spüren fest codierte +Geheimnisse, schwache Verschlüsselung und unsichere Deserialisierung auf. Dabei +läuft Ruff in weniger als einer Sekunde, sodass ihr es während der Eingabe in +eurer IDE und vor jedem Commit ausführen könnt. Alle drei oben genannten +Schwachstellen werden erkannt und noch viel mehr, :abbr:`u. a. (unter anderem)`: + ++--------+-----------------------------------------------------------------------+ +| Regel | Beschreibung | ++--------+-----------------------------------------------------------------------+ +| `S105`_| fest codierte Geheimnisse | ++--------+-----------------------------------------------------------------------+ +| `S301`_| :doc:`/data-processing/serialisation-formats/pickle/index` und andere | +| | unsichere Deserialisierung | ++--------+-----------------------------------------------------------------------+ +| `S307`_| Verwendung von :func:`eval` mit nicht vertrauenswürdigen Eingaben | ++--------+-----------------------------------------------------------------------+ +| `S113`_| fehlende Zeitüberschreitungen | ++--------+-----------------------------------------------------------------------+ +| `S324`_| schwache Kryptografie wie :abbr:`z. B. (zum Beispiel)` MD5-Kollisionen| ++--------+-----------------------------------------------------------------------+ +| `S608`_| SQL-Injection über String-Formatierung | ++--------+-----------------------------------------------------------------------+ + +.. seealso:: + * `flake8-bandit (S) `_ + * `lint.flake8-bandit + `_ + +Bandit könnt ihr auch in Jupyter Notebooks, :abbr:`IDEs (Integrated Development +Wnvironments)` und :doc:`../git/advanced/hooks/prek` integrieren. + +Zudem könnt ihr :doc:`../qa/pysa` für `Taint +`_-Analysen verwenden. + +Für GitHub-Repositories könnt ihr alternativ auch `CodeQL +`_ verwenden; :abbr:`s.a. (siehe auch)` +`codeql-action +`_. + +Vertrauenswürdige Veröffentlichung +---------------------------------- + +In einem früheren Abschnitt haben wir schon einige Hinweise gegeben, wie die +Veröffentlichung von Python-Paketen auf :term:`PyPI` abgesichert werden kann: + +.. seealso:: + * :ref:`secure-release-workflow` + * :ref:`add_2fa` + +.. seealso:: + * `Publishing package distribution releases using GitHub Actions CI/CD + workflows + `_ + +.. _S105: https://docs.astral.sh/ruff/rules/hardcoded-password-string/ +.. _S301: https://docs.astral.sh/ruff/rules/suspicious-pickle-usage/ +.. _S307: https://docs.astral.sh/ruff/rules/suspicious-eval-usage/ +.. _S113: https://docs.astral.sh/ruff/rules/request-without-timeout/ +.. _S324: https://docs.astral.sh/ruff/rules/hashlib-insecure-hash-function/ +.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/ +.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/ diff --git a/docs/productive/security/pypi-changes.png b/docs/productive/security/pypi-changes.png new file mode 100644 index 00000000..7034fab2 Binary files /dev/null and b/docs/productive/security/pypi-changes.png differ diff --git a/docs/productive/security/sbom.rst b/docs/productive/security/sbom.rst index a78d6518..2d8f5242 100644 --- a/docs/productive/security/sbom.rst +++ b/docs/productive/security/sbom.rst @@ -9,14 +9,22 @@ Eine Software Bill-of-Materials (SBOM) ist ein Dokument zum Austausch von Informationen über Software und deren Zusammensetzung. Dieses Format wird vor allem im Sicherheitsbereich verwendet, um Software und ihre Abhängigkeiten mithilfe von Schwachstellendatenbanken wie `CVE `_ und -`OSV `_ auf Schwachstellen zu überprüfen. Das vom -CPython-Projekt verwendete SBOM-Format ist `SPDX +`OSV `_ auf Schwachstellen zu überprüfen. + +Das vom CPython-Projekt verwendete SBOM-Format ist `SPDX `_, das bei Bedarf in andere Formate konvertiert werden kann. Die SBOM-Datei für die in CPython enthaltenen Abhängigkeiten wird unter `Misc/sbom.spdx.json `_ verwaltet. Die Datei wird erstellt mit `Tools/build/generate_sbom.py `_. +Ihr könnt die SBOM-Datei für jede Python-Version abrufen unter +:samp:`https://www.python.org/ftp/python/{MAJOR.MINOR.PATCH}/Python-{MAJOR.MINOR.PATCH}.tgz.spdx.json`, also :abbr:`z.B. (zum Beispiel)` unter +https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz.spdx.json. + +.. seealso:: + * `Python Software Bill-of-Materials Information + `_ SBOM-Datei erstellen -------------------- diff --git a/pyproject.toml b/pyproject.toml index a4c26cae..a0cfe5f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,9 +59,9 @@ packages = [] line-length = 79 src = [ "docs", "fastAPI" ] extend-exclude = [ - "docs/productive/qa/requests/*", - "docs/workspace/ipython/examples.ipynb", # `np.*mean*?` is valid iPython syntax "docs/data-processing/apis/grpc/accounts_pb2_grpc.py", # Changing the function signature would violate the Liskov Substitution Principle + "docs/productive/qa/requests/*", + "docs/workspace/ipython/examples.ipynb", # `np.*mean*?` is valid iPython syntax ] lint.select = [ "ALL" ] lint.ignore = [