Skip to content

Commit 0e819dc

Browse files
committed
📝 Extend seccurity section
1 parent 5e7df28 commit 0e819dc

7 files changed

Lines changed: 581 additions & 348 deletions

File tree

docs/productive/qa/pysa.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ Ursprung zu ihrem Endpunkt und identifiziert dabei anfälligen Code.
1313
.. seealso::
1414
* `What Is Taint Analysis and Why Should I Care?
1515
<https://dzone.com/articles/what-is-taint-analysis-and-why-should-i-care>`_
16-
* `How Pysa works <https://pyre-check.org/docs/pysa-basics>`_
16+
* `How Pysa works <https://pyre-check.org/docs/pysa-basics/>`_
1717
* `Running Pysa <https://pyre-check.org/docs/pysa-running/>`_
1818
* `Pysa Tutorial
19-
<https://github.com/facebook/pyre-check/tree/main/documentation/pysa_tutorial>`_
19+
<https://github.com/facebook/Pysa/tree/main/documentation/pysa_tutorial>`_
2020

2121
Konfiguration
2222
-------------

docs/productive/security/dependencies.rst

Lines changed: 363 additions & 312 deletions
Large diffs are not rendered by default.

docs/productive/security/environments.rst

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ die Entwicklungsumgebung enthält alle Abhängigkeiten.
5454
So wie eure Python-Umgebung mit unveränderbaren Referenzen aktuell gehalten
5555
werden sollte, sollten auch eure
5656
:doc:`../git/advanced/hooks/checks` und GitHub Actions regelmäßig aktualisiert
57-
werdenn.
57+
werden.
5858

5959
In der :file:`.pre-commit-config.yaml` sollten die Versionen der Checks mit
6060
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
6868
.. seealso::
6969
:doc:`../git/advanced/hooks/prek`
7070

71-
GitHub Actions könnt ihr `pinact <https://github.com/suzuki-shunsuke/pinact>`_
72-
verwenden, :abbr:`z. B. (zum Beispiel)` mit:
71+
.. _pinact:
72+
73+
Überprüft eure GitHub-Actions
74+
-----------------------------
75+
76+
Für GitHub Actions könnt ihr `pinact
77+
<https://github.com/suzuki-shunsuke/pinact>`_ verwenden, :abbr:`z. B. (zum
78+
Beispiel)` mit:
7379

7480
.. code-block:: console
7581
7682
$ pinact run -u --min-age 7
7783
78-
Überprüft eure GitHub-Actions
79-
-----------------------------
84+
`zizmor <https://docs.zizmor.sh>`_ ist ein Tool zur statischen Analyse, das
85+
Sicherheitslücken in GitHub-Actions-Workflows aufspürt – darunter
86+
Template-Injection, nicht fixierte Aktionen, übermäßige Berechtigungen, das
87+
Offenlegen von Anmeldedaten sowie `mehr als 30 weitere Prüfregeln
88+
<https://docs.zizmor.sh/audits/>`_. ``zizmor`` erkennt Schwachstellen wie
89+
diejenigen, die durch :ref:`token_exfiltration` ausgenutzt wurden.
8090

81-
:ref:`zizmorcore` ist ein Tool zur statischen Analyse, das Sicherheitslücken in
82-
GitHub-Actions-Workflows aufspürt – darunter Template-Injection, nicht fixierte
83-
Aktionen, übermäßige Berechtigungen, das Offenlegen von Anmeldedaten sowie `mehr
84-
als 30 weitere Prüfregeln <https://docs.zizmor.sh/audits/>`_. ``zizmor`` erkennt
85-
Schwachstellen wie diejenigen, die durch :ref:`token_exfiltration` ausgenutzt
86-
wurden.
91+
.. seealso::
92+
* :ref:`zizmorcore`

docs/productive/security/index.rst

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,18 @@ Phishing-Angriff per E-Mail auf PyPI-User
5555
`PyPI Users Email Phishing Attack
5656
<https://blog.pypi.org/posts/2025-07-28-pypi-phishing-attack/>`_
5757

