Static and session security fixes for Plug

Tags: #<Tag:0x00007f11491acb18> #<Tag:0x00007f11491ac7d0>


The function is NOT executed during de-serialization.

You CANNOT bypass the :only and :only_matching checks with the null byte.

I cannot provide detailed information on how to exploit the attacks for now. In a week, once we have given developers enough time to upgrade, I will be glad to answer questions.


Okay, even better. I don’t think either of the issues is really severe, both require that programmer does make some bad decisions in addition to patched issues.


pure speculation below

Attacker could alter the cookie to include serialized function, that would get de-serialized and executed during cookie de-serialization? Provided they can keep the cookie cryptographic signature at the same time.

interesting point, looking forward to hear about what can be done here in a couple weeks. I’m scared of the scalable jwt concept though so I save auth cookies in the database and only process the ones I know I’ve generated

Attacker could fetch a *.db file instead of *.ico file. Provided the secret file is somehow located in priv/static, and programmer specified :only, or :only_matching Plug.Static options. So fetching /assets/secret.db%00%favicon.ico would return secret.db file.

they could maybe upload some bash scripts and the execute them doing something as the app user

I cannot provide detailed information on how to exploit the attacks for now. In a week, once we have given developers enough time to upgrade, I will be glad to answer questions.

@josevalim please do, I’d like to know more


I think it is more likely a disallowed MIME type is sent to client. Like, you allow uploading/downloading PNG files but someone uploads a JAR file that gets automatically executed in the client’s browser.


I would encourage the Phoenix team to create a CVE for this vulnerablity if they have not already.


Is there some sort of pipe that we can subscribe to for all sorts of Elixir security releases?


Thoughts on something like gemnasium for this?


I have released Plug v1.3.3, v1.2.4, v1.1.8, v1.0.5 that also allows structs, bitstrings and improper lists to be deserialized.

Finally, when this thread is 7 days old, I will provide more information about the vulnerabilities. So if you haven’t upgraded yet, please do so.


Hi everyone,

Here is more information on the null byte issue, as reported by NCC Group:

The “static” plug, used to serve assets in Plug-based web frameworks, serves two primary functions: locating the requested file, and setting the response content type. The asset content type is set dynamically, using the Mime.from_path function. For example, a request for the file “images/phoenix.png” will result in a content type of “image/png.” However, if the request is updated to “images/phoenix.png%00.html,” the resulting content type will be set to “text/html.”

Some have mentioned the vulnerability could cause a “access control” issue, causing one user to see files permitted by other users, however I don’t believe that to be possible because:

  1. Plug.Static doesn’t provide any control access. All files are available to all users

  2. If you are implementing control access by plugging Plug.Static on an authenticated route, it is most likely that you are doing authentication based on the path prefix rather than the path suffix and any “weird character”, such as a null byte, would make authentication fail

However, it is important to mention that this vulnerability may affect you even if you don’t use null byte. A bug report has been filled on Erlang/OTP issues tracker.

I will provide more information about the other vulnerability soon.


The access control issue @josevalim mentions is something I described in this post. I agree that most sites would probably implement sharing at the directory level, but some cloud syncing services have more fine-grained access control, for example for use in an enterprise environment.

Still, even if the example is a bit obscure, the important takeaway is this: until the underlying issue in the Erlang runtime is resolved, the path you’re inspecting and the path that’s actually being read from (or written to) may differ, so any application that build paths with user input should probably implement null-byte screening.


Thank you, I couldn’t quite remember where I saw it. :slight_smile: It was also slightly referenced on this thread in regards to :only and :only_matching (which are also prefix based and therefore not vulnerable).



While I don’t believe this poises a security issue in OTP itself, I believe the platform would be safer if it raised when a string or binary with a null byte is given anytime we are interacting with the filesystem.

so you were mostly right but it is indeed a relatively minor issue :slight_smile:


The 2nd issue (cookie de-serialization) is only minor issue since Elixir/Erlang does not mix data and code into objects.

Rails had a similar issue back in a day where it would de-serialize stuff from params/cookie (don’t remember exactly) into classes. Combine that with ability to re-define classes at run time and you have remote code execution at it’s finest.


so did PHP


RE the quoted erlang bug report text:

I don’t think @josevalim intends to say that the null byte issue with Plug is minor, just that this isn’t necessarily a security issue in OTP itself.


that’s what I said, my opinion may or may not be the same as Jose’s :slight_smile:

To be precise about what I meant: the vulnerability might not be minor, but it is less severe than I thought (hence “relatively minor”).


Thanks for staying on top of this! It got me thinking…

It’d be nice to build some security vulnerability reporting features into mix & hex.

Perhaps a package author could flag a particular version as containing a vulnerability, and then when running commands like mix deps.get, we’d get a warning about that vulnerability.

I think that could help the ecosystem as a whole stay on top of security issues as Elixir grows.


Hex package versions can be retired, security issues being one of the reasons for retirement. In this instance we did not retire Plug because all versions would need to be retired and the security reason was not severe enough to require a retirement of the released versions.

I think a separate tool or service for reporting any security vulnerabilities would be great, but it should not be part of elixir core or hex.


I think it would be cool if @rrrene’s HexFaktor could be extended to be that tool!


I wrote up a quick blog post on the vulnerabilities, which you can find here. It details the more “practical” method of achieving code execution in serialization functionality, as well as PoCs for anyone who wants to experiment with these locally.