
Denial-of-Service-Schwachstelle in ecdsa (PyPI)
Denial-of-Service-Sicherheitslücke in ecdsa (PyPI)
Ich habe eine Sicherheitslücke mittleren Schweregrads in python-ecdsa identifiziert und verantwortungsvoll offengelegt – einer weit verbreiteten Python-Kryptografiebibliothek mit 47,8 Millionen Downloads im letzten Monat.
Ich fand dieses Problem, während ich python-ecdsa mit einer ganz bestimmten Frage im Hinterkopf überprüfte:
Was passiert, wenn eine fehlerhafte DER-Kodierung ihre Länge falsch angibt und der Parser ihr zu weit vertraut?
In diesem Fall führte diese Frage zu einem echten Fehler.
Die DER-Parsing-Hilfsfunktionen in ecdsa.der akzeptierten abgeschnittene Daten, wenn die kodierte Länge mehr Bytes beanspruchte, als tatsächlich vorhanden waren. Diese fehlerhafte Eingabe hätte sofort zurückgewiesen werden müssen. Stattdessen konnte sie tiefer in die Parsing-Logik vordringen und während der Schlüsselanalyse einen internen IndexError auslösen.
Dieses Problem wurde zu CVE-2026-33936.
Projekt: python-ecdsa auf GitHub
Paket: ecdsa (pip)
CVE: CVE-2026-33936
vom Angreifer kontrollierte fehlerhafte DER-Kodierung → abgeschnittene Länge als gültig akzeptiert → Parser überschreitet Vertrauensgrenze → SigningKey.from_der() erreicht internen Ausnahmepfad → unerwarteter IndexError / DoS-Risiko auf Anwendungsebene
python-ecdsa ist eine weit verbreitete Python-Bibliothek für Elliptische-Kurven-Kryptografie.
Unter anderem verarbeitet sie:
Das bedeutet, ihr Parsing-Code sitzt direkt an einer Sicherheitsgrenze.
Wenn eine Bibliothek extern bereitgestelltes Schlüsselmaterial oder strukturierte Binäreingaben akzeptiert, ist Korrektheit nicht nur eine Frage der Qualität. Sie ist eine Sicherheitseigenschaft.
Wenn fehlerhafte Eingaben akzeptiert werden, obwohl sie zurückgewiesen werden sollten, beginnt nachgelagerter Code, Annahmen auf der Grundlage ungültigen Zustands zu treffen. An diesem Punkt hören Fehler auf, „nur Parsing-Fehler“ zu sein, und werden zu Sicherheitslücken.
DER-Parsing ist einer dieser Bereiche, in denen kleine Validierungsfehler überproportionale Auswirkungen haben können.
Die Fehlerklasse ist direkt:
Genau diese Art von Grenzfehler ist es wert, in einer Sicherheitsüberprüfung betrachtet zu werden.
Ich suchte hier nicht nach seltsamem kryptografischem Verhalten. Ich suchte nach Vertrauensfehlern bei der Verarbeitung strukturierter Eingaben.
Das war der richtige Ort, um zu suchen.
Das grundlegende Problem war eine ungenügende Validierung von DER-Längenfeldern beim Parsen fehlerhafter oder abgeschnittener Eingaben.
Insbesondere akzeptierte ecdsa.der.remove_octet_string() Eingaben, bei denen die deklarierte DER-Länge die tatsächlich im Puffer verfügbaren Bytes überstieg.
Anstatt fehlerhafte DER wie diese zurückzuweisen:
40963akzeptierte die Hilfsfunktion sie und gab abgeschnittenen Inhalt als gültig zurück.
Das allein ist bereits ein Fehler.
Die stärkere Auswirkung zeigte sich jedoch nachgelagert.
Da die fehlerhafte Eingabe statt an der Grenze zurückgewiesen zu werden, akzeptiert wurde, konnte SigningKey.from_der() später einen internen Ausnahmepfad erreichen und auslösen:
IndexError: index out of bounds on dimension 1
Das ist bedeutsam, weil dies nicht die Art von Fehler ist, die ein Aufrufer bei fehlerhaften Eingaben erwartet.
Das korrekte Verhalten ist eine saubere Parsing-Ablehnung wie UnexpectedDER oder ValueError.
Die Sicherheitslücke bestand also nicht isoliert darin, „dass es einen IndexError gibt“.
Die eigentliche Sicherheitslücke war diese:
Das ist eine Fehlerkette, nicht zwei unabhängige Probleme.
Ein Parser, der fehlerhafte Eingaben zurückweist, ist keine kosmetische Verbesserung. Er ist Teil des Sicherheitsmodells.
Die wichtige Unterscheidung hier ist nicht, ob die Eingabe ungültig war. Natürlich war sie ungültig.
Die wichtige Unterscheidung ist, wie sich die Bibliothek angesichts ungültiger Eingaben verhalten hat.
Es gibt einen echten Unterschied zwischen:
Das erste ist robustes Verhalten.
Das zweite schafft ein Risiko auf Anwendungsebene, wenn Software nicht vertrauenswürdige DER parst und annimmt, dass Bibliotheksfehler innerhalb der erwarteten Ausnahmetypen bleiben.
Deshalb wurde dies korrekterweise als Sicherheitslücke eingestuft und nicht nur als Parser-Qualitätsfehler.
Ich habe zwei PoCs verwendet, da sie zwei verschiedene Teile derselben Fehlerkette demonstrierten.
Der erste PoC zeigte, dass remove_octet_string() abgeschnittene DER akzeptierte, deren deklarierte Länge den verfügbaren Puffer überstieg.
Damit wurde der grundlegende Validierungsfehler belegt:
Der zweite PoC zeigte die wichtigere nachgelagerte Auswirkung:
Fehlerhafte DER, die SigningKey.from_der() zugeführt wurde, löste vor der Korrektur deterministisch einen internen IndexError aus.
Damit wurde die sicherheitsrelevante Auswirkung belegt:
Das ist ein viel stärkeres Ergebnis als „Parser akzeptiert seltsame Bytes“.
Es zeigt Grenzfehler plus reale betriebliche Konsequenz.
Der erste PoC beweist die Grundursache.
Der zweite PoC beweist die Auswirkung.
Diese Aufteilung ist wichtig.
Viele Berichte hören auf bei:
„dieser Parser akzeptiert fehlerhafte Daten.“
Das ist nützlich, aber nicht immer ausreichend, um zu zeigen, warum der Fehler wichtig ist.
In diesem Fall war der stärkere Bericht:
Das macht die Sicherheitsgeschichte viel klarer.
Die Korrektur war minimal und korrekt.
Der Patch fügte die gleiche fehlende Sicherheitsregel hinzu, die bereits in remove_sequence() verwendet wird:
die deklarierte Länge muss in den verfügbaren Puffer passen
Diese Prüfung wurde angewendet auf:
remove_constructed()remove_implicit()remove_octet_string()Nachdem diese Bereichsprüfungen hinzugefügt wurden, wurde fehlerhafte/abgeschnittene DER sofort zurückgewiesen mit:
UnexpectedDER: Length longer than the provided buffer
Und der PoC, der zuvor IndexError ausgelöst hatte, erreichte den internen Ausnahmepfad nicht mehr.
Er scheiterte sauber während des Parsings, genau das, was von Anfang an hätte passieren sollen.