58-
ZIP-Parser-Verwirrungsangriffe
59-
Im August 2025 führte :term:`PyPI` Restriktionen ein, die verhindern sollen,
60-
dass es bei Installations- und Prüfprogramme für Python-Pakete durch
61-
unterschiedliche Implementierungen des ZIP-Parsers zu Verwechslungen kommen
62-
kann. :term:`uv` zeigte ein anderes Entpackungsverhalten als viele
63-
Python-basierte Installationsprogramme, die :mod:`zipfile` verwenden.
58+
Shai-Hulud
59+
Im November 2025 entwickelt sich ein Angriff auf das `npm
60+
<https://www.npmjs.com/>`_-Ökosystem weiter und nutzt kompromittierte Konten
61+
aus, um schädliche Pakete zu veröffentlichen. Diese als *Shai-Hulud*
62+
bezeichnete Kampagne hat eine große Anzahl von JavaScript-Paketen ins Visier
63+
genommen und Zugangsdaten abgezogen, um sich weiter zu verbreiten.
64+
:term:`PyPI` selbst wurde zwar nicht ausgenutzt, jedoch wurden einige
65+
PyPI-Anmeldedaten in kompromittierten Repositories offengelegt.
6466

6567
.. seealso::
66-
`uv security advisory: ZIP payload obfuscation
67-
<https://astral.sh/blog/uv-security-advisory-cve-2025-54368>`_
68+
`PyPI and Shai-Hulud: Staying Secure Amid Emerging Threats
69+
<https://blog.pypi.org/posts/2025-11-26-pypi-and-shai-hulud/>`_
6870

6971
.. _token_exfiltration:
7072

@@ -79,6 +81,19 @@ Token Exfiltration
7981
`Token Exfiltration Campaign via GitHub Actions Workflows
8082
<https://blog.pypi.org/posts/2025-09-16-github-actions-token-exfiltration/>`_
8183

84+
ZIP-Parser-Verwirrungsangriffe
85+
Im August 2025 führte :term:`PyPI` Restriktionen ein, die verhindern sollen,
86+
dass es bei Installations- und Prüfprogramme für Python-Pakete durch
87+
unterschiedliche Implementierungen des ZIP-Parsers zu Verwechslungen kommen
88+
kann. :term:`uv` zeigte ein anderes Entpackungsverhalten als viele
89+
Python-basierte Installationsprogramme, die :mod:`zipfile` verwenden.
90+
91+
.. seealso::
92+
`uv security advisory: ZIP payload obfuscation
93+
<https://astral.sh/blog/uv-security-advisory-cve-2025-54368>`_
94+
95+
.. _ultralytics:
96+
8297
Ultralytics
8398
Im Dezember 2024 wurde `ultralytics
8499
<https://pypi.org/project/ultralytics/>`_ Opfer eines Supply-Chain-Angriffs,
@@ -90,19 +105,6 @@ Ultralytics
90105
`Supply-chain attack analysis: Ultralytics
91106
<https://blog.pypi.org/posts/2024-12-11-ultralytics-attack-analysis/>`_
92107

