brainlid

brainlid

Blog Post: Can Phoenix Safely use the Zip Module?

Elixir has a built-in Zip library that comes with OTP. This post explores how to use the zip module and asks the important question: “Is this safe to use with user provided zips?” We explore two different types of zip-based attacks and see what we learn from it.

Most Liked

akash-akya

akash-akya

Nice post! zip format is full of dark corners like this.

Another fun fact. Because of the way zip spec is, which is unlike other formats, zip file index is at the end. You can just append new index to delete/rename files! Without actually touching file data. Basically, you can just take the existing index, update it, and append at the end of the file, without actually modifying any of the file data. And according to spec, this is a valid file. And there are many tools that abuse this fact for various “features”. Also, that’s how most of the “recover deleted files” feature works.

IMO one way to reduce the issue surface is to avoid touching the file system altogether if you don’t need to. You can just keep them on memory if they are small, or you can stream them if you can’t fit them on memory, or extract only the file you need.

If you are automating something which requires reading from zip, then likely you already know the filenames, or structure, so you can just fetch the ones you need.

There are mainly two approach to stream files from a zip:

Since both approach use streams, and don’t write/extract anything to the file system, both are not susceptible to path traversal attack

  • read the zip from the beginning to the end. Example: zstream
    Since you can’t really reverse stream (or move to an arbitrary position), it is not susceptible to zip bomb. The code does not even need to be aware of zip bomb!

    Cons:

    • because this approach relay on local file header which is optional according to spec, you won’t be able to parse all the zip files (especially the ones which are written in a streaming way)
    • since the approach does not strictly follow the spec, you might see some of the ghost files, or duplicate files or, the files which does not show when you open zip in a GUI etc.
    • can not selectively extract a single file efficiently
  • use seek & read API - Example: unzip (full disclosure, I am the author)
    approach might be susceptible to zip-bomb, if the library is not explicitly handling it (In case of unzip I am handling it). Since this approach follows the spec, it should work with all types of zip files.

Where Next?

Popular in Blog Posts Top

jordiee
https://medium.com/@jpiepkow/team-based-login-with-accesspass-be236d4bd7dd
New
tmartin8080
Sharing some articles I’ve written recently while working in Elixir. Some are how-to guides and others for reference. Will update this ...
New
brainlid
Building a LiveView powered chat app is easier than ever when using Streams! Sophie DeBenedetto shows us how in this article. She createa...
New
AstonJ
Update: How to use the blogs section You can post in one of the Official Blog Posts threads (like this one), or, via Devtalk and a new t...
New
lawik
Building on other people’s work I bashed things together and suddenly I can know when someone is speaking using Elixir and Membrane.
New
AstonJ
Update: How to use the blogs section You can post in one of the Official Blog Posts threads (like this one), or, via Devtalk and a new t...
New
brainlid
Dialyzer is a tool that you’ve probably heard about in the Elixir community. You may have even used it. However, adding Dialyzer to an ex...
New
brainlid
OTP 26 was released and the Elixir 1.14.4 builds have been updated! Erlang OTP 26 changed how map keys are sorted, or not sorted actually...
New
rocket4ce
A comprehensive guide for deploying Phoenix 1.8 applications using Coolify on Hetzner servers. Covers server setup, Coolify configuration...
New
rms.mrcs
Hi, everyone! In this article I describe how I created a simple metrics engine that can list to Hackney metric updates and send this data...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement