Class: Dandruff::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/dandruff/config.rb

Overview

Configuration class for the Dandruff sanitizer

This class manages all configuration options for customizing HTML sanitization behavior. It provides sensible security-focused defaults and allows fine-grained control through numerous configuration options. Configuration can be set during initialization or modified later through accessor methods.

Examples:

Basic configuration

config = Dandruff::Config.new(
  allowed_tags: ['p', 'strong', 'em'],
  allowed_attributes: ['class', 'href']
)

Using profiles

config = Dandruff::Config.new(use_profiles: { html: true, svg: true })

Block configuration

dandruff = Dandruff.new do |config|
  config.allowed_tags = ['p', 'a']
  config.forbidden_attributes = ['onclick']
end

See Also:

Constant Summary collapse

CONFIG_MAPPING =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Configuration key normalization mapping

Maps configuration hash keys (including legacy aliases) to their corresponding setter methods. This allows flexible configuration key naming while maintaining backward compatibility with older key names.

Keys are normalized to lowercase before lookup, so configuration is case-insensitive.

Examples:

Using different key styles

Config.new(allowed_tags: ['p'])           # Modern style
Config.new('allowed_tags' => ['p'])       # String keys
Config.new(add_tags: ['custom'])          # Legacy alias
{
  'add_tags' => :additional_tags=, # backward compatibility
  'additional_tags' => :additional_tags=,
  'add_attr' => :additional_attributes=, # backward compatibility
  'additional_attributes' => :additional_attributes=,
  'add_attributes' => :additional_attributes=, # backward compatibility
  'add_uri_safe_attr' => :additional_uri_safe_attributes=, # backward compatibility
  'additional_uri_safe_attributes' => :additional_uri_safe_attributes=,
  'add_uri_safe_attributes' => :additional_uri_safe_attributes=, # backward compatibility
  'allowed_tags' => :allowed_tags=,
  'allowed_attr' => :allowed_attributes=, # backward compatibility
  'allowed_attributes' => :allowed_attributes=,
  'allowed_attributes_per_tag' => :allowed_attributes_per_tag=,
  'forbidden_tags' => :forbidden_tags=,
  'forbid_tags' => :forbidden_tags=, # backward compatibility
  'forbidden_attr' => :forbidden_attributes=, # backward compatibility
  'forbidden_attributes' => :forbidden_attributes=,
  'forbid_attributes' => :forbidden_attributes=, # backward compatibility
  'allow_data_uri' => :allow_data_uri=,
  'allow_aria_attr' => :allow_aria_attributes=,  # backward compatibility
  'allow_aria_attributes' => :allow_aria_attributes=,
  'allow_data_attr' => :allow_data_attributes=,  # backward compatibility
  'allow_data_attributes' => :allow_data_attributes=,
  'allow_self_close_in_attr' => :allow_self_close_in_attributes=, # backward compatibility
  'allow_self_close_in_attributes' => :allow_self_close_in_attributes=,
  'allow_style_tags' => :allow_style_tags=,
  'allow_document_elements' => :allow_document_elements=,
  'minimal_profile' => :minimal_profile=,
  'pass_limit' => :mutation_max_passes=
}.freeze
HTML_EMAIL_ATTRIBUTES =

Per-tag attribute restrictions for HTML email profile

Defines which attributes are allowed on specific tags when using the html_email profile. This provides fine-grained security control by limiting each tag to only its appropriate attributes, preventing attribute confusion attacks where dangerous attributes appear on unexpected tags.

**Security rationale:** Email clients have inconsistent rendering behavior, and allowing arbitrary attributes on any tag can lead to security issues. For example, allowing ‘href’ on ‘img’ tags or ‘src’ on ‘a’ tags could enable attacks. Per-tag restrictions prevent this.

