Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-33936 — Denial of Service vulnerability in ecdsa (PyPI) | Kitploit
Tools/GitHubGitHub/0xmrma/cve-2026-33936
Vulnerability AnalysisCode AnalysisCryptographyPapers & ResearchLearning & Education
GitHub0xmrma/cve-2026-33936

CVE-2026-33936

Denial of Service vulnerability in ecdsa (PyPI)

View Repository
1126 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-33936

Denial of Service vulnerability in ecdsa (PyPI)

Intro

I identified and responsibly disclosed a Moderate-severity vulnerability in python-ecdsa, a widely used Python cryptography library with 47.8M downloads in the last month.

I found this issue while reviewing python-ecdsa with a very specific question in mind:

What happens if malformed DER lies about its length and the parser trusts it too far?

In this case, that question led to a real bug.

The DER parsing helpers in ecdsa.der accepted truncated data in cases where the encoded length claimed more bytes than were actually present. That malformed input should have been rejected immediately. Instead, it could pass deeper into parsing logic and eventually trigger an internal IndexError during key parsing.

That issue became CVE-2026-33936.

Project: python-ecdsa on GitHub
Package: ecdsa (pip)
CVE: CVE-2026-33936

photo0

Attack Chain

attacker-controlled malformed DER → truncated length accepted as valid → parser continues past trust boundary → SigningKey.from_der() reaches internal exception path → unexpected IndexError / application-level DoS risk


What python-ecdsa Does

python-ecdsa is a widely used Python library for elliptic-curve cryptography.

Among other things, it handles:

  • key parsing
  • key serialization
  • DER/ASN.1 decoding
  • signing and verification workflows

That means its parsing code sits directly on a security boundary.

Whenever a library accepts externally supplied key material or structured binary input, correctness is not just a quality issue. It is a security property.

If malformed input is accepted when it should be rejected, downstream code starts making assumptions on top of invalid state. That is where bugs stop being “just parsing mistakes” and start becoming vulnerabilities.


Why This Surface Was Worth Looking At

DER parsing is one of those areas where small validation mistakes can have outsized effects.

The bug class is straightforward:

  • length field says one thing
  • actual buffer contains something shorter
  • parser trusts the claim too far
  • later code operates on state that should never have existed

That is exactly the kind of boundary failure worth checking in security review.

I was not looking for weird cryptographic behavior here. I was looking for trust failures in structured-input handling.

That was the right place to look.


Root Cause

The root issue was improper validation of DER length fields when parsing malformed or truncated input.

Specifically, ecdsa.der.remove_octet_string() accepted input where the declared DER length exceeded the number of bytes actually available in the buffer.

So instead of rejecting malformed DER like this:

  • declared length: 4096
  • actual remaining bytes: 3

the helper accepted it and returned truncated content as if it were valid.

That is already a bug.

But the stronger impact showed up downstream.

Because malformed input was accepted instead of rejected at the boundary, SigningKey.from_der() could later reach an internal exception path and raise:

IndexError: index out of bounds on dimension 1

That matters because this is not the kind of failure a caller expects from malformed input. The correct behavior is a clean parse rejection such as UnexpectedDER or ValueError.

So the vulnerability was not “IndexError exists” in isolation.

The real vulnerability was this:

  • malformed DER length fields were not validated correctly
  • truncated input crossed the parse boundary
  • downstream code hit an internal exception path as a consequence

That is one bug chain, not two unrelated issues.


Why This Is a Security Issue, Not Just Bad Parsing Hygiene

A parser rejecting malformed input is not a cosmetic improvement. It is part of the security model.

The important distinction here is not whether the input was invalid. Of course it was invalid.

The important distinction is how the library behaved in the face of invalid input.

There is a real difference between:

  • rejecting malformed DER cleanly at the boundary, and
  • accepting malformed DER, continuing deeper, and crashing with an internal exception

The first is robust behavior.

The second creates application-level risk if software parses untrusted DER and assumes library failures stay within expected exception types.

That is why this was properly classified as a vulnerability rather than merely a parser-quality bug.


Proof of Concept

I used two PoCs because they demonstrated two different parts of the same bug chain.

PoC 1: truncated DER accepted

The first PoC showed that remove_octet_string() accepted truncated DER whose declared length exceeded the available buffer.

That established the core validation failure:

  • the buffer was shorter than the encoded length
  • the helper should have rejected it
  • it did not

PoC 2: deterministic internal exception path

The second PoC showed the more important downstream effect: malformed DER supplied to SigningKey.from_der() deterministically triggered an internal IndexError before the fix.

That established the security-relevant impact:

  • malformed input crossed the boundary
  • parsing continued too far
  • library code raised an internal exception instead of a clean parse error

That is a much stronger result than “parser accepted weird bytes.”

It shows boundary failure plus real operational consequence.


Why the PoCs Were Chosen This Way

The first PoC proves root cause.

The second PoC proves impact.

That split matters.

A lot of reports stop at:

“this parser accepts malformed data.”

That is useful, but not always enough to show why the bug matters.

In this case, the stronger report was:

  • malformed DER is wrongly accepted
  • that acceptance is not self-contained
  • it can propagate into a crashy internal exception path in key parsing

That makes the security story much clearer.


Fix Analysis

The fix was minimal and correct.

The patch added the same missing safety rule already used in remove_sequence():

the declared length must fit within the available buffer

That check was applied to:

  • remove_constructed()
  • remove_implicit()
  • remove_octet_string()

Once those bounds checks were added, malformed/truncated DER was rejected immediately with:

UnexpectedDER: Length longer than the provided buffer

And the PoC that previously triggered IndexError no longer reached the internal exception path. It failed cleanly during parsing, which is exactly what should have happened from the start.

This is the kind of fix you want to see in a parser vulnerability:

  • narrow
  • explicit
  • directly tied to the trust boundary
  • easy to reason about
  • reinforced with regression coverage

No redesign. No ambiguity. Just correct validation where it was missing.


Regression Tests

I also added focused regression tests to make sure this exact class of malformed DER stays rejected.

The new tests cover truncated-length rejection for:

  • remove_octet_string
  • remove_constructed
  • remove_implicit

That was important because the bug was not about one weird runtime path. It was about a validation rule that needed to hold consistently across related DER helpers.

After the fix and tests were added, the full suite passed locally:

python -m pytest -q
# 2018 passed, 5 skipped

That matters in real disclosure work.

A fix is much stronger when it comes with tests that lock the boundary down.


Severity and Classification

This issue was reasonably classified as Moderate.

The key impact here is availability / robustness, not confidentiality or integrity.

The advisory classification was:

Download Tool