93-
Shai-Hulud
94-
Im November 2025 entwickelt sich ein Angriff auf das `npm
95-
<https://www.npmjs.com/>`_-Ökosystem weiter und nutzt kompromittierte Konten
96-
aus, um schädliche Pakete zu veröffentlichen. Diese als *Shai-Hulud*
97-
bezeichnete Kampagne hat eine große Anzahl von JavaScript-Paketen ins Visier
98-
genommen und Zugangsdaten abgezogen, um sich weiter zu verbreiten.
99-
:term:`PyPI` selbst wurde zwar nicht ausgenutzt, jedoch wurden einige
100-
PyPI-Anmeldedaten in kompromittierten Repositoriess offengelegt.
101-
102-
.. seealso::
103-
`PyPI and Shai-Hulud: Staying Secure Amid Emerging Threats
104-
<https://blog.pypi.org/posts/2025-11-26-pypi-and-shai-hulud/>`_
105-
106108
Das sind keine theoretischen Angriffe. Sie haben sich bei echten Projekten mit
107109
Millionen von Nutzer*innen ereignet. Wenn ihr ein bösartiges Paket auf PyPI
108110
entdeckt, könnt ihr es über das `Sicherheitsmeldesystem von PyPI
@@ -137,6 +139,7 @@ seit Juli 2024 erstellten Berichte zu GitHub-Sicherheitshinweisen:
137139
:titlesonly:
138140
:maxdepth: 0
139141

142+
own-code
140143
dependencies
141144
environments
142145
sbom
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
.. SPDX-FileCopyrightText: 2023 cusy GmbH
2+
..
3+
.. SPDX-License-Identifier: BSD-3-Clause
4+
5+
Eigener Code
6+
============
7+
8+
Angriffe auf die Lieferkette gehen nicht nur von :doc:`dependencies` aus, auch
9+
euer eigener Code kann Angriffspunkte liefern. Ein fest im Quellcode
10+
hinterlegtes PyPI-Token liefert, sobald es in ein öffentliches Repository
11+
hochgeladen wurde, alles, was für einem Angriff benötigt wird und euer Konto zu
12+
kompromittieren und bösartige Pakete unter eurem Namen zu veröffentlichen.
13+
Abgesehen von Secrets verbergen sich häufige Sicherheitsfehler in alltäglichen
14+
Codemustern, die bei einem Code-Review zunächst unbedenklich erscheinen und von
15+
Menschen übersehen werden können. Diese mit einem Linter aufzuspüren, ist die
16+
erste Verteidigungsstufe.
17+
18+
Das ewige Geheimnis
19+
-------------------
20+
21+
Durchgesickerte Zugangsdaten sind der Ausgangspunkt für viele
22+
Sicherheitsverletzungen in der Lieferkette. Ein offengelegtes :term:`PyPI`-Token
23+
ermöglicht, mit Hintertüren versehene Versionen eurer Pakete zu veröffentlichen.
24+
Eine offengelegte Datenbank-URL ermöglicht, Daten zu entwenden. Und doch ist ein
25+
solches Muster weit verbreitet. Besser ist die Verwendung von
26+
Umgebungsvariablen:
27+
28+
.. code-block:: python
29+
30+
import os
31+
32+
DATABASE_KEY = os.environ["DB_KEY"]
33+
DATABASE_URL = os.environ["DB_URL"]
34+
35+
.. warning::
36+
Git vergisst nie: wenn ihr ein Secret einmal durch Git verwaltet habt, bleibt
37+
es für immer in der Historie eures Repositories erhalten. Es in einem
38+
späteren Commit einfach zu löschen, hilft nicht wirklich. Alle, die Zugriff
39+
auf das Repository haben, können diese Anmeldedaten wieder extrahieren. Bei
40+
Angriffen wird oft zunächst die Git-Historie nach Geheimnissen durchforstet,
41+
und ein einmal veröffentlichts PyPI-Token oder Cloud-Anmeldedaten sind oft
42+
der erste Schritt bei einer Kompromittierung der Lieferkette.
43+
44+
Kryptografische Schwachstellen
45+
------------------------------
46+
47+
Weitere häufige Sicherheitslücken sind kryptografische Schwachstellen wie
48+
`MD5 <https://de.wikipedia.org/wiki/Message-Digest_Algorithm_5>`_ und `SHA-1
49+
<https://de.wikipedia.org/wiki/Secure_Hash_Algorithm#SHA-1>`_. MD5-Kollisionen
50+
wurden erstmals 2004 nachgewiesen und SHA1-Kollisionen 2017. Es können also
51+
Kollisionen erzeugt werden durch andere Eingaben, die denselben Hash-Wert
52+
ergeben. Dies ermöglicht die Fälschung von Zertifikaten, die Manipulation von
53+
Downloads oder die Umgehung von Integritätsprüfungen. Verwendet daher keines der
54+
beiden Verfahren für Sicherheitszwecke sondern stattdessen `SHA256 oder besser
55+
<https://de.wikipedia.org/wiki/SHA-2>`_:
56+
57+
.. code-block:: python
58+
59+
import hashlib
60+
61+
digest = hashlib.sha256(payload).hexdigest()
62+
63+
Hängende Verbindungen
64+
---------------------
65+
66+
Das hier ist zwar subtil, aber dennoch gefährlich, da ein langsamer Server
67+
euren Prozess auf unbestimmte Zeit zum Stillstand bringen kann. Ein Angriff über
68+
einen solchen Server, mit dem eure Anwendung kommuniziert, kann jede Anfrage zum
69+
Erliegen bringen, euren Thread-Pool erschöpfen und einen
70+
Denial-of-Service-Angriff auslösen. Eure gesamte Anwendung kommt dann zum
71+
Stillstand, weil ihr einen Parameter vergessen habt. Daher solltet ihr immer
72+
einen Timeout angeben:
73+
74+
.. code-block:: pycon
75+
76+
>>> import httpx
77+
>>> r = httpx.get("https://httpbin.org/get", timeout=30)
78+
httpx.ReadTimeout: The read operation timed out
79+
80+
.. _bandit:
81+
82+
Erkennt Sicherheitslücken mit Ruff
83+
----------------------------------
84+
85+
:doc:`../qa/ruff` ist ein schneller Python-Linter, der umfassende
86+
Sicherheitsregeln von :ref:`Bandit <bandit>` enthält:
87+
88+
.. code-block:: console
89+
90+
$ uvx ruff check --select S .
91+
92+
.. seealso::
93+
Weitere Informationen findet ihr in der `Dokumentation zu den
94+
Ruff-Sicherheitsregeln
95+
<https://docs.astral.sh/ruff/rules/#flake8-bandit-s>`_.
96+
97+
Für zukünftige Checks könnt ihr ``ruff`` ihn in der :file:`pyproject.toml`-Datei
98+
konfigurieren:
99+
100+
.. code-block:: toml
101+
102+
[tool.ruff]
103+
lint.select = ["S"]
104+
105+
Die Sicherheitsregeln ``["S"]`` mit den Bandit-Prüfungen.spüren fest codierte
106+
Geheimnisse, schwache Verschlüsselung und unsichere Deserialisierung auf. Dabei
107+
läuft Ruff in weniger als einer Sekunde, sodass ihr es während der Eingabe in
108+
eurer IDE und vor jedem Commit ausführen könnt. Alle drei oben genannten
109+
Schwachstellen werden erkannt und noch viel mehr, :abbr:`u. a. (unter anderem)`:
110+
111+
+--------+-----------------------------------------------------------------------+
112+
| Regel | Beschreibung |
113+
+--------+-----------------------------------------------------------------------+
114+
| `S105`_| fest codierte Geheimnisse |
115+
+--------+-----------------------------------------------------------------------+
116+
| `S301`_| :doc:`/data-processing/serialisation-formats/pickle/index` und andere |
117+
| | unsichere Deserialisierung |
118+
+--------+-----------------------------------------------------------------------+
119+
| `S307`_| Verwendung von :func:`eval` mit nicht vertrauenswürdigen Eingaben |
120+
+--------+-----------------------------------------------------------------------+
121+
| `S113`_| fehlende Zeitüberschreitungen |
122+
+--------+-----------------------------------------------------------------------+
123+
| `S324`_| schwache Kryptografie wie :abbr:`z. B. (zum Beispiel)` MD5-Kollisionen|
124+
+--------+-----------------------------------------------------------------------+
125+
| `S608`_| SQL-Injection über String-Formatierung |
126+
+--------+-----------------------------------------------------------------------+
127+
128+
.. seealso::
129+
* `flake8-bandit (S) <https://docs.astral.sh/ruff/rules/#flake8-bandit-s>`_
130+
* `lint.flake8-bandit
131+
<https://docs.astral.sh/ruff/settings/#lintflake8-bandit>`_
132+
133+
Bandit könnt ihr auch in Jupyter Notebooks, :abbr:`IDEs (Integrated Development
134+
Wnvironments)` und :doc:`../git/advanced/hooks/prek` integrieren.
135+
136+
Zudem könnt ihr :doc:`../qa/pysa` für `Taint
137+
<https://en.wikipedia.org/wiki/Taint_checking>`_-Analysen verwenden.
138+
139+
Für GitHub-Repositories könnt ihr alternativ auch `CodeQL
140+
<https://codeql.github.com>`_ verwenden; :abbr:`s.a. (siehe auch)`
141+
`codeql-action
142+
<https://github.com/github/codeql-action/blob/main/README.md#usage>`_.
143+
144+
Vertrauenswürdige Veröffentlichung
145+
----------------------------------
146+
147+
In einem früheren Abschnitt haben wir schon einige Hinweise gegeben, wie die
148+
Veröffentlichung von Python-Paketen auf :term:`PyPI` abgesichert werden kann:
149+
150+
.. seealso::
151+
* :ref:`secure-release-workflow`
152+
* :ref:`add_2fa`
153+
154+
.. seealso::
155+
* `Publishing package distribution releases using GitHub Actions CI/CD
156+
workflows
157+
<https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/>`_
158+
159+
.. _S105: https://docs.astral.sh/ruff/rules/hardcoded-password-string/
160+
.. _S301: https://docs.astral.sh/ruff/rules/suspicious-pickle-usage/
161+
.. _S307: https://docs.astral.sh/ruff/rules/suspicious-eval-usage/
162+
.. _S113: https://docs.astral.sh/ruff/rules/request-without-timeout/
163+
.. _S324: https://docs.astral.sh/ruff/rules/hashlib-insecure-hash-function/
164+
.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/
165+
.. _S608: https://docs.astral.sh/ruff/rules/hardcoded-sql-expression/
302 KB
Loading

