DEV Community

Cover image for Checking file signature while processing stream in C#
Talles L
Talles L

Posted on

Checking file signature while processing stream in C#

While you are processing a stream, if you can read and seek on it, you can read the beginning of it, test if it has the desired signature (and maybe throw an error here), rewind it, to then do whatever you want with it.

Here’s an example of an API that takes an upload and saves it locally if (and only if) it’s a PNG:

var app = WebApplication.Create();

app.MapPost("/", (IFormFile content) =>
{
    using var stream = content.OpenReadStream();

    if (!IsPng(stream))
        throw new Exception("The given file is not a PNG.");

    using var fileStream = new FileStream(content.FileName, FileMode.Create, FileAccess.Write);

    stream.CopyTo(fileStream);
})
.DisableAntiforgery();

app.Run();

bool IsPng(Stream stream)
{
    if (!stream.CanRead)
        throw new Exception("Cannot read stream.");

    if (!stream.CanSeek)
        throw new Exception("Cannot seek stream.");

    if (stream.Position != 0)
        throw new Exception("Stream is not at the beginning.");

    var pngSignature = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A  };
    var len = pngSignature.Length;

    var streamBytes = new byte[len];
    stream.Read(streamBytes, 0, len);
    stream.Position = 0;

    return Enumerable.SequenceEqual(pngSignature, streamBytes);
}
Enter fullscreen mode Exit fullscreen mode

Just run dotnet new webapi, replace the contents of Program.cs, then run it with dotnet run. Perform a request with curl --location 'http://localhost:5108' --form 'content=@"/path/to/your/file.png"'.

If you need a compiled list of file signatures, take a look at Wikipedia list and Gary Kessler’s page.

There is also FileTypeChecker and FileSignatures libraries. Their approach is pretty similar, read, check, then rewind.

Top comments (0)