Skip to content

Crash on Large Route Buffer Initialization due to Unchecked malloc in C Extension #197

@yhrscholar

Description

@yhrscholar

Description

Initializing a Matcher (C extension) with a large, valid set of route patterns can lead to process crash or resource exhaustion. The root cause is in Matcher_init (in src/japronto/router/cmatcher.c), which allocates memory for the compiled routes buffer without checking the size:

    // Extract length from Python‐generated bytes
    PyBytes_AsStringAndSize(compiled, &compiled_buffer, &buffer_len);
    // Allocate buffer_len bytes without bounds checking
    self->buffer = malloc(buffer_len);
    // Copy all bytes
    memcpy(self->buffer, compiled_buffer, buffer_len);

Since buffer_len is derived directly from user-supplied routes via compile_all(routes), an attacker can force buffer_len to be extremely large, causing malloc to fail (NULL) or succeed but consume excessive memory, leading to denial-of-service or crash.

Steps to Reproduce

from japronto.router.cmatcher import Matcher
from japronto.router.matcher  import Route

def dummy_handler(request):
    return None

huge_pattern = "/" + "A" * (1 << 30)
routes = [ Route(huge_pattern, dummy_handler, methods=[]) ]
m = Matcher(routes)

Expected Results

When malloc fails inside the C extension due to insufficient memory (triggered by the large buffer_len), the initialization should raise a Python exception.

Actual Results

The Python process either crashes with a segmentation fault or becomes unresponsive due to excessive memory allocation.

Version

commit hash: e73b76e

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions