Skip to content
Back to skills

1491 Atom Exhaustion 83bc7012

ASecurity

Atoms are never garbage collected. The VM has a limit (default ~1M atoms). Creating atoms from user input can crash the system.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentrustapi

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1491-atom-exhaustion_83bc7012 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1491 Atom Exhaustion 83bc7012?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1491 Atom Exhaustion 83bc7012
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1491-atom-exhaustion-83bc7012/badge)](https://www.skillsdirectory.com/skills/tools-only-1491-atom-exhaustion-83bc7012)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Atom Exhaustion

## The Problem

Atoms are never garbage collected. The VM has a limit (default ~1M atoms). Creating atoms from user input can crash the system.

```elixir
# VULNERABILITY - DoS via atom exhaustion
def process_field(field_name) do
  key = String.to_atom(field_name)  # Each unique input creates new atom
  Map.get(data, key)
end

# Attacker sends: field_1, field_2, ... field_1000000 -> VM crash
```

## Dangerous Functions

```elixir
# NEVER use on external input:
String.to_atom(user_input)
List.to_atom(user_input)
:erlang.binary_to_atom(user_input, :utf8)
:erlang.list_to_atom(user_input)
```

## Safe Alternatives

### String.to_existing_atom

```elixir
# Only converts to atoms that already exist
def process_field(field_name) do
  try do
    key = String.to_existing_atom(field_name)
    Map.get(data, key)
  rescue
    ArgumentError -> {:error, :invalid_field}
  end
end
```

### Whitelist Approach

```elixir
@valid_fields ~w(name email phone)a

def process_field(field_name) do
  atom = String.to_existing_atom(field_name)

  if atom in @valid_fields do
    {:ok, Map.get(data, atom)}
  else
    {:error, :invalid_field}
  end
rescue
  ArgumentError -> {:error, :invalid_field}
end
```

### Use Strings as Keys

```elixir
# SAFE - no atom creation
def process_json(json_map) do
  # JSON keys are already strings
  name = Map.get(json_map, "name")
  email = Map.get(json_map, "email")
  %{name: name, email: email}
end
```

### Atom Whitelist in Module Attribute

```elixir
defmodule API do
  @allowed_actions [:create, :read, :update, :delete]

  def dispatch(action_string) do
    action = String.to_existing_atom(action_string)

    if action in @allowed_actions do
      perform(action)
    else
      {:error, :unauthorized_action}
    end
  rescue
    ArgumentError -> {:error, :invalid_action}
  end
end
```

## Safe Contexts

Atom creation is safe when:
- Input is compile-time constant
- Input comes from trusted internal source
- Input is validated against whitelist first

```elixir
# SAFE - compile-time
@fields [:name, :email]

# SAFE - internal message
def handle_info({:internal, action}, state) when is_atom(action) do
  # action is already an atom from trusted code
end
```

## Review Questions

1. Is String.to_atom used on any external input?
2. Is there a whitelist for dynamic atom conversion?
3. Could String.to_existing_atom be used instead?
4. Would using strings as keys work instead?

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.