Skip to content

ASGI query parsing crashes on valueless param + no percent-decoding #34

Description

@LoboGuardian

Summary

The ASGI adapter parses the query string with k, v = kv.split("=", 1), which raises ValueError when a parameter has no = (e.g. ?debug). The exception is uncaught inside the adapter, so the request dies before the handler runs. Query and form values are also never percent-decoded.

Where

  • src/htealeaf/server/adapter/asgi.py:75-79:
args_kv = scope["query_string"].decode().split("&") if scope["query_string"] else []
args = {}
for kv in args_kv:
    k, v = kv.split("=", 1)   # ValueError on a valueless param
    args[k] = v
  • src/htealeaf/server/http/request.py:87 form() — same non-decoding split pattern.

Reproduction

curl "http://127.0.0.1:8000/?debug"      # -> 500 / dropped request
curl "http://127.0.0.1:8000/?q=a%20b"    # -> value stays "a%20b", not "a b"

Suggested fix

Reuse urllib.parse.parse_qsl (already used by the CGI adapter), which handles valueless params and percent-decoding:

from urllib.parse import parse_qsl
args = dict(parse_qsl(scope["query_string"].decode(), keep_blank_values=True))

Why it matters

A valueless query param is common and lets any client trigger a 500 on the ASGI adapter; missing percent-decoding silently corrupts input. The CGI adapter already does this correctly — the ASGI/form() paths should match. Found during a security review of develop.

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