docs/productive/security/sbom.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,22 @@ Eine Software Bill-of-Materials (SBOM) ist ein Dokument zum Austausch von
99
Informationen über Software und deren Zusammensetzung. Dieses Format wird vor
1010
allem im Sicherheitsbereich verwendet, um Software und ihre Abhängigkeiten
1111
mithilfe von Schwachstellendatenbanken wie `CVE <https://www.cve.org/>`_ und
12-
`OSV <https://osv.dev/>`_ auf Schwachstellen zu überprüfen. Das vom
13-
CPython-Projekt verwendete SBOM-Format ist `SPDX
12+
`OSV <https://osv.dev/>`_ auf Schwachstellen zu überprüfen.
13+
14+
Das vom CPython-Projekt verwendete SBOM-Format ist `SPDX
1415
<https://spdx.github.io/spdx-spec/v3.0.1/model/Software/Classes/Sbom/>`_, das
1516
bei Bedarf in andere Formate konvertiert werden kann. Die SBOM-Datei für die in
1617
CPython enthaltenen Abhängigkeiten wird unter `Misc/sbom.spdx.json
1718
<https://github.com/python/cpython/blob/main/Misc/sbom.spdx.json>`_ verwaltet.
1819
Die Datei wird erstellt mit `Tools/build/generate_sbom.py
1920
<https://github.com/python/cpython/blob/main/Tools/build/generate_sbom.py>`_.
21+
Ihr könnt die SBOM-Datei für jede Python-Version abrufen unter
22+
:samp:`https://www.python.org/ftp/python/{MAJOR.MINOR.PATCH}/Python-{MAJOR.MINOR.PATCH}.tgz.spdx.json`, also :abbr:`z.B. (zum Beispiel)` unter
23+
https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz.spdx.json.
24+
25+
.. seealso::
26+
* `Python Software Bill-of-Materials Information
27+
<https://www.python.org/downloads/metadata/sbom/>`_
2028

2129
SBOM-Datei erstellen
2230
--------------------

0 commit comments

Comments
 (0)