Elixir Security: What's the impact of DoS due to atom creation?

Michael Lubas, 2023-04-05

In Elixir and Erlang, the atom is a basic type, a constant whose value is its own name. There is a hard limit on the number of atoms that can be created, the default is 1_048_576. If external user input results in atoms being created at runtime, this can cause the entire system to crash. There is an obvious question raised from all this, “If my application is vulnerable, what is the impact?”

Will your entire site go down? Could it just crash and restart? The answer depends on the environment your application is running in. The example test below is a Phoenix application running on an AWS EC2 server, using Elixir releases, with systemd.


Warning: It is recommended to perform this test in a development or staging environment that is similar to production. Do not try this in production.


1. View logs for your application

This step is so you can observe what happens during the crash.

journalctl -u parax.service -f --output cat

If you have a different logging setup, such as Gigalixir or Fly.io, use the appropriate command.

2. Connect to your running application

If you’re using Elixir releases, connecting to your running application can be done with one command:

./parax/_build/prod/rel/parax/bin/parax remote

If you have a different setup, such as Gigalixir or Fly.io, use the appropriate command.

3. Create too many atoms

In the iex shell you just created, run:

Enum.map(1..1048576, fn x -> String.to_atom(Integer.to_string(x)) end)

It will crash the application.

4. Observe results

In the journalctl terminal:

no more index entries in atom_tab (max=1048576)
Crash dump is being written to: erl_crash.dump...done
parax.service: main process exited, code=exited, status=1/FAILURE
Unit parax.service entered failed state.
parax.service failed.
parax.service holdoff time over, scheduling restart.
Stopped Parax daemon.
Started Parax daemon.
17:19:07.065 [info] Running ParaxWeb.Endpoint with cowboy 2.9.0 at 0.0.0.0:8443 (https)

In this test the application daemon is restarted successfully, and the site will continue to function normally. This is the ideal scenario, and the impact is low, although there is some downtime during the restart. With a different configuration the application may fail to restart, meaning an attacker can use this vulnerability to take the application offline. The default impact of atom DoS should still be considered high, because there is a risk of the system failing to restart.

Recommendations

1. Use Sobelow to detect code vulnerable to atom DoS.

2. Test how your application handles atom exhaustion, as described here.

3. If your application does not restart after a major crash, change the deployment environment so it can recover. This will improve overall reliability.


Paraxial.io stops data breaches by securing your Elixir and Phoenix apps. Detect and fix critical security issues today. Attending ElixirConf EU (April 17th) in Lisbon? Paraxial.io founder Michael Lubas is giving the training Elixir Application Security and will be speaking at the conference. Hope to see you there!

Subscribe to stay up to date on new posts.