Skip to the content.
« Secure Coding Recommendations

Preventing atom exhaustion

General

Erlang

Elixir

Background

Each unique atom value in use in the virtual machine takes up an entry in the global atom table. New atom values are appended to this table as needed, but entries are never removed. The size of the table is determined at startup, based on the +t emulator flag, with a default of 1.048.576 entries. If an attempt is made to add a new value while the table is at capacity, the virtual machine crashes.

Because of the above, care should be taken to not create an unbounded number of atoms. In particular, creating atoms from untrusted input can lead to denial-of-service (DoS) vulnerabilities.

The best way to prevent atom exhaustion is by ensuring no new atom values are created at runtime: as long as any atom value required by the application is referenced in code, that value will be defined in the atom table when the code is loaded (e.g. at release startup). The conversion of other types into atoms can then be constrained to only allow existing values by using lookup tables, or when this is not practical, by using the ...to_existing_atom/1 function variants.

A lookup table is to be preferred since the ...to_existing_atom/1 function variants can still accept arbitrary input and introduce unintended atoms. Using a lookup table prevents the risk of converting unexpected or harmful values, such as an existing module name, into atoms. This method not only safeguards against atom table exhaustion but also ensures strict control over which atoms are allowed in your application.

Beware of functions in applications/libraries that create atoms from input values. For instance, the xmerl_scan XML parser that comes with Erlang/OTP generates atoms from XML tag and attribute names (see Erlang standard library: xmerl), and the http_uri:parse/1 function in the ‘inets’ application converts the URI scheme to an atom (see Erlang standard library: inets).

Consider using instrumentation to monitor the value of erlang:system_info(atom_count) relative to erlang:system_info(atom_limit), and generate an alert when the atom count continues to increase after startup or when it crosses a threshold.

Next: Serialisation and deserialisation »