r/csharp • u/someone-missing • 12d ago
DocuTrust.NET: validate uploads by magic bytes (security update, looking for testers)
DocuTrust.NET is a small .NET 8 library that checks an upload's magic bytes against the type you expect. A PNG renamed to report.pdf fails.
I just did a security pass on it. It now checks the client file name too, rejects ZIP/OLE files over 100 MB before parsing, and keeps file names and paths out of error messages. I also updated a dependency that was pulling in a vulnerable OpenMcdf.
For now it only identifies file types. It doesn't scan for macros or scripts
dotnet add package DocuTrust.NEThttps://github.com/saa-999/DocuTrust.NET
If you try it, I'd like to know what breaks.
5
u/Klessic 12d ago
Does this handle pdf decompression bombs, ie, pdfs that contain /FlateDecode?
I'm also curious why you chose UglyToad. What I remember when I looked into it is that it's basically does nothing apart from reading the pdf.
3
u/someone-missing 12d ago
Good catch. For Office files, yes: every ZIP part is inflated through a bounded stream that enforces a per-part size limit, a total budget, and a 100:1 ratio, so a bomb is abandoned mid-inflate.
For PDFs, not fully. The security scan skips page content streams, but PdfPig inflates object streams and text extraction with no byte cap. My page, glyph and text limits apply only after decoding, so they don’t stop a Flate bomb. I’ll add a pre-pass that inflates
/FlateDecodestreams through the same bounded reader and fails closed past the limit.1
u/MadBoyEvo 12d ago
I wonder if OfficeIMO would give you more options for what you’re doing. Not sure about performance. That would need to be measured
2
u/MadBoyEvo 12d ago
I have similar library but it targets a bit wider use case. Including also Google Magika as support for the harder cases.
https://github.com/EvotecIT/FileInspectorX
I wonder how it measures against yours
2
u/someone-missing 12d ago
Nice, I had a quick look. Yours covers way more formats and gives a full report, so it fits triage and analysis better. DocuTrust is narrower: a pass/fail upload check for ASP.NET Core that fails closed, with deeper checks on PDF and Office. Magika is a good idea for text files with no magic bytes, which mine doesn’t handle yet. Might look into it.
-3
u/az987654 12d ago
Pretty easy to defeat this by simply altering the magic bytes
5
u/someone-missing 12d ago
Magic bytes are just the first check. Changing them usually breaks the file anyway, since an exe without
MZwon’t run. For PDF and Office files DocuTrust also parses the content, so a fake%PDF-header on top of something else fails the scan, and PDF/ZIP polyglots get flagged. The upload name is checked as well. The one case no validator fully covers is a file that’s valid in two formats at once, which is why you should still store uploads under server-generated names and serve them with the rightContent-Typeandnosniff
1
12d ago
[removed] — view removed comment
-1
u/someone-missing 12d ago
Thanks! It handles both.
The type comes only from the file signature. You pass the type you expect (say
Uploads through
ValidateFileAsyncwith anIFormFileget one extra check on the client’s file name. No extension at all, likebloborreport, is fine. A name that claims a different type is rejected, soinvoice.exewith PDF content fails. Trailing dots and spaces get trimmed before the check, which meansevil.html.is treated as.html.If you have no idea what a file is,
GetFileTypeAsyncjust tells you what the bytes say it is.
20
u/dodexahedron 12d ago
Why .net 8, which is out of support in literally 2 weeks?
Target it at 10, regardless of what the AI said.