dandruff 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +23 -0
- data/CHANGELOG.md +69 -0
- data/COMPARISON.md +175 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +142 -0
- data/LICENSE.txt +21 -0
- data/Makefile +41 -0
- data/README.md +1196 -0
- data/Rakefile +12 -0
- data/examples/basic_usage.rb +84 -0
- data/examples/email_sanitization_example.md +268 -0
- data/failed-expectations.md +192 -0
- data/lib/dandruff/attributes.rb +223 -0
- data/lib/dandruff/config.rb +500 -0
- data/lib/dandruff/expressions.rb +103 -0
- data/lib/dandruff/tags.rb +160 -0
- data/lib/dandruff/utils.rb +27 -0
- data/lib/dandruff/version.rb +5 -0
- data/lib/dandruff.rb +1095 -0
- metadata +134 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 92f96a417934ece71e7a47f7c4ae9b38af85c4fc249c806033527998d5dceb04
|
|
4
|
+
data.tar.gz: 660b1352cca1a330c1728ba2788803313482be7afc1325d28a0f9a0ac92d8671
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f5a5e2e77d5e5330880c468ba9c92abc8ae5cbd977db0aed73e9fde021eb3e52f019b8c6b6a01c260496bad64106d93b08b6af1cc9dec1bc205cf8819469ef39
|
|
7
|
+
data.tar.gz: 1dd3a851d79ea500828f9a755796cbd51255920a63c4b36bd166a17a62de8a6b3a26261a1752a1fbd0011dc3ac496a5ab46ff10afae6f48495b8145e671cbada
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Omakase Ruby styling for Rails
|
|
2
|
+
# inherit_gem: { rubocop-rails-omakase: rubocop.yml }
|
|
3
|
+
|
|
4
|
+
# Overwrite or add rules to create your own house style
|
|
5
|
+
#
|
|
6
|
+
# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
|
|
7
|
+
# Layout/SpaceInsideArrayLiteralBrackets:
|
|
8
|
+
# Enabled: false
|
|
9
|
+
|
|
10
|
+
inherit_gem: { kuyio-rubocop: rubocop-default.yml }
|
|
11
|
+
inherit_mode:
|
|
12
|
+
merge:
|
|
13
|
+
- Exclude
|
|
14
|
+
|
|
15
|
+
AllCops:
|
|
16
|
+
Exclude:
|
|
17
|
+
- Gemfile
|
|
18
|
+
- Gemfile.lock
|
|
19
|
+
- vendor/**/*
|
|
20
|
+
- spec/fixtures/examples.rb
|
|
21
|
+
|
|
22
|
+
Style/Lambda:
|
|
23
|
+
EnforcedStyle: literal
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
## [0.8.0] - 2025-11-24
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- **BREAKING**: Renamed library from `scrubber` to `dandruff`.
|
|
7
|
+
- **BREAKING**: Renamed main module from `Scrubber` to `Dandruff`.
|
|
8
|
+
- **BREAKING**: Renamed all files and directories to match new namespace.
|
|
9
|
+
- Added `Dandruff.scrub` alias for `Dandruff.sanitize`.
|
|
10
|
+
- Full YARD documentation
|
|
11
|
+
- Expanded README with more examples and documentation
|
|
12
|
+
|
|
13
|
+
## [0.7.0] - 2025-11-23
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- Removed duplicate `describe 'namespace configuration'` block, reducing example count to 414.
|
|
17
|
+
- Excluded `spec/fixtures/examples.rb` from RuboCop to avoid infinite loops.
|
|
18
|
+
- Fixed unused method argument in `valid_uri_attribute?`.
|
|
19
|
+
- Added `MATH_SVG_TAGS` constant and used safe navigation.
|
|
20
|
+
- Disabled cyclomatic complexity and perceived complexity metrics for several methods.
|
|
21
|
+
- Updated RSpec example titles for uniqueness.
|
|
22
|
+
- Re-enabled RSpec/RepeatedExample cop after fixing duplicates.
|
|
23
|
+
## [0.6.0] - 2025-11-22
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Refined CSS validation to allow safe CSS (behavior:, binding:, data:image/svg+xml) while blocking dangerous patterns.
|
|
27
|
+
- Updated HTML email profile: enabled style tags, preserved document elements, disabled DOM clobbering, allowed data attributes.
|
|
28
|
+
- Fixed namespace handling: preserve text content when removing unknown namespaces.
|
|
29
|
+
- Updated SVG attribute handling: safe handling of filter, data URIs, feImage.
|
|
30
|
+
- Updated configuration handling: added explicit allow_data_attributes flag for strict attribute lists.
|
|
31
|
+
- Updated tests to reflect new behavior.
|
|
32
|
+
|
|
33
|
+
## [0.5.0] - 2025-11-21
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
- Specs covering metadata tag stripping, data/file URI enforcement, obfuscated CSS payloads, expanded DOM clobbering identifiers, attribute hook execution, SVG/MathML hardening, mutation-XSS stabilization, and DOM clobbering canonical parity.
|
|
37
|
+
- Canonical DOM clobbering denylist test to track parity with DOMPurify.
|
|
38
|
+
- Performance section in README with benchmark stats from local Apple M1 Max runs.
|
|
39
|
+
- `html_email` profile to support safe rendering of HTML emails (allows `head`, `meta`, `style` tags and email-specific attributes while stripping scripts and forms).
|
|
40
|
+
- **Per-tag attribute control** via `allowed_attributes_per_tag` configuration option, enabling fine-grained attribute allow lists per HTML tag (e.g., allow `href` only on `<a>` tags). Includes comprehensive documentation and test coverage.
|
|
41
|
+
- **Optimized `html_email` profile** to use per-tag attribute restrictions instead of global attribute allowlisting, improving security by preventing attribute confusion attacks while maintaining full email compatibility.
|
|
42
|
+
- Hook-based per-tag attribute control documentation showing how to use `upon_sanitize_attribute` hook for custom per-tag validation logic.
|
|
43
|
+
- Additional HTML email profile regression specs to preserve `<html lang>`, head/meta/style content, legacy body margins/padding, table layout attributes, and enforced `alt` on `<img>` while stripping dangerous handlers/URIs.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
- Default forbidden tags now include `base`, `link`, `meta`, and `style`; removed these from the default allowlist to mirror DOMPurify defaults.
|
|
47
|
+
- Tightened URI allowlist to http/https/mailto/ftp/tel or relative; `data:`/`file:` are blocked unless explicitly allowed via `allow_data_uri`.
|
|
48
|
+
- Media/link data URIs now honor `allow_data_uri` across tags; inline styles are scanned for escaped/scripted payloads and stripped when unsafe.
|
|
49
|
+
- Broadened DOM clobbering protection and now invoke `upon_sanitize_attribute` hooks during attribute processing.
|
|
50
|
+
- Optional `allow_style_tags` opt-in drops entire style blocks on detection of dangerous patterns; default remains to deny `<style>`.
|
|
51
|
+
- Added optional mutation-XSS stability pass (`sanitize_until_stable` with `mutation_max_passes`) to re-sanitize until output stabilizes and reduce mXSS risk.
|
|
52
|
+
- Expanded URI-safe recognition to SVG `filter` attributes and extended DOM-clobbering denylist; added SVG filter/data-URI and extra clobbering specs.
|
|
53
|
+
- Added SVG animateMotion/feImage data-URI blocking tests to harden remaining SVG vectors.
|
|
54
|
+
- Annotation-XML now forbidden by default; added MathML coverage/tests for maction/annotation-xml and malicious MathML URIs.
|
|
55
|
+
- Added mutation XSS stability test and baseProfile SVG trap coverage.
|
|
56
|
+
- Inline style filtering hardened to catch behavior/binding directives and data SVG URLs; style opt-in drops blocks containing these payloads.
|
|
57
|
+
- `sanitize_until_stable` defaults to 2 passes (bounded), with `pass_limit` to disable or increase passes.
|
|
58
|
+
- Removed `return_trusted_type` flag to avoid implying browser Trusted Types; always return String unless `return_dom`/`return_dom_fragment`.
|
|
59
|
+
- Added `minimal_profile` option to use an HTML-only allowlist (SVG/MathML off by default when enabled) and drop document wrappers unless explicitly allowed.
|
|
60
|
+
- CSS tests expanded for nested/escaped `@import`; URI parsing tightened to reject leading whitespace/control characters.
|
|
61
|
+
- Inline styles now parsed into allowed declarations with protocol checks; unsafe values drop the entire attribute.
|
|
62
|
+
- Dandruff now uses instance-based configuration (`Dandruff.new(config)`) instead of module-level global state; the module-level `Dandruff.sanitize` is a convenience wrapper that builds a fresh instance per call.
|
|
63
|
+
- `use_profiles=` now resets and reapplies profile-derived config, fixing block-style configuration for `html_email` (preserves document elements/attributes even with `return_dom`).
|
|
64
|
+
- HTML email profile now forces full-document parsing and preserves legacy margin attributes and backgrounds on row/table elements to improve email fidelity.
|
|
65
|
+
|
|
66
|
+
## [0.4.0] - 2025-11-20
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
- Initial public release of Scrubber
|
data/COMPARISON.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# HTML Sanitizer Comparison
|
|
2
|
+
|
|
3
|
+
This document compares Dandruff (this project) with [Loofah](https://github.com/flavorjones/loofah), [sanitize](https://github.com/rgrove/sanitize), and [rails-html-sanitization](https://github.com/rails/rails-html-sanitizer).
|
|
4
|
+
|
|
5
|
+
All four libraries are widely used and have solid track records. They make different trade‑offs in API design, configuration style, and how much “framework” they provide around Nokogiri. Dandruff’s design is strongly influenced by [DOMPurify](https://github.com/cure53/DOMPurify) and emphasizes XSS-hardening features and rich hooks; the other libraries are more focused on being flexible building blocks (Loofah), a concise configuration layer (sanitize), or Rails‑friendly defaults (rails-html-sanitization).
|
|
6
|
+
|
|
7
|
+
The goal of this comparison is to highlight where each library is a particularly good fit, rather than to declare a single “winner”.
|
|
8
|
+
|
|
9
|
+
## High-Level Feature Matrix
|
|
10
|
+
|
|
11
|
+
| Aspect | Dandruff | Loofah | sanitize | rails-html-sanitization |
|
|
12
|
+
| --- | --- | --- | --- | --- |
|
|
13
|
+
| **Core model** | Standalone sanitizer modeled after DOMPurify, using Nokogiri HTML5 parsing | Set of Nokogiri-based dandruffs (fragment and document) with composable behavior | Configuration layer on top of Loofah dandruffs | Rails-centric helpers and safe lists backed by Loofah |
|
|
14
|
+
| **Configuration style** | Ruby object/DSL with profiles and per-call overrides | Choose and combine dandruffs; custom dandruff classes | Hash-based allow/forbid lists plus transformers | Limited knobs; mostly choice of sanitizer method and options |
|
|
15
|
+
| **Hooks / extension** | Named hooks around attribute/element sanitization; can adjust or veto behavior | Custom dandruff classes and Nokogiri manipulation | Transformers (blocks) that can modify the tree | Limited extension; primarily composition with Loofah or custom helpers |
|
|
16
|
+
| **Content types** | HTML, SVG, MathML, SVG filters via profiles | Primarily HTML fragments/documents; SVG/MathML require custom handling | Same as Loofah; primarily HTML | HTML/ERB rendered through Rails; other types are uncommon |
|
|
17
|
+
| **HTML email support** | Dedicated `html_email` profile with per-tag attribute rules | Possible with custom dandruffs and rules | Possible with custom config/transformers | Possible with custom config; no email-specific profile |
|
|
18
|
+
| **Return types** | String, DOM, or fragment based on config | Nokogiri fragment/document or serialized string | String output by default | String output, integrated with Rails views/helpers |
|
|
19
|
+
| **Default posture** | Defensive defaults modeled after DOMPurify | Depends on chosen dandruff; some permissive, some stricter | Conservative defaults suitable for common use cases | Rails defaults tuned for typical web views |
|
|
20
|
+
|
|
21
|
+
## Library-by-Library Discussion
|
|
22
|
+
|
|
23
|
+
### Dandruff
|
|
24
|
+
|
|
25
|
+
#### **Design**
|
|
26
|
+
Dandruff is a Ruby implementation inspired by DOMPurify’s design and threat model. It uses Nokogiri’s HTML5 parsing to work with modern HTML and provides configuration through a Ruby object/DSL (`Dandruff::Config`). It exposes a single primary sanitizer with options rather than a collection of separate dandruff classes.
|
|
27
|
+
|
|
28
|
+
#### **Configuration and profiles**
|
|
29
|
+
- Allows setting allowed/forbidden/additional tags and attributes.
|
|
30
|
+
- Supports profiles such as `html`, `svg`, `math_ml`, `svg_filters`, and `html_email` that encapsulate curated safe lists.
|
|
31
|
+
- Per-call overrides allow you to adjust rules for a specific sanitization call without mutating the global configuration.
|
|
32
|
+
|
|
33
|
+
#### **Hooks and advanced behavior**
|
|
34
|
+
- Named hooks (e.g., before/after sanitize elements or attributes, per-element/attribute hooks) allow you to implement cross-cutting rules without forking the library.
|
|
35
|
+
- Can optionally “sanitize until stable”: run sanitization repeatedly until the output no longer changes. This can mitigate payloads that only appear after an initial transformation step.
|
|
36
|
+
|
|
37
|
+
#### **Strengths**
|
|
38
|
+
- Strong focus on XSS mitigation and modern HTML features due to its DOMPurify heritage.
|
|
39
|
+
- Rich, explicit hook system for custom policies.
|
|
40
|
+
- Built-in support for several content profiles, including HTML email.
|
|
41
|
+
|
|
42
|
+
#### **Trade-offs**
|
|
43
|
+
- Adds a more opinionated sanitization framework on top of Nokogiri; this is helpful for many applications, but lower-level libraries can be preferable when you want complete control.
|
|
44
|
+
- The “sanitize until stable” option introduces additional processing; in high-throughput pipelines you may choose to disable it when you are confident in your input and policies.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Loofah
|
|
49
|
+
|
|
50
|
+
#### **Design**
|
|
51
|
+
Loofah is a Nokogiri-based library that provides a set of “dandruffs” and helper methods to clean HTML fragments and documents. It is a foundational piece in the Ruby ecosystem and underpins other sanitizers like sanitize and rails-html-sanitization.
|
|
52
|
+
|
|
53
|
+
#### **Configuration and extensibility**
|
|
54
|
+
- Ships with built-in dandruffs (e.g., stripping or escaping certain content) and lets you compose them.
|
|
55
|
+
- You can define custom dandruffs by subclassing and implementing your own logic, or by manipulating the Nokogiri document directly.
|
|
56
|
+
- The configuration is comparatively low-level: instead of a single global config object, you use and combine dandruffs and Nokogiri operations.
|
|
57
|
+
|
|
58
|
+
#### **Strengths**
|
|
59
|
+
- Very flexible when you need fine-grained control over the Nokogiri document tree.
|
|
60
|
+
- Mature and widely used; many Rails and Ruby projects rely on it directly or indirectly.
|
|
61
|
+
- Good fit when you already think in terms of Nokogiri nodes and custom dandruff classes.
|
|
62
|
+
|
|
63
|
+
#### **Trade-offs**
|
|
64
|
+
- Higher-level policies (like “safe for HTML email” or “DOMPurify-like hardening”) need to be composed manually.
|
|
65
|
+
- No named hook system; extension typically happens by writing more code around Nokogiri.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### sanitize
|
|
70
|
+
|
|
71
|
+
#### **Design**
|
|
72
|
+
`sanitize` builds on Loofah and provides a configuration-driven interface: you specify allowed tags, attributes, and protocols, plus optional transformers that can rewrite or remove specific nodes. It targets a middle ground between low-level Loofah and more opinionated frameworks.
|
|
73
|
+
|
|
74
|
+
#### **Configuration and transformers**
|
|
75
|
+
- Uses a hash-based configuration with explicit allow/forbid lists.
|
|
76
|
+
- Transformers are blocks that run during sanitization and can inspect or modify nodes.
|
|
77
|
+
- Comes with several built-in configurations aimed at common use cases, which can be a starting point for your own policies.
|
|
78
|
+
|
|
79
|
+
#### **Strengths**
|
|
80
|
+
- Expressive configuration model for allowlist-style policies without having to write full custom dandruffs.
|
|
81
|
+
- Transformers allow targeted adjustments when you need to make exceptions or enforce special rules.
|
|
82
|
+
- Good compromise when you want more structure than pure Loofah, but do not need a full DOMPurify-like feature set.
|
|
83
|
+
|
|
84
|
+
#### **Trade-offs**
|
|
85
|
+
- Shares Loofah’s underlying parsing and sanitization behavior, so any limitations or quirks there apply.
|
|
86
|
+
- Complex policies can become harder to reason about when expressed as many transformers.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### rails-html-sanitization
|
|
91
|
+
|
|
92
|
+
#### **Design**
|
|
93
|
+
`rails-html-sanitization` is the library Rails uses for HTML sanitization, built on top of Loofah. It provides Rails-focused APIs and defaults that integrate closely with Action View and other Rails components.
|
|
94
|
+
|
|
95
|
+
#### **Configuration and integration**
|
|
96
|
+
- Exposes sanitization helpers that fit naturally into Rails views and helpers.
|
|
97
|
+
- Uses curated safe lists aimed at typical Rails HTML output.
|
|
98
|
+
- Changes and security fixes are coordinated with Rails releases, which is convenient for Rails applications that update regularly.
|
|
99
|
+
|
|
100
|
+
#### **Strengths**
|
|
101
|
+
- Excellent fit for standard Rails applications that want “batteries included” sanitization in templates.
|
|
102
|
+
- Rails-aware defaults that try to balance safety and convenience in common web app scenarios.
|
|
103
|
+
- Minimal configuration burden; Rails developers can often rely on the defaults.
|
|
104
|
+
|
|
105
|
+
#### **Trade-offs**
|
|
106
|
+
- Less suited for non-Rails environments or for highly specialized sanitization policies.
|
|
107
|
+
- Extension usually involves reaching down to Loofah or additional custom code, rather than tweaking a rich configuration object.
|
|
108
|
+
|
|
109
|
+
## Security Considerations
|
|
110
|
+
|
|
111
|
+
All four libraries take security seriously, but they differ in how much they encode a specific threat model in their APIs and defaults.
|
|
112
|
+
|
|
113
|
+
### **Dandruff**
|
|
114
|
+
- Inspired by DOMPurify’s approach to XSS prevention, including careful handling of attributes, URIs, and different content types.
|
|
115
|
+
- Profiles group safe lists and attribute restrictions, which helps avoid subtle misconfigurations.
|
|
116
|
+
- Hook system enables project-specific rules; as with any extensibility, care is required to avoid accidentally whitelisting unsafe constructs.
|
|
117
|
+
- Optional “sanitize until stable” behavior provides extra resilience against multi-step payloads at the cost of more processing.
|
|
118
|
+
|
|
119
|
+
### **Loofah**
|
|
120
|
+
- Provides robust primitives and dandruffs, and benefits from a long history of security review and fixes.
|
|
121
|
+
- Actual security posture depends on how you compose dandruffs and write custom code around them.
|
|
122
|
+
- Shared foundation for other libraries means improvements and fixes can benefit the wider ecosystem.
|
|
123
|
+
|
|
124
|
+
### **sanitize**
|
|
125
|
+
- Makes explicit allow/forbid configuration central, which can help reason about the policy.
|
|
126
|
+
- Transformers offer precise control but, if misused, can inadvertently permit risky nodes or attributes.
|
|
127
|
+
- Inherits Loofah’s behavior and security updates.
|
|
128
|
+
|
|
129
|
+
### **rails-html-sanitization**
|
|
130
|
+
- Rails-safe defaults are tuned for common Rails templates, and Rails security advisories often highlight sanitizer-related updates.
|
|
131
|
+
- Security posture is strongly tied to keeping Rails and its dependencies up to date.
|
|
132
|
+
- More specialized use cases (e.g., heavy SVG/MathML or complex HTML email) may require additional layers on top.
|
|
133
|
+
|
|
134
|
+
## Usage Scenarios
|
|
135
|
+
|
|
136
|
+
### Rich user-generated content (posts, comments, WYSIWYG)
|
|
137
|
+
|
|
138
|
+
- **Dandruff**: Strong choice when you want DOMPurify-style defenses, hooks for special cases, and the ability to support richer content types (like SVG or MathML) behind explicit profiles.
|
|
139
|
+
- **Loofah**: Good when you need detailed control over the tree and are comfortable building your own dandruffs.
|
|
140
|
+
- **sanitize**: Convenient when you want a clear allowlist configuration and occasional transformers, but no large framework.
|
|
141
|
+
- **rails-html-sanitization**: Appropriate in Rails apps where the built-in view helpers already meet your needs.
|
|
142
|
+
|
|
143
|
+
### HTML email sanitization/rendering
|
|
144
|
+
|
|
145
|
+
- **Dandruff**: Offers an `html_email` profile with per-tag attribute rules and email-oriented safe lists, which can reduce the chance of missing subtle constraints.
|
|
146
|
+
- **Loofah**: Works well for email when you build a dedicated set of dandruffs and tests for your email policies.
|
|
147
|
+
- **sanitize**: A good fit when you prefer hash-based policies; you can encode an email-specific configuration and add transformers for edge cases.
|
|
148
|
+
- **rails-html-sanitization**: Usable within Rails mailers; for complex email policies you may still want to layer `sanitize` or Dandruff (or custom Loofah logic) on top.
|
|
149
|
+
|
|
150
|
+
### SVG/MathML or mixed content
|
|
151
|
+
|
|
152
|
+
- **Dandruff**: Profiles for `svg`, `math_ml`, and `svg_filters` make it straightforward to enable these formats with curated safe lists.
|
|
153
|
+
- **Loofah** and **sanitize**: Capable of handling SVG/MathML with custom configurations, but require more manual policy design and testing.
|
|
154
|
+
- **rails-html-sanitization**: Possible but not a primary focus; typically you would supplement it with lower-level tools for complex SVG/MathML use.
|
|
155
|
+
|
|
156
|
+
### Rails applications
|
|
157
|
+
|
|
158
|
+
- **rails-html-sanitization**: Natural default for Rails because it integrates directly with Action View and is maintained as part of Rails.
|
|
159
|
+
- **Dandruff**: Attractive when you want DOMPurify-inspired hardening, or more explicit hooks; it can be used alongside Rails.
|
|
160
|
+
- **sanitize**: A good option when you like Loofah’s foundation but prefer hash-based configs, and you are comfortable wiring it into your Rails app.
|
|
161
|
+
- **Loofah**: Best fit if you are already using Nokogiri/Loofah directly and want to keep that level of control.
|
|
162
|
+
|
|
163
|
+
### Non-Rails services, background jobs, or custom pipelines
|
|
164
|
+
|
|
165
|
+
- **Dandruff**: Helpful when you want a self-contained sanitizer with clear profiles and hooks, and you do not rely on Rails.
|
|
166
|
+
- **Loofah**: Ideal if you already have Nokogiri logic and want to stay close to the DOM representation.
|
|
167
|
+
- **sanitize**: Simple configuration-centric choice for services that just need to enforce a stable allowlist policy.
|
|
168
|
+
- **rails-html-sanitization**: Less relevant outside Rails; typically you would use one of the other three libraries directly.
|
|
169
|
+
|
|
170
|
+
## Choosing Between Them
|
|
171
|
+
|
|
172
|
+
- Prefer **Dandruff** when you want DOMPurify-style behavior, strong XSS-oriented defaults, support for multiple content profiles (including HTML email), and a rich hook system in a standalone library.
|
|
173
|
+
- Prefer **Loofah** when you value fine-grained control over Nokogiri documents and are comfortable assembling your own dandruffs and policies.
|
|
174
|
+
- Prefer **sanitize** when you like Loofah’s robustness but want a concise, configuration-based interface with transformers for special cases.
|
|
175
|
+
- Prefer **rails-html-sanitization** when you are in a Rails application and are satisfied with Rails’ built-in sanitization semantics and integration.
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
GIT
|
|
2
|
+
remote: https://github.com/kuyio/kuyio-rubocop.git
|
|
3
|
+
revision: 9b25aab12c07cfdea072ff70c1e6d4e066795ff2
|
|
4
|
+
specs:
|
|
5
|
+
kuyio-rubocop (0.3.1)
|
|
6
|
+
rubocop (~> 1.74.0)
|
|
7
|
+
rubocop-performance (~> 1.24.0)
|
|
8
|
+
rubocop-rails (~> 2.30.0)
|
|
9
|
+
rubocop-rspec (~> 3.5.0)
|
|
10
|
+
|
|
11
|
+
PATH
|
|
12
|
+
remote: .
|
|
13
|
+
specs:
|
|
14
|
+
dandruff (0.8.0)
|
|
15
|
+
nokogiri (~> 1.10)
|
|
16
|
+
|
|
17
|
+
GEM
|
|
18
|
+
remote: https://rubygems.org/
|
|
19
|
+
specs:
|
|
20
|
+
activesupport (8.1.1)
|
|
21
|
+
base64
|
|
22
|
+
bigdecimal
|
|
23
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
24
|
+
connection_pool (>= 2.2.5)
|
|
25
|
+
drb
|
|
26
|
+
i18n (>= 1.6, < 2)
|
|
27
|
+
json
|
|
28
|
+
logger (>= 1.4.2)
|
|
29
|
+
minitest (>= 5.1)
|
|
30
|
+
securerandom (>= 0.3)
|
|
31
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
32
|
+
uri (>= 0.13.1)
|
|
33
|
+
ast (2.4.3)
|
|
34
|
+
base64 (0.3.0)
|
|
35
|
+
benchmark (0.5.0)
|
|
36
|
+
bigdecimal (3.3.1)
|
|
37
|
+
concurrent-ruby (1.3.5)
|
|
38
|
+
connection_pool (2.5.4)
|
|
39
|
+
diff-lcs (1.6.2)
|
|
40
|
+
drb (2.2.3)
|
|
41
|
+
i18n (1.14.7)
|
|
42
|
+
concurrent-ruby (~> 1.0)
|
|
43
|
+
json (2.16.0)
|
|
44
|
+
language_server-protocol (3.17.0.5)
|
|
45
|
+
lint_roller (1.1.0)
|
|
46
|
+
logger (1.7.0)
|
|
47
|
+
minitest (5.26.2)
|
|
48
|
+
nokogiri (1.18.10-aarch64-linux-gnu)
|
|
49
|
+
racc (~> 1.4)
|
|
50
|
+
nokogiri (1.18.10-aarch64-linux-musl)
|
|
51
|
+
racc (~> 1.4)
|
|
52
|
+
nokogiri (1.18.10-arm-linux-gnu)
|
|
53
|
+
racc (~> 1.4)
|
|
54
|
+
nokogiri (1.18.10-arm-linux-musl)
|
|
55
|
+
racc (~> 1.4)
|
|
56
|
+
nokogiri (1.18.10-arm64-darwin)
|
|
57
|
+
racc (~> 1.4)
|
|
58
|
+
nokogiri (1.18.10-x86_64-darwin)
|
|
59
|
+
racc (~> 1.4)
|
|
60
|
+
nokogiri (1.18.10-x86_64-linux-gnu)
|
|
61
|
+
racc (~> 1.4)
|
|
62
|
+
nokogiri (1.18.10-x86_64-linux-musl)
|
|
63
|
+
racc (~> 1.4)
|
|
64
|
+
parallel (1.27.0)
|
|
65
|
+
parser (3.3.10.0)
|
|
66
|
+
ast (~> 2.4.1)
|
|
67
|
+
racc
|
|
68
|
+
prism (1.6.0)
|
|
69
|
+
racc (1.8.1)
|
|
70
|
+
rack (3.2.4)
|
|
71
|
+
rainbow (3.1.1)
|
|
72
|
+
rake (13.3.1)
|
|
73
|
+
regexp_parser (2.11.3)
|
|
74
|
+
rspec (3.13.2)
|
|
75
|
+
rspec-core (~> 3.13.0)
|
|
76
|
+
rspec-expectations (~> 3.13.0)
|
|
77
|
+
rspec-mocks (~> 3.13.0)
|
|
78
|
+
rspec-core (3.13.6)
|
|
79
|
+
rspec-support (~> 3.13.0)
|
|
80
|
+
rspec-expectations (3.13.5)
|
|
81
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
82
|
+
rspec-support (~> 3.13.0)
|
|
83
|
+
rspec-mocks (3.13.7)
|
|
84
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
85
|
+
rspec-support (~> 3.13.0)
|
|
86
|
+
rspec-support (3.13.6)
|
|
87
|
+
rubocop (1.74.0)
|
|
88
|
+
json (~> 2.3)
|
|
89
|
+
language_server-protocol (~> 3.17.0.2)
|
|
90
|
+
lint_roller (~> 1.1.0)
|
|
91
|
+
parallel (~> 1.10)
|
|
92
|
+
parser (>= 3.3.0.2)
|
|
93
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
94
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
95
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
96
|
+
ruby-progressbar (~> 1.7)
|
|
97
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
98
|
+
rubocop-ast (1.48.0)
|
|
99
|
+
parser (>= 3.3.7.2)
|
|
100
|
+
prism (~> 1.4)
|
|
101
|
+
rubocop-performance (1.24.0)
|
|
102
|
+
lint_roller (~> 1.1)
|
|
103
|
+
rubocop (>= 1.72.1, < 2.0)
|
|
104
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
105
|
+
rubocop-rails (2.30.3)
|
|
106
|
+
activesupport (>= 4.2.0)
|
|
107
|
+
lint_roller (~> 1.1)
|
|
108
|
+
rack (>= 1.1)
|
|
109
|
+
rubocop (>= 1.72.1, < 2.0)
|
|
110
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
111
|
+
rubocop-rspec (3.5.0)
|
|
112
|
+
lint_roller (~> 1.1)
|
|
113
|
+
rubocop (~> 1.72, >= 1.72.1)
|
|
114
|
+
ruby-progressbar (1.13.0)
|
|
115
|
+
securerandom (0.4.1)
|
|
116
|
+
tzinfo (2.0.6)
|
|
117
|
+
concurrent-ruby (~> 1.0)
|
|
118
|
+
unicode-display_width (3.2.0)
|
|
119
|
+
unicode-emoji (~> 4.1)
|
|
120
|
+
unicode-emoji (4.1.0)
|
|
121
|
+
uri (1.1.1)
|
|
122
|
+
|
|
123
|
+
PLATFORMS
|
|
124
|
+
aarch64-linux-gnu
|
|
125
|
+
aarch64-linux-musl
|
|
126
|
+
arm-linux-gnu
|
|
127
|
+
arm-linux-musl
|
|
128
|
+
arm64-darwin
|
|
129
|
+
x86_64-darwin
|
|
130
|
+
x86_64-linux-gnu
|
|
131
|
+
x86_64-linux-musl
|
|
132
|
+
|
|
133
|
+
DEPENDENCIES
|
|
134
|
+
benchmark (~> 0.5)
|
|
135
|
+
dandruff!
|
|
136
|
+
kuyio-rubocop!
|
|
137
|
+
rake (~> 13.0)
|
|
138
|
+
rspec (~> 3.0)
|
|
139
|
+
rubocop (~> 1.21)
|
|
140
|
+
|
|
141
|
+
BUNDLED WITH
|
|
142
|
+
2.7.2
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 KUY.io Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/Makefile
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Makefile for Dandruff Ruby Gem
|
|
2
|
+
|
|
3
|
+
.PHONY: all test build clean install lint help
|
|
4
|
+
|
|
5
|
+
# Default target
|
|
6
|
+
all: test build
|
|
7
|
+
|
|
8
|
+
# Run test suite
|
|
9
|
+
specs:
|
|
10
|
+
bundle exec rake spec
|
|
11
|
+
|
|
12
|
+
# Build the gem
|
|
13
|
+
build:
|
|
14
|
+
gem build dandruff.gemspec
|
|
15
|
+
|
|
16
|
+
# Clean build artifacts
|
|
17
|
+
clean:
|
|
18
|
+
rm -f *.gem
|
|
19
|
+
|
|
20
|
+
# Install the gem locally
|
|
21
|
+
install: build
|
|
22
|
+
gem install dandruff-*.gem
|
|
23
|
+
|
|
24
|
+
# Run linting
|
|
25
|
+
lint:
|
|
26
|
+
bundle exec rubocop
|
|
27
|
+
|
|
28
|
+
# Run both specs and linting
|
|
29
|
+
test: specs lint
|
|
30
|
+
|
|
31
|
+
# Show help
|
|
32
|
+
help:
|
|
33
|
+
@echo "Available targets:"
|
|
34
|
+
@echo " all - Run tests and build the gem (default)"
|
|
35
|
+
@echo " test - Run both specs and linting"
|
|
36
|
+
@echo " build - Build the gem package"
|
|
37
|
+
@echo " install - Build and install the gem locally"
|
|
38
|
+
@echo " clean - Remove built gem files"
|
|
39
|
+
@echo " specs - Run the test suite"
|
|
40
|
+
@echo " lint - Run RuboCop linting"
|
|
41
|
+
@echo " help - Show this help message"
|