AshPhoenixTranslations.LocaleValidator (ash_phoenix_translations v1.0.0)
View SourceSecure locale and field validation to prevent atom exhaustion attacks.
This module provides safe validation for user-provided locale codes and field names, ensuring that only valid, pre-defined atoms are created. This prevents denial-of-service attacks through atom table exhaustion.
Security
The BEAM VM has a fixed limit of approximately 1 million atoms. Creating atoms from untrusted user input can allow attackers to exhaust this limit and crash the VM.
This module uses whitelisting and String.to_existing_atom/1 to ensure:
- Only supported locales can be converted to atoms
- Only translatable fields can be converted to atoms
- Invalid input is rejected with proper logging
Configuration
Configure supported locales in your application config:
config :ash_phoenix_translations,
supported_locales: [:en, :es, :fr, :de, :it, :pt, :ja, :zh, :ko, :ar, :ru]Examples
# Valid locale
iex> LocaleValidator.validate_locale("en")
{:ok, :en}
# Invalid locale
iex> LocaleValidator.validate_locale("invalid")
{:error, :invalid_locale}
# Valid field for resource
iex> LocaleValidator.validate_field("name", MyApp.Product)
{:ok, :name}
# Invalid field
iex> LocaleValidator.validate_field("nonexistent", MyApp.Product)
{:error, :invalid_field}
Summary
Functions
Returns the list of supported locales.
Validates a field name against translatable attributes for a resource.
Validates a locale and returns it as an atom if valid.
Functions
Returns the list of supported locales.
Reads from application configuration, falling back to default locales.
Validates a field name against translatable attributes for a resource.
Parameters
field- The field name to validate (atom or string)resource_module- The Ash resource module to check against
Returns
{:ok, field_atom}if valid{:error, :invalid_field}if invalid
Examples
validate_field("name", MyApp.Product)
#=> {:ok, :name}
validate_field("nonexistent", MyApp.Product)
#=> {:error, :invalid_field}
Validates a locale and returns it as an atom if valid.
Accepts both atoms and strings. For strings, validates against configured supported locales and only converts to existing atoms.
Parameters
locale- The locale to validate (atom or string)
Returns
{:ok, locale_atom}if valid{:error, :invalid_locale}if invalid
Examples
validate_locale(:en)
#=> {:ok, :en}
validate_locale("es")
#=> {:ok, :es}
validate_locale("invalid")
#=> {:error, :invalid_locale}
validate_locale("<script>alert('xss')</script>")
#=> {:error, :invalid_locale}