Usage: This constant is automatically used when ‘use_profiles: { html_email: true }` is configured. You can also use it as a template for your own per-tag attribute rules.

Examples:

Using email profile

config = Config.new(use_profiles: { html_email: true })
# Automatically uses HTML_EMAIL_ATTRIBUTES for per-tag control

Custom per-tag attributes

config.allowed_attributes_per_tag = {
  'a' => ['href', 'title'],
  'img' => ['src', 'alt', 'width', 'height']
}

See Also:

{
  # Document structure
  'body' => %w[bgcolor text link vlink alink background style class id leftmargin topmargin marginwidth
    marginheight],
  'html' => %w[lang dir xmlns],
  'head' => [],
  'meta' => %w[name content charset],
  'title' => [],
  'style' => %w[type],

  # Table elements (core of email layouts)
  'table' => %w[width height border cellpadding cellspacing align bgcolor background style class id role summary],
  'thead' => %w[align class id style dir lang title],
  'tbody' => %w[align class id style dir lang title],
  'tfoot' => %w[align class id style dir lang title],
  'tr' => %w[height bgcolor background valign align style class id],
  'td' => %w[width height colspan rowspan align valign bgcolor background style class id headers scope],
  'th' => %w[width height colspan rowspan align valign bgcolor background style class id headers scope],

  # Legacy presentation elements
  'font' => %w[face size color style],
  'center' => %w[align class id style dir lang title],

  # Links and media
  'a' => %w[href target title class id style name rel],
  'img' => %w[src alt width height border align style class id],

  # Headings
  'h1' => %w[align class id style dir lang title],
  'h2' => %w[align class id style dir lang title],
  'h3' => %w[align class id style dir lang title],
  'h4' => %w[align class id style dir lang title],
  'h5' => %w[align class id style dir lang title],
  'h6' => %w[align class id style dir lang title],

  # Block elements
  'p' => %w[align class id style dir lang title],
  'div' => %w[align class id style dir lang title],
  'span' => %w[align class id style dir lang title],
  'blockquote' => %w[align class id style dir lang title cite],
  'pre' => %w[align class id style dir lang title],
  'code' => %w[align class id style dir lang title],

  # Lists
  'ul' => %w[align class id style dir lang title type],
  'ol' => %w[align class id style dir lang title type start],
  'li' => %w[align class id style dir lang title value],

  # Inline formatting
  'strong' => %w[align class id style dir lang title],
  'em' => %w[align class id style dir lang title],
  'b' => %w[align class id style dir lang title],
  'i' => %w[align class id style dir lang title],
  'u' => %w[align class id style dir lang title],
  's' => %w[align class id style dir lang title],
  'strike' => %w[align class id style dir lang title],
  'sup' => %w[align class id style dir lang title],
  'sub' => %w[align class id style dir lang title],
  'small' => %w[align class id style dir lang title],
  'big' => %w[align class id style dir lang title],
  'mark' => %w[align class id style dir lang title],
  'del' => %w[align class id style dir lang title cite datetime],
  'ins' => %w[align class id style dir lang title cite datetime],

  # Empty elements
  'br' => %w[class style],
  'hr' => %w[align class id style dir lang title width size noshade]
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cfg = {}) ⇒ Config

Initializes a new configuration instance

Parameters:

  • cfg (Hash) (defaults to: {})

    configuration options to apply



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/dandruff/config.rb', line 196

def initialize(cfg = {})
  # Attribute defaults
  @allow_aria_attributes = true   # permit aria-* attributes
  @allow_data_attributes = true   # permit data-* attributes
  @allow_self_close_in_attributes = true

  # URI/protocol defaults
  @allow_data_uri = true              # allow data URIs for safe elements by default
  @allow_unknown_protocols = false    # block unknown protocols by default

  # Output / parsing defaults
  @safe_for_templates = false
  @safe_for_xml = true
  @whole_document = false
  @allow_document_elements = false
  @force_body = false
  @return_dom = false
  @return_dom_fragment = false

  # Sanitization controls
  @sanitize_dom = true            # DOM clobbering protection enabled
  @sanitize_named_props = false
  @sanitize_until_stable = true   # run multiple passes to deter mXSS
  @mutation_max_passes = 2        # conservative default pass limit
  @keep_content = true
  @in_place = false
  @minimal_profile = false
  @allow_style_tags = true

  # Profiles / namespaces
  @use_profiles = {}
  @namespace = 'http://www.w3.org/1999/xhtml'
  @parser_media_type = 'text/html'

  # Tag/attribute allow/forbid defaults
  @forbidden_tags = %w[base link meta annotation-xml noscript]

  @allowed_attributes = nil

  apply_config(cfg)
  process_profiles unless @use_profiles.empty?
end

Instance Attribute Details

#add_attributesObject

Returns the value of attribute add_attributes.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def add_attributes
  @add_attributes
end

#add_data_uri_tagsObject

Returns the value of attribute add_data_uri_tags.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def add_data_uri_tags
  @add_data_uri_tags
end

#add_forbid_contentsObject

Returns the value of attribute add_forbid_contents.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def add_forbid_contents
  @add_forbid_contents
end

#add_uri_safe_attributesObject

Returns the value of attribute add_uri_safe_attributes.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def add_uri_safe_attributes
  @add_uri_safe_attributes
end

#additional_attributesObject

Returns the value of attribute additional_attributes.



# File 'lib/dandruff/config.rb', line 28

#additional_tagsObject

Returns the value of attribute additional_tags.



# File 'lib/dandruff/config.rb', line 34

#additional_uri_safe_attributesObject

Returns the value of attribute additional_uri_safe_attributes.



# File 'lib/dandruff/config.rb', line 40

#allow_aria_attributesObject

Returns the value of attribute allow_aria_attributes.



# File 'lib/dandruff/config.rb', line 46

#allow_data_attributesObject

Returns the value of attribute allow_data_attributes.



# File 'lib/dandruff/config.rb', line 50

#allow_data_uriObject

Returns the value of attribute allow_data_uri.



# File 'lib/dandruff/config.rb', line 54

#allow_document_elementsObject

Returns the value of attribute allow_document_elements.



# File 'lib/dandruff/config.rb', line 112

#allow_self_close_in_attributesObject

Returns the value of attribute allow_self_close_in_attributes.



# File 'lib/dandruff/config.rb', line 64

#allow_style_tagsObject

Returns the value of attribute allow_style_tags.



# File 'lib/dandruff/config.rb', line 107

#allow_unknown_protocolsObject

Returns the value of attribute allow_unknown_protocols.



# File 'lib/dandruff/config.rb', line 59

#allowed_attributesObject

Returns the value of attribute allowed_attributes.



# File 'lib/dandruff/config.rb', line 68

#allowed_attributes_per_tagObject

Returns the value of attribute allowed_attributes_per_tag.



# File 'lib/dandruff/config.rb', line 74

#allowed_namespacesObject

Returns the value of attribute allowed_namespaces.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def allowed_namespaces
  @allowed_namespaces
end

#allowed_tagsObject

Returns the value of attribute allowed_tags.



# File 'lib/dandruff/config.rb', line 83

#allowed_uri_regexpObject

Returns the value of attribute allowed_uri_regexp.



# File 'lib/dandruff/config.rb', line 89

#custom_element_handlingObject

Returns the value of attribute custom_element_handling.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def custom_element_handling
  @custom_element_handling
end

#forbid_attributesObject

Returns the value of attribute forbid_attributes.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def forbid_attributes
  @forbid_attributes
end

#forbid_contentsObject

Returns the value of attribute forbid_contents.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def forbid_contents
  @forbid_contents
end

#forbidden_attributesObject

Returns the value of attribute forbidden_attributes.



# File 'lib/dandruff/config.rb', line 95

#forbidden_tagsObject

Returns the value of attribute forbidden_tags.



# File 'lib/dandruff/config.rb', line 101

#force_bodyObject

Returns the value of attribute force_body.



# File 'lib/dandruff/config.rb', line 172

#html_integration_pointsObject

Returns the value of attribute html_integration_points.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def html_integration_points
  @html_integration_points
end

#in_placeBoolean

Attempt to sanitize in place (experimental)

Returns:

  • (Boolean)

    (default: false)



180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/dandruff/config.rb', line 180

attr_accessor :additional_attributes, :add_attributes, :add_data_uri_tags,
:additional_tags, :additional_uri_safe_attributes, :add_uri_safe_attributes,
:allow_aria_attributes, :allow_data_attributes, :allow_data_uri, :allow_unknown_protocols,
:allow_self_close_in_attributes, :allowed_attributes, :allowed_attributes_per_tag, :allowed_tags,
:allowed_namespaces, :allowed_uri_regexp, :custom_element_handling,
:forbidden_attributes, :forbid_attributes, :forbid_contents, :add_forbid_contents, :forbidden_tags,
:force_body, :html_integration_points, :in_place, :keep_content,
:mathml_text_integration_points, :namespace, :parser_media_type,
:return_dom_fragment, :return_dom,
:safe_for_templates, :safe_for_xml, :sanitize_dom, :sanitize_until_stable, :mutation_max_passes,
:sanitize_named_props, :trusted_types_policy, :allow_style_tags, :minimal_profile,
:whole_document, :allow_document_elements

#keep_contentObject

Returns the value of attribute keep_content.



# File 'lib/dandruff/config.rb', line 116

#mathml_text_integration_pointsObject

Returns the value of attribute mathml_text_integration_points.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def mathml_text_integration_points
  @mathml_text_integration_points
end

#minimal_profileObject

Returns the value of attribute minimal_profile.



# File 'lib/dandruff/config.rb', line 168

#mutation_max_passesObject

Returns the value of attribute mutation_max_passes.



# File 'lib/dandruff/config.rb', line 155

#namespaceObject

Returns the value of attribute namespace.



# File 'lib/dandruff/config.rb', line 160

#parser_media_typeObject

Returns the value of attribute parser_media_type.



# File 'lib/dandruff/config.rb', line 164

#return_domObject

Returns the value of attribute return_dom.



# File 'lib/dandruff/config.rb', line 125

#return_dom_fragmentObject

Returns the value of attribute return_dom_fragment.



# File 'lib/dandruff/config.rb', line 129

#safe_for_templatesObject

Returns the value of attribute safe_for_templates.



# File 'lib/dandruff/config.rb', line 137

#safe_for_xmlObject

Returns the value of attribute safe_for_xml.



# File 'lib/dandruff/config.rb', line 141

#sanitize_domObject

Returns the value of attribute sanitize_dom.



# File 'lib/dandruff/config.rb', line 145

#sanitize_named_propsObject

Returns the value of attribute sanitize_named_props.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def sanitize_named_props
  @sanitize_named_props
end

#sanitize_until_stableObject

Returns the value of attribute sanitize_until_stable.



# File 'lib/dandruff/config.rb', line 150

#trusted_types_policyObject

Returns the value of attribute trusted_types_policy.



180
181
182
# File 'lib/dandruff/config.rb', line 180

def trusted_types_policy
  @trusted_types_policy
end

#whole_documentObject

Returns the value of attribute whole_document.



# File 'lib/dandruff/config.rb', line 133

Instance Method Details

#use_profiles=(profiles) ⇒ Hash

Note:

Setting profiles resets allowed_tags and allowed_attributes to nil, allowing the profile configuration to take effect

Sets content type profiles and rebuilds configuration

Profiles are pre-configured sets of tags and attributes for common content types. When you set profiles, the configuration automatically enables the appropriate tags, attributes, and security settings for those content types.

**Available profiles:**

  • :html - Standard HTML5 content

  • :svg - SVG graphics

  • :svg_filters - SVG filter effects

  • :math_ml - Mathematical notation

  • :html_email - HTML email with legacy attributes

Examples:

Enable multiple profiles

config.use_profiles = { html: true, svg: true }

Email profile

config.use_profiles = { html_email: true }

Parameters:

  • profiles (Hash<Symbol, Boolean>)

    hash of profile names to enable

Returns:

  • (Hash)

    the set profiles



402
403
404
405
406
# File 'lib/dandruff/config.rb', line 402

def use_profiles=(profiles)
  @use_profiles = profiles || {}
  reset_profile_dependent_settings
  process_profiles unless @use_profiles.empty?
end