
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.
Dies ist die Art von Korrektur, die man bei einer Parser-Sicherheitslücke sehen möchte:
Kein Redesign. Keine Unklarheit. Einfach korrekte Validierung dort, wo sie fehlte.
Ich habe ebenfalls fokussierte Regressionstests hinzugefügt, um sicherzustellen, dass diese genaue Klasse fehlerhafter DER zurückgewiesen bleibt.
Die neuen Tests decken die Zurückweisung abgeschnittener Längen ab für:
remove_octet_stringremove_constructedremove_implicitDas war wichtig, denn der Fehler betraf nicht einen seltsamen Laufzeitpfad. Es ging um eine Validierungsregel, die konsistent über verwandte DER-Hilfsfunktionen hinweg gelten musste.
Nachdem die Korrektur und die Tests hinzugefügt waren, bestand die gesamte Testsuite lokal:
python -m pytest -q
# 2018 passed, 5 skipped
Das ist in der realen Offenlegungsarbeit von Bedeutung.
Eine Korrektur ist viel stärker, wenn sie mit Tests einhergeht, die die Grenze absichern.
Dieses Problem wurde angemessen als Mittel eingestuft.
Die Hauptauswirkung betrifft hier die Verfügbarkeit/Robustheit, nicht die Vertraulichkeit oder Integrität.
Die Klassifizierung in der Beratung war:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:LDas ergibt Sinn.
Die Behauptung ist nicht, dass fehlerhafte DER einem Angreifer die Codeausführung ermöglicht. Die Behauptung ist, dass fehlerhafte DER unerwartete interne Ausnahmen in Software auslösen kann, die nicht vertrauenswürdiges DER-Material mit dieser Bibliothek parst.
Das ist ein realer und vertretbarer DoS-artiger Parsing-Fehler.
Dieses Problem wurde privat über GitHub Security Advisories gemeldet.
Der Bericht enthielt:
IndexErrorDer Betreuer validierte das Problem, forderte, dass die Korrektur mit Unit-Tests einhergeht, und die koordinierte Korrektur erfolgte über den temporären privaten Fork-Workflow der GHSA.
Während der CVE-Bearbeitung verweigerte GitHub zunächst die Zuweisung, weil der Beratungstext so aussah, als könne er mehr als eine Sicherheitslücke beschreiben. Die Klarstellung war einfach:
Dies war eine einzige Sicherheitslücke mit einer einzigen Grundursache – unzureichende DER-Längenvalidierung – und der SigningKey.from_der()-IndexError war eine nachgelagerte Konsequenz derselben Akzeptanz fehlerhafter Eingaben, nicht ein separater, unabhängig behebbarer Fehler.
Diese Klarstellung reichte aus, und das Problem wurde zugewiesen:
CVE-2026-33936
Die Lektion hier ist nicht „DER ist knifflig.“
Jeder weiß bereits, dass DER knifflig ist.
Die eigentliche Lektion ist diese:
fehlerhafte strukturierte Eingaben müssen genau an dem Punkt zurückgewiesen werden, an dem der Parser weiß, dass sie ungültig sind.
Wenn man diese Grenze verpasst, arbeitet späterer Code auf der Grundlage von Annahmen, die nicht mehr vertrauenswürdig sind.
So werden Parsing-Fehler auf niedriger Ebene zu Sicherheitsproblemen.
Dieser Fehler unterstreicht auch etwas Wichtiges über Berichte und Triage:
„Fehlerhafte Eingabe akzeptiert“ war der Anfang der Geschichte.
„Fehlerhafte Eingabe akzeptiert, dann in einen internen Ausnahmepfad während der Schlüsselanalyse fortgepflanzt“ war die vollständige Geschichte.
Diese Unterscheidung half, den Fall klar und korrekt darzulegen.
Diese Sicherheitslücke drehte sich nicht um exotische Kryptografie.
Es ging um einen Parser, der fehlerhaften Eingaben länger vertraute, als er sollte.
Ein abgeschnittenes DER-Längenfeld überquerte die Grenze, überlebte die Validierung, obwohl es hätte zurückgewiesen werden sollen, und verursachte schließlich absturzartiges Verhalten bei der Schlüsselanalyse.
Deshalb wurde dies zu CVE-2026-33936.
Behoben durch die Durchsetzung korrekter DER-Längenbereichsprüfungen in den betroffenen Hilfsparsern.
