pax_global_header 0000666 0000000 0000000 00000000064 15147370663 0014526 g ustar 00root root 0000000 0000000 52 comment=a8a04134d77f765a166188ef0850369adb6686ab
rails-rails-html-sanitizer-a8a0413/ 0000775 0000000 0000000 00000000000 15147370663 0017243 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/.github/ 0000775 0000000 0000000 00000000000 15147370663 0020603 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/.github/workflows/ 0000775 0000000 0000000 00000000000 15147370663 0022640 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/.github/workflows/ci.yml 0000664 0000000 0000000 00000002772 15147370663 0023766 0 ustar 00root root 0000000 0000000 name: ci
concurrency:
group: "${{github.workflow}}-${{github.ref}}"
cancel-in-progress: true
on:
workflow_dispatch:
push:
branches:
- main
- v*.*.x
tags:
- v*.*.*
pull_request:
types: [opened, synchronize]
branches:
- '*'
jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rm Gemfile.lock
- uses: ruby/setup-ruby@v1
with:
ruby-version: "4.0"
bundler-cache: true
- run: bundle exec rubocop
cruby:
strategy:
fail-fast: false
matrix:
ruby: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "4.0", "ruby-head", "truffleruby-head", "jruby-9.4", "jruby-10.0", "jruby-head"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rm Gemfile.lock
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
bundler-cache: true
- run: bundle exec rake
cruby-nokogiri-system-libraries:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: rm Gemfile.lock
- uses: ruby/setup-ruby@v1
with:
ruby-version: "4.0"
- name: Install nokogiri with system libraries
run: |
sudo apt install pkg-config libxml2-dev libxslt-dev
bundle config set force_ruby_platform true
bundle config build.nokogiri --enable-system-libraries
bundle install
bundle exec nokogiri -v
- run: bundle exec rake
rails-rails-html-sanitizer-a8a0413/.gitignore 0000664 0000000 0000000 00000000215 15147370663 0021231 0 ustar 00root root 0000000 0000000 *.gem
*.rbc
.bundle
.config
.yardoc
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
rails-rails-html-sanitizer-a8a0413/.rdoc_options 0000664 0000000 0000000 00000000702 15147370663 0021745 0 ustar 00root root 0000000 0000000 ---
encoding: UTF-8
static_path: []
rdoc_include: []
page_dir:
charset: UTF-8
exclude:
- "~\\z"
- "\\.orig\\z"
- "\\.rej\\z"
- "\\.bak\\z"
- "\\.gemspec\\z"
- "issues"
- "Gemfile*"
- "Rakefile"
hyperlink_all: false
line_numbers: false
locale:
locale_dir: locale
locale_name:
main_page: "README.md"
markup: rdoc
output_decoration: true
show_hash: false
skip_tests: true
tab_width: 8
template_stylesheets: []
title:
visibility: :protected
webcvs:
rails-rails-html-sanitizer-a8a0413/.rubocop.yml 0000664 0000000 0000000 00000015312 15147370663 0021517 0 ustar 00root root 0000000 0000000 require:
- rubocop-minitest
- rubocop-packaging
- rubocop-performance
- rubocop-rails
AllCops:
TargetRubyVersion: 2.7
# RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
# to ignore them, so only the ones explicitly set in this file are enabled.
DisabledByDefault: true
SuggestExtensions: false
Exclude:
- '**/tmp/**/*'
- '**/templates/**/*'
- '**/vendor/**/*'
- 'actionpack/lib/action_dispatch/journey/parser.rb'
- 'actionmailbox/test/dummy/**/*'
- 'actiontext/test/dummy/**/*'
- '**/node_modules/**/*'
Performance:
Exclude:
- '**/test/**/*'
Rails/IndexBy:
Enabled: true
Rails/IndexWith:
Enabled: true
# Prefer &&/|| over and/or.
Style/AndOr:
Enabled: true
# Align `when` with `case`.
Layout/CaseIndentation:
Enabled: true
Layout/ClosingHeredocIndentation:
Enabled: true
Layout/ClosingParenthesisIndentation:
Enabled: true
# Align comments with method definitions.
Layout/CommentIndentation:
Enabled: true
Layout/ElseAlignment:
Enabled: true
# Align `end` with the matching keyword or starting expression except for
# assignments, where it should be aligned with the LHS.
Layout/EndAlignment:
Enabled: true
EnforcedStyleAlignWith: variable
AutoCorrect: true
Layout/EndOfLine:
Enabled: true
Layout/EmptyLineAfterMagicComment:
Enabled: true
Layout/EmptyLinesAroundAccessModifier:
Enabled: true
EnforcedStyle: only_before
Layout/EmptyLinesAroundBlockBody:
Enabled: true
# In a regular class definition, no empty lines around the body.
Layout/EmptyLinesAroundClassBody:
Enabled: true
# In a regular method definition, no empty lines around the body.
Layout/EmptyLinesAroundMethodBody:
Enabled: true
# In a regular module definition, no empty lines around the body.
Layout/EmptyLinesAroundModuleBody:
Enabled: true
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
Style/HashSyntax:
Enabled: true
# Method definitions after `private` or `protected` isolated calls need one
# extra level of indentation.
Layout/IndentationConsistency:
Enabled: true
EnforcedStyle: indented_internal_methods
# Two spaces, no tabs (for indentation).
Layout/IndentationWidth:
Enabled: true
Layout/LeadingCommentSpace:
Enabled: true
Layout/SpaceAfterColon:
Enabled: true
Layout/SpaceAfterComma:
Enabled: true
Layout/SpaceAfterSemicolon:
Enabled: true
Layout/SpaceAroundEqualsInParameterDefault:
Enabled: true
Layout/SpaceAroundKeyword:
Enabled: true
Layout/SpaceAroundOperators:
Enabled: true
Layout/SpaceBeforeComma:
Enabled: true
Layout/SpaceBeforeComment:
Enabled: true
Layout/SpaceBeforeFirstArg:
Enabled: true
Style/DefWithParentheses:
Enabled: true
# Defining a method with parameters needs parentheses.
Style/MethodDefParentheses:
Enabled: true
Style/ExplicitBlockArgument:
Enabled: true
Style/FrozenStringLiteralComment:
Enabled: true
EnforcedStyle: always
Exclude:
- 'actionview/test/**/*.builder'
- 'actionview/test/**/*.ruby'
- 'actionpack/test/**/*.builder'
- 'actionpack/test/**/*.ruby'
- 'activestorage/db/migrate/**/*.rb'
- 'activestorage/db/update_migrate/**/*.rb'
- 'actionmailbox/db/migrate/**/*.rb'
- 'actiontext/db/migrate/**/*.rb'
Style/MapToHash:
Enabled: true
Style/RedundantFreeze:
Enabled: true
# Use `foo {}` not `foo{}`.
Layout/SpaceBeforeBlockBraces:
Enabled: true
# Use `foo { bar }` not `foo {bar}`.
Layout/SpaceInsideBlockBraces:
Enabled: true
EnforcedStyleForEmptyBraces: space
# Use `{ a: 1 }` not `{a:1}`.
Layout/SpaceInsideHashLiteralBraces:
Enabled: true
Layout/SpaceInsideParens:
Enabled: true
# Check quotes usage according to lint rule below.
Style/StringLiterals:
Enabled: true
EnforcedStyle: double_quotes
# Detect hard tabs, no hard tabs.
Layout/IndentationStyle:
Enabled: true
# Empty lines should not have any spaces.
Layout/TrailingEmptyLines:
Enabled: true
# No trailing whitespace.
Layout/TrailingWhitespace:
Enabled: true
# Use quotes for string literals when they are enough.
Style/RedundantPercentQ:
Enabled: true
Lint/AmbiguousOperator:
Enabled: true
Lint/AmbiguousRegexpLiteral:
Enabled: true
Lint/DuplicateRequire:
Enabled: true
Lint/DuplicateMagicComment:
Enabled: true
Lint/DuplicateMethods:
Enabled: true
Lint/ErbNewArguments:
Enabled: true
Lint/EnsureReturn:
Enabled: true
Lint/MissingCopEnableDirective:
Enabled: true
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
Lint/RequireParentheses:
Enabled: true
Lint/RedundantCopDisableDirective:
Enabled: true
Lint/RedundantCopEnableDirective:
Enabled: true
Lint/RedundantStringCoercion:
Enabled: true
Lint/RedundantSafeNavigation:
Enabled: true
Lint/UriEscapeUnescape:
Enabled: true
Lint/UselessAssignment:
Enabled: true
Lint/DeprecatedClassMethods:
Enabled: true
Lint/InterpolationCheck:
Enabled: true
Exclude:
- '**/test/**/*'
Lint/SafeNavigationChain:
Enabled: true
Style/EvalWithLocation:
Enabled: true
Exclude:
- '**/test/**/*'
Style/ParenthesesAroundCondition:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: true
Style/RedundantBegin:
Enabled: true
Style/RedundantReturn:
Enabled: true
AllowMultipleReturnValues: true
Style/RedundantRegexpEscape:
Enabled: true
Style/Semicolon:
Enabled: true
AllowAsExpressionSeparator: true
# Prefer Foo.method over Foo::method
Style/ColonMethodCall:
Enabled: true
Style/TrivialAccessors:
Enabled: true
# Prefer a = b || c over a = b ? b : c
Style/RedundantCondition:
Enabled: true
Style/RedundantDoubleSplatHashBraces:
Enabled: true
Style/ArrayIntersect:
Enabled: true
Performance/BindCall:
Enabled: true
Performance/FlatMap:
Enabled: true
Performance/MapCompact:
Enabled: true
Performance/SelectMap:
Enabled: true
Performance/RedundantMerge:
Enabled: true
Performance/StartWith:
Enabled: true
Performance/EndWith:
Enabled: true
Performance/RegexpMatch:
Enabled: true
Performance/ReverseEach:
Enabled: true
Performance/StringReplacement:
Enabled: true
Performance/DeletePrefix:
Enabled: true
Performance/DeleteSuffix:
Enabled: true
Performance/OpenStruct:
Enabled: true
Performance/InefficientHashSearch:
Enabled: true
Performance/ConstantRegexp:
Enabled: true
Performance/RedundantStringChars:
Enabled: true
Performance/StringInclude:
Enabled: true
Minitest/AssertPredicate:
Enabled: true
Minitest/AssertRaisesWithRegexpArgument:
Enabled: true
Minitest/AssertWithExpectedArgument:
Enabled: true
Minitest/LiteralAsActualArgument:
Enabled: true
Minitest/NonExecutableTestMethod:
Enabled: true
Minitest/SkipEnsure:
Enabled: true
Minitest/UnreachableAssertion:
Enabled: true
Minitest/NoAssertions:
Enabled: true
rails-rails-html-sanitizer-a8a0413/CHANGELOG.md 0000664 0000000 0000000 00000017421 15147370663 0021061 0 ustar 00root root 0000000 0000000 ## v1.7.0 / 2026-02-24
* Add `Rails::HTML::Sanitizer.allowed_uri?` which delegates to `Loofah::HTML5::Scrub.allowed_uri?`,
allowing the Rails framework to check URI safety without a direct dependency on Loofah.
The minimum Loofah dependency is now `~> 2.25`.
*Mike Dalessio*
## v1.6.2 / 2024-12-12
* `PermitScrubber` fully supports frozen "allowed tags".
v1.6.1 introduced safety checks that may remove unsafe tags from the allowed list, which
introduced a regression for applications passing a frozen array of allowed tags. Tags and
attributes are now properly copied when they are passed to the scrubber.
Fixes #195.
*Mike Dalessio*
## 1.6.1 / 2024-12-02
This is a performance and security release which addresses several possible XSS vulnerabilities.
* The dependency on Nokogiri is updated to v1.15.7 or >=1.16.8.
This change addresses CVE-2024-53985 (GHSA-w8gc-x259-rc7x).
*Mike Dalessio*
* Disallowed tags will be pruned when they appear in foreign content (i.e. SVG or MathML content),
regardless of the `prune:` option value. Previously, disallowed tags were "stripped" unless the
gem was configured with the `prune: true` option.
The CVEs addressed by this change are:
- CVE-2024-53986 (GHSA-638j-pmjw-jq48)
- CVE-2024-53987 (GHSA-2x5m-9ch4-qgrr)
*Mike Dalessio*
* The tags "noscript", "mglyph", and "malignmark" will not be allowed, even if explicitly added to
the allowlist. If applications try to allow any of these tags, a warning is emitted and the tags
are removed from the allow-list.
The CVEs addressed by this change are:
- CVE-2024-53988 (GHSA-cfjx-w229-hgx5)
- CVE-2024-53989 (GHSA-rxv5-gxqc-xx8g)
Please note that we _may_ restore support for allowing "noscript" in a future release. We do not
expect to ever allow "mglyph" or "malignmark", though, especially since browser support is minimal
for these tags.
*Mike Dalessio*
* Improve performance by eliminating needless operations on attributes that are being removed. #188
*Mike Dalessio*
## 1.6.0 / 2023-05-26
* Dependencies have been updated:
- Loofah `~>2.21` and Nokogiri `~>1.14` for HTML5 parser support
- As a result, required Ruby version is now `>= 2.7.0`
Security updates will continue to be made on the `1.5.x` release branch as long as Rails 6.1
(which supports Ruby 2.5) is still in security support.
*Mike Dalessio*
* HTML5 standards-compliant sanitizers are now available on platforms supported by
Nokogiri::HTML5. These are available as:
- `Rails::HTML5::FullSanitizer`
- `Rails::HTML5::LinkSanitizer`
- `Rails::HTML5::SafeListSanitizer`
And a new "vendor" is provided at `Rails::HTML5::Sanitizer` that can be used in a future version
of Rails.
Note that for symmetry `Rails::HTML4::Sanitizer` is also added, though its behavior is identical
to the vendor class methods on `Rails::HTML::Sanitizer`.
Users may call `Rails::HTML::Sanitizer.best_supported_vendor` to get back the HTML5 vendor if it's
supported, else the legacy HTML4 vendor.
*Mike Dalessio*
* Module namespaces have changed, but backwards compatibility is provided by aliases.
The library defines three additional modules:
- `Rails::HTML` for general functionality (replacing `Rails::Html`)
- `Rails::HTML4` containing sanitizers that parse content as HTML4
- `Rails::HTML5` containing sanitizers that parse content as HTML5
The following aliases are maintained for backwards compatibility:
- `Rails::Html` points to `Rails::HTML`
- `Rails::HTML::FullSanitizer` points to `Rails::HTML4::FullSanitizer`
- `Rails::HTML::LinkSanitizer` points to `Rails::HTML4::LinkSanitizer`
- `Rails::HTML::SafeListSanitizer` points to `Rails::HTML4::SafeListSanitizer`
*Mike Dalessio*
* `LinkSanitizer` always returns UTF-8 encoded strings. `SafeListSanitizer` and `FullSanitizer`
already ensured this encoding.
*Mike Dalessio*
* `SafeListSanitizer` allows `time` tag and `lang` attribute by default.
*Mike Dalessio*
* The constant `Rails::Html::XPATHS_TO_REMOVE` has been removed. It's not necessary with the
existing sanitizers, and should have been a private constant all along anyway.
*Mike Dalessio*
## 1.5.0 / 2023-01-20
* `SafeListSanitizer`, `PermitScrubber`, and `TargetScrubber` now all support pruning of unsafe tags.
By default, unsafe tags are still stripped, but this behavior can be changed to prune the element
and its children from the document by passing `prune: true` to any of these classes' constructors.
*seyerian*
## 1.4.4 / 2022-12-13
* Address inefficient regular expression complexity with certain configurations of Rails::Html::Sanitizer.
Fixes CVE-2022-23517. See
[GHSA-5x79-w82f-gw8w](https://github.com/rails/rails-html-sanitizer/security/advisories/GHSA-5x79-w82f-gw8w)
for more information.
*Mike Dalessio*
* Address improper sanitization of data URIs.
Fixes CVE-2022-23518 and #135. See
[GHSA-mcvf-2q2m-x72m](https://github.com/rails/rails-html-sanitizer/security/advisories/GHSA-mcvf-2q2m-x72m)
for more information.
*Mike Dalessio*
* Address possible XSS vulnerability with certain configurations of Rails::Html::Sanitizer.
Fixes CVE-2022-23520. See
[GHSA-rrfc-7g8p-99q8](https://github.com/rails/rails-html-sanitizer/security/advisories/GHSA-rrfc-7g8p-99q8)
for more information.
*Mike Dalessio*
* Address possible XSS vulnerability with certain configurations of Rails::Html::Sanitizer.
Fixes CVE-2022-23519. See
[GHSA-9h9g-93gc-623h](https://github.com/rails/rails-html-sanitizer/security/advisories/GHSA-9h9g-93gc-623h)
for more information.
*Mike Dalessio*
## 1.4.3 / 2022-06-09
* Address a possible XSS vulnerability with certain configurations of Rails::Html::Sanitizer.
Prevent the combination of `select` and `style` as allowed tags in SafeListSanitizer.
Fixes CVE-2022-32209
*Mike Dalessio*
## 1.4.2 / 2021-08-23
* Slightly improve performance.
Assuming elements are more common than comments, make one less method call per node.
*Mike Dalessio*
## 1.4.1 / 2021-08-18
* Fix regression in v1.4.0 that did not pass comment nodes to the scrubber.
Some scrubbers will want to override the default behavior and allow comments, but v1.4.0 only
passed through elements to the scrubber's `keep_node?` method.
This change once again allows the scrubber to make the decision on comment nodes, but still skips
other non-elements like processing instructions (see #115).
*Mike Dalessio*
## 1.4.0 / 2021-08-18
* Processing Instructions are no longer allowed by Rails::Html::PermitScrubber
Previously, a PI with a name (or "target") matching an allowed tag name was not scrubbed. There
are no known security issues associated with these PIs, but similar to comments it's preferred to
omit these nodes when possible from sanitized output.
Fixes #115.
*Mike Dalessio*
## 1.3.0
* Address deprecations in Loofah 2.3.0.
*Josh Goodall*
## 1.2.0
* Remove needless `white_list_sanitizer` deprecation.
By deprecating this, we were forcing Rails 5.2 to be updated or spew
deprecations that users could do nothing about.
That's pointless and I'm sorry for adding that!
Now there's no deprecation warning and Rails 5.2 works out of the box, while
Rails 6 can use the updated naming.
*Kasper Timm Hansen*
## 1.1.0
* Add `safe_list_sanitizer` and deprecate `white_list_sanitizer` to be removed
in 1.2.0. https://github.com/rails/rails-html-sanitizer/pull/87
*Juanito Fatas*
* Remove `href` from LinkScrubber's `tags` as it's not an element.
https://github.com/rails/rails-html-sanitizer/pull/92
*Juanito Fatas*
* Explain that we don't need to bump Loofah here if there's CVEs.
https://github.com/rails/rails-html-sanitizer/commit/d4d823c617fdd0064956047f7fbf23fff305a69b
*Kasper Timm Hansen*
## 1.0.1
* Added support for Rails 4.2.0.beta2 and above
## 1.0.0
* First release.
rails-rails-html-sanitizer-a8a0413/CONTRIBUTING.md 0000664 0000000 0000000 00000006722 15147370663 0021503 0 ustar 00root root 0000000 0000000 Contributing to Rails Html Sanitizers
=====================
[](https://github.com/rails/rails-html-sanitizer/actions/workflows/ci.yml)
Rails Html Sanitizers is work of [many contributors](https://github.com/rails/rails-html-sanitizer/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/rails/rails-html-sanitizer/pulls), [propose features and discuss issues](https://github.com/rails/rails-html-sanitizer/issues).
### How to submit a pull request
#### Fork the Project
Fork the [project on Github](https://github.com/rails/rails-html-sanitizer) and check out your copy.
```
git clone https://github.com/contributor/rails-html-sanitizer.git
cd rails-html-sanitizer
git remote add upstream https://github.com/rails/rails-html-sanitizer.git
```
#### Create a Topic Branch
Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
```
git checkout main
git pull upstream main
git checkout -b my-feature-branch
```
#### Bundle Install and Test
Ensure that you can build the project and run tests.
```
bundle install
bundle exec rake test
```
#### Write Tests
Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [test](test).
We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix.
#### Write Code
Implement your feature or bug fix.
Make sure that `bundle exec rake test` completes without errors.
#### Write Documentation
Document any external behavior in the [README](README.md).
#### Commit Changes
Make sure git knows your name and email address:
```
git config --global user.name "Your Name"
git config --global user.email "contributor@example.com"
```
Writing good commit logs is important. A commit log should describe what changed and why.
```
git add ...
git commit
```
#### Push
```
git push origin my-feature-branch
```
#### Make a Pull Request
Go to https://github.com/contributor/rails-html-sanitizer and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
#### Rebase
If you've been working on a change for a while, rebase with upstream/main.
```
git fetch upstream
git rebase upstream/main
git push origin my-feature-branch -f
```
#### Check on Your Pull Request
Go back to your pull request after a few minutes and see whether it passed muster with CI. Everything should look green, otherwise fix issues and amend your commit as described above.
#### Be Patient
It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there!
#### Thank You
Please do know that we really appreciate and value your time and work. We love you, really.
### How to cut a release
A quick checklist:
- [ ] make sure CI is green! https://github.com/rails/rails-html-sanitizer/actions/workflows/ci.yml
- [ ] update `CHANGELOG.md` and `lib/rails/html/sanitizer/version.rb`
- [ ] run `bundle exec rake build`
- [ ] create a git tag
- [ ] `git push && git push --tags`
- [ ] `gem push pkg/*.gem`
- [ ] create a release at https://github.com/rails/rails-html-sanitizer/releases
- if security-related,
- [ ] publish the CVE
- [ ] post to https://discuss.rubyonrails.org/c/security-announcements
- [ ] submit a PR to https://github.com/rubysec/ruby-advisory-db
rails-rails-html-sanitizer-a8a0413/Gemfile 0000664 0000000 0000000 00000000521 15147370663 0020534 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
source "https://rubygems.org"
gemspec
gem "rake"
gem "minitest", "< 6"
group :rubocop do
gem "rubocop", ">= 1.25.1", require: false
gem "rubocop-minitest", require: false
gem "rubocop-packaging", require: false
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false
end
rails-rails-html-sanitizer-a8a0413/Gemfile.lock 0000664 0000000 0000000 00000016162 15147370663 0021473 0 ustar 00root root 0000000 0000000 PATH
remote: .
specs:
rails-html-sanitizer (1.7.0.dev)
loofah (~> 2.25)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
GEM
remote: https://rubygems.org/
specs:
activesupport (8.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
json
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
ast (2.4.3)
base64 (0.3.0)
bigdecimal (4.0.1)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
crass (1.0.6)
drb (2.2.3)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
json (2.18.1)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
logger (1.7.0)
loofah (2.25.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
minitest (5.27.0)
nokogiri (1.19.1-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.1-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.19.1-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.1-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.19.1-arm64-darwin)
racc (~> 1.4)
nokogiri (1.19.1-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.19.1-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.19.1-x86_64-linux-musl)
racc (~> 1.4)
parallel (1.27.0)
parser (3.3.10.2)
ast (~> 2.4.1)
racc
prism (1.9.0)
racc (1.8.1)
rack (3.2.5)
rainbow (3.1.1)
rake (13.3.1)
regexp_parser (2.11.3)
rubocop (1.84.2)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.49.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.49.0)
parser (>= 3.3.7.2)
prism (~> 1.7)
rubocop-minitest (0.39.1)
lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
rubocop-packaging (0.6.0)
lint_roller (~> 1.1.0)
rubocop (>= 1.72.1, < 2.0)
rubocop-performance (1.26.1)
lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.47.1, < 2.0)
rubocop-rails (2.34.3)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
ruby-progressbar (1.13.0)
securerandom (0.4.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.2.0)
uri (1.1.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
minitest (< 6)
rails-html-sanitizer!
rake
rubocop (>= 1.25.1)
rubocop-minitest
rubocop-packaging
rubocop-performance
rubocop-rails
CHECKSUMS
activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
loofah (2.25.0) sha256=df5ed7ac3bac6a4ec802df3877ee5cc86d027299f8952e6243b3dac446b060e6
minitest (5.27.0) sha256=2d3b17f8a36fe7801c1adcffdbc38233b938eb0b4966e97a6739055a45fa77d5
nokogiri (1.19.1-aarch64-linux-gnu) sha256=cfdb0eafd9a554a88f12ebcc688d2b9005f9fce42b00b970e3dc199587b27f32
nokogiri (1.19.1-aarch64-linux-musl) sha256=1e2150ab43c3b373aba76cd1190af7b9e92103564063e48c474f7600923620b5
nokogiri (1.19.1-arm-linux-gnu) sha256=0a39ed59abe3bf279fab9dd4c6db6fe8af01af0608f6e1f08b8ffa4e5d407fa3
nokogiri (1.19.1-arm-linux-musl) sha256=3a18e559ee499b064aac6562d98daab3d39ba6cbb4074a1542781b2f556db47d
nokogiri (1.19.1-arm64-darwin) sha256=dfe2d337e6700eac47290407c289d56bcf85805d128c1b5a6434ddb79731cb9e
nokogiri (1.19.1-x86_64-darwin) sha256=7093896778cc03efb74b85f915a775862730e887f2e58d6921e3fa3d981e68bf
nokogiri (1.19.1-x86_64-linux-gnu) sha256=1a4902842a186b4f901078e692d12257678e6133858d0566152fe29cdb98456a
nokogiri (1.19.1-x86_64-linux-musl) sha256=4267f38ad4fc7e52a2e7ee28ed494e8f9d8eb4f4b3320901d55981c7b995fc23
parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
rack (3.2.5) sha256=4cbd0974c0b79f7a139b4812004a62e4c60b145cba76422e288ee670601ed6d3
rails-html-sanitizer (1.7.0.dev)
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
rubocop (1.84.2) sha256=5692cea54168f3dc8cb79a6fe95c5424b7ea893c707ad7a4307b0585e88dbf5f
rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
rubocop-minitest (0.39.1) sha256=998398d6da4026d297f0f9bf709a1eac5f2b6947c24431f94af08138510cf7ed
rubocop-packaging (0.6.0) sha256=fb92bd0fb48e6f8cdb1648d2249b0cd51c2497dcc87340132d22f01edbf558a7
rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
rubocop-rails (2.34.3) sha256=10d37989024865ecda8199f311f3faca990143fbac967de943f88aca11eb9ad2
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
BUNDLED WITH
4.0.6
rails-rails-html-sanitizer-a8a0413/MIT-LICENSE 0000664 0000000 0000000 00000002142 15147370663 0020676 0 ustar 00root root 0000000 0000000 Copyright (c) 2013-2023 Rafael Mendonça França, Kasper Timm Hansen, Mike Dalessio
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
rails-rails-html-sanitizer-a8a0413/README.md 0000664 0000000 0000000 00000022544 15147370663 0020531 0 ustar 00root root 0000000 0000000 # Rails HTML Sanitizers
This gem is responsible for sanitizing HTML fragments in Rails applications. Specifically, this is the set of sanitizers used to implement the Action View `SanitizerHelper` methods `sanitize`, `sanitize_css`, `strip_tags` and `strip_links`.
Rails HTML Sanitizer is only intended to be used with Rails applications. If you need similar functionality but aren't using Rails, consider using the underlying sanitization library [Loofah](https://github.com/flavorjones/loofah) directly.
## Usage
### Sanitizers
All sanitizers respond to `sanitize`, and are available in variants that use either HTML4 or HTML5 parsing, under the `Rails::HTML4` and `Rails::HTML5` namespaces, respectively.
NOTE: The HTML5 sanitizers are not supported on JRuby. Users may programmatically check for support by calling `Rails::HTML::Sanitizer.html5_support?`.
#### FullSanitizer
```ruby
full_sanitizer = Rails::HTML5::FullSanitizer.new
full_sanitizer.sanitize("Bold no more! See more here...")
# => Bold no more! See more here...
```
or, if you insist on parsing the content as HTML4:
```ruby
full_sanitizer = Rails::HTML4::FullSanitizer.new
full_sanitizer.sanitize("Bold no more! See more here...")
# => Bold no more! See more here...
```
#### LinkSanitizer
```ruby
link_sanitizer = Rails::HTML5::LinkSanitizer.new
link_sanitizer.sanitize('Only the link text will be kept.')
# => Only the link text will be kept.
```
or, if you insist on parsing the content as HTML4:
```ruby
link_sanitizer = Rails::HTML4::LinkSanitizer.new
link_sanitizer.sanitize('Only the link text will be kept.')
# => Only the link text will be kept.
```
#### SafeListSanitizer
This sanitizer is also available as an HTML4 variant, but for simplicity we'll document only the HTML5 variant below.
```ruby
safe_list_sanitizer = Rails::HTML5::SafeListSanitizer.new
# sanitize via an extensive safe list of allowed elements
safe_list_sanitizer.sanitize(@article.body)
# sanitize only the supplied tags and attributes
safe_list_sanitizer.sanitize(@article.body, tags: %w(table tr td), attributes: %w(id class style))
# sanitize via a custom scrubber
safe_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
# prune nodes from the tree instead of stripping tags and leaving inner content
safe_list_sanitizer = Rails::HTML5::SafeListSanitizer.new(prune: true)
# the sanitizer can also sanitize css
safe_list_sanitizer.sanitize_css('background-color: #000;')
```
### Scrubbers
Scrubbers are objects responsible for removing nodes or attributes you don't want in your HTML document.
This gem includes two scrubbers `Rails::HTML::PermitScrubber` and `Rails::HTML::TargetScrubber`.
#### `Rails::HTML::PermitScrubber`
This scrubber allows you to permit only the tags and attributes you want.
```ruby
scrubber = Rails::HTML::PermitScrubber.new
scrubber.tags = ['a']
html_fragment = Loofah.fragment('')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => ""
```
By default, inner content is left, but it can be removed as well.
```ruby
scrubber = Rails::HTML::PermitScrubber.new
scrubber.tags = ['a']
html_fragment = Loofah.fragment('text')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => "text"
scrubber = Rails::HTML::PermitScrubber.new(prune: true)
scrubber.tags = ['a']
html_fragment = Loofah.fragment('text')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => ""
```
#### `Rails::HTML::TargetScrubber`
Where `PermitScrubber` picks out tags and attributes to permit in sanitization,
`Rails::HTML::TargetScrubber` targets them for removal. See https://github.com/flavorjones/loofah/blob/main/lib/loofah/html5/safelist.rb for the tag list.
**Note:** by default, it will scrub anything that is not part of the permitted tags from
loofah `HTML5::Scrub.allowed_element?`.
```ruby
scrubber = Rails::HTML::TargetScrubber.new
scrubber.tags = ['img']
html_fragment = Loofah.fragment('
')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => ""
```
Similarly to `PermitScrubber`, nodes can be fully pruned.
```ruby
scrubber = Rails::HTML::TargetScrubber.new
scrubber.tags = ['span']
html_fragment = Loofah.fragment('text')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => "text"
scrubber = Rails::HTML::TargetScrubber.new(prune: true)
scrubber.tags = ['span']
html_fragment = Loofah.fragment('text')
html_fragment.scrub!(scrubber)
html_fragment.to_s # => ""
```
#### Custom Scrubbers
You can also create custom scrubbers in your application if you want to.
```ruby
class CommentScrubber < Rails::HTML::PermitScrubber
def initialize
super
self.tags = %w( form script comment blockquote )
self.attributes = %w( style )
end
def skip_node?(node)
node.text?
end
end
```
See `Rails::HTML::PermitScrubber` documentation to learn more about which methods can be overridden.
#### Custom Scrubber in a Rails app
Using the `CommentScrubber` from above, you can use this in a Rails view like so:
```ruby
<%= sanitize @comment, scrubber: CommentScrubber.new %>
```
### A note on HTML entities
__Rails HTML sanitizers are intended to be used by the view layer, at page-render time. They are *not* intended to sanitize persisted strings that will be sanitized *again* at page-render time.__
Proper HTML sanitization will replace some characters with HTML entities. For example, text containing a `<` character will be updated to contain `<` to ensure that the markup is well-formed.
This is important to keep in mind because __HTML entities will render improperly if they are sanitized twice.__
#### A concrete example showing the problem that can arise
Imagine the user is asked to enter their employer's name, which will appear on their public profile page. Then imagine they enter `JPMorgan Chase & Co.`.
If you sanitize this before persisting it in the database, the stored string will be `JPMorgan Chase & Co.`
When the page is rendered, if this string is sanitized a second time by the view layer, the HTML will contain `JPMorgan Chase & Co.` which will render as "JPMorgan Chase & Co.".
Another problem that can arise is rendering the sanitized string in a non-HTML context (for example, if it ends up being part of an SMS message). In this case, it may contain inappropriate HTML entities.
#### Suggested alternatives
You might simply choose to persist the untrusted string as-is (the raw input), and then ensure that the string will be properly sanitized by the view layer.
That raw string, if rendered in an non-HTML context (like SMS), must also be sanitized by a method appropriate for that context. You may wish to look into using [Loofah](https://github.com/flavorjones/loofah) or [Sanitize](https://github.com/rgrove/sanitize) to customize how this sanitization works, including omitting HTML entities in the final string.
If you really want to sanitize the string that's stored in your database, you may wish to look into [Loofah::ActiveRecord](https://github.com/flavorjones/loofah-activerecord) rather than use the Rails HTML sanitizers.
### A note on module names
In versions < 1.6, the only module defined by this library was `Rails::Html`. Starting in 1.6, we define three additional modules:
- `Rails::HTML` for general functionality (replacing `Rails::Html`)
- `Rails::HTML4` containing sanitizers that parse content as HTML4
- `Rails::HTML5` containing sanitizers that parse content as HTML5 (if supported)
The following aliases are maintained for backwards compatibility:
- `Rails::Html` points to `Rails::HTML`
- `Rails::HTML::FullSanitizer` points to `Rails::HTML4::FullSanitizer`
- `Rails::HTML::LinkSanitizer` points to `Rails::HTML4::LinkSanitizer`
- `Rails::HTML::SafeListSanitizer` points to `Rails::HTML4::SafeListSanitizer`
## Installation
Add this line to your application's Gemfile:
gem 'rails-html-sanitizer'
And then execute:
$ bundle
Or install it yourself as:
$ gem install rails-html-sanitizer
## Support matrix
| branch | ruby support | actively maintained | security support |
|--------|--------------|---------------------|----------------------------------------|
| 1.6.x | >= 2.7 | yes | yes |
| 1.5.x | >= 2.5 | no | while Rails 6.1 is in security support |
| 1.4.x | >= 1.8.7 | no | no |
## Read more
Loofah is what underlies the sanitizers and scrubbers of rails-html-sanitizer.
- [Loofah and Loofah Scrubbers](https://github.com/flavorjones/loofah)
The `node` argument passed to some methods in a custom scrubber is an instance of `Nokogiri::XML::Node`.
- [`Nokogiri::XML::Node`](https://nokogiri.org/rdoc/Nokogiri/XML/Node.html)
- [Nokogiri](http://nokogiri.org)
## Contributing to Rails HTML Sanitizers
Rails HTML Sanitizers is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues.
See [CONTRIBUTING](CONTRIBUTING.md).
### Security reports
Trying to report a possible security vulnerability in this project? Please check out the [Rails project's security policy](https://rubyonrails.org/security) for instructions.
## License
Rails HTML Sanitizers is released under the [MIT License](MIT-LICENSE).
rails-rails-html-sanitizer-a8a0413/Rakefile 0000664 0000000 0000000 00000000316 15147370663 0020710 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
require "bundler/gem_tasks"
require "rake/testtask"
task default: :test
Rake::TestTask.new do |t|
t.pattern = "test/**/*_test.rb"
t.warning = true
t.verbose = true
end
rails-rails-html-sanitizer-a8a0413/lib/ 0000775 0000000 0000000 00000000000 15147370663 0020011 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/lib/rails-html-sanitizer.rb 0000664 0000000 0000000 00000003565 15147370663 0024431 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
require_relative "rails/html/sanitizer/version"
require "loofah"
require_relative "rails/html/scrubbers"
require_relative "rails/html/sanitizer"
module Rails
Html = HTML # :nodoc:
end
module ActionView
module Helpers
module SanitizeHelper
module ClassMethods
# Replaces the allowed tags for the +sanitize+ helper.
#
# class Application < Rails::Application
# config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
# end
#
def sanitized_allowed_tags=(tags)
sanitizer_vendor.safe_list_sanitizer.allowed_tags = tags
end
# Replaces the allowed HTML attributes for the +sanitize+ helper.
#
# class Application < Rails::Application
# config.action_view.sanitized_allowed_attributes = ['onclick', 'longdesc']
# end
#
def sanitized_allowed_attributes=(attributes)
sanitizer_vendor.safe_list_sanitizer.allowed_attributes = attributes
end
[:protocol_separator,
:uri_attributes,
:bad_tags,
:allowed_css_properties,
:allowed_css_keywords,
:shorthand_css_properties,
:allowed_protocols].each do |meth|
meth_name = "sanitized_#{meth}"
define_method(meth_name) { deprecate_option(meth_name) }
define_method("#{meth_name}=") { |_| deprecate_option("#{meth_name}=") }
end
private
def deprecate_option(name)
ActiveSupport::Deprecation.warn "The #{name} option is deprecated " \
"and has no effect. Until Rails 5 the old behavior can still be " \
"installed. To do this add the `rails-deprecated-sanitizer` to " \
"your Gemfile. Consult the Rails 4.2 upgrade guide for more information."
end
end
end
end
end
rails-rails-html-sanitizer-a8a0413/lib/rails/ 0000775 0000000 0000000 00000000000 15147370663 0021123 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/lib/rails/html/ 0000775 0000000 0000000 00000000000 15147370663 0022067 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/lib/rails/html/sanitizer.rb 0000664 0000000 0000000 00000035152 15147370663 0024432 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
module Rails
module HTML
class Sanitizer
class << self
def html5_support?
return @html5_support if defined?(@html5_support)
@html5_support = Loofah.respond_to?(:html5_support?) && Loofah.html5_support?
end
def best_supported_vendor
html5_support? ? Rails::HTML5::Sanitizer : Rails::HTML4::Sanitizer
end
def allowed_uri?(uri_string)
Loofah::HTML5::Scrub.allowed_uri?(uri_string)
end
end
def sanitize(html, options = {})
raise NotImplementedError, "subclasses must implement sanitize method."
end
private
def remove_xpaths(node, xpaths)
node.xpath(*xpaths).remove
node
end
def properly_encode(fragment, options)
fragment.xml? ? fragment.to_xml(options) : fragment.to_html(options)
end
end
module Concern
module ComposedSanitize
def sanitize(html, options = {})
return unless html
return html if html.empty?
serialize(scrub(parse_fragment(html), options))
end
end
module Parser
module HTML4
def parse_fragment(html)
Loofah.html4_fragment(html)
end
end
module HTML5
def parse_fragment(html)
Loofah.html5_fragment(html)
end
end if Rails::HTML::Sanitizer.html5_support?
end
module Scrubber
module Full
def scrub(fragment, options = {})
fragment.scrub!(TextOnlyScrubber.new)
end
end
module Link
def initialize
super
@link_scrubber = TargetScrubber.new
@link_scrubber.tags = %w(a)
@link_scrubber.attributes = %w(href)
end
def scrub(fragment, options = {})
fragment.scrub!(@link_scrubber)
end
end
module SafeList
# The default safe list for tags
DEFAULT_ALLOWED_TAGS = Set.new([
"a",
"abbr",
"acronym",
"address",
"b",
"big",
"blockquote",
"br",
"cite",
"code",
"dd",
"del",
"dfn",
"div",
"dl",
"dt",
"em",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"hr",
"i",
"img",
"ins",
"kbd",
"li",
"mark",
"ol",
"p",
"pre",
"samp",
"small",
"span",
"strong",
"sub",
"sup",
"time",
"tt",
"ul",
"var",
]).freeze
# The default safe list for attributes
DEFAULT_ALLOWED_ATTRIBUTES = Set.new([
"abbr",
"alt",
"cite",
"class",
"datetime",
"height",
"href",
"lang",
"name",
"src",
"title",
"width",
"xml:lang",
]).freeze
def self.included(klass)
class << klass
attr_accessor :allowed_tags
attr_accessor :allowed_attributes
end
klass.allowed_tags = DEFAULT_ALLOWED_TAGS.dup
klass.allowed_attributes = DEFAULT_ALLOWED_ATTRIBUTES.dup
end
def initialize(prune: false)
@permit_scrubber = PermitScrubber.new(prune: prune)
end
def scrub(fragment, options = {})
if scrubber = options[:scrubber]
# No duck typing, Loofah ensures subclass of Loofah::Scrubber
fragment.scrub!(scrubber)
elsif allowed_tags(options) || allowed_attributes(options)
@permit_scrubber.tags = allowed_tags(options)
@permit_scrubber.attributes = allowed_attributes(options)
fragment.scrub!(@permit_scrubber)
else
fragment.scrub!(:strip)
end
end
def sanitize_css(style_string)
Loofah::HTML5::Scrub.scrub_css(style_string)
end
private
def allowed_tags(options)
options[:tags] || self.class.allowed_tags
end
def allowed_attributes(options)
options[:attributes] || self.class.allowed_attributes
end
end
end
module Serializer
module UTF8Encode
def serialize(fragment)
properly_encode(fragment, encoding: "UTF-8")
end
end
end
end
end
module HTML4
module Sanitizer
module VendorMethods
def full_sanitizer
Rails::HTML4::FullSanitizer
end
def link_sanitizer
Rails::HTML4::LinkSanitizer
end
def safe_list_sanitizer
Rails::HTML4::SafeListSanitizer
end
def white_list_sanitizer # :nodoc:
safe_list_sanitizer
end
end
extend VendorMethods
end
# == Rails::HTML4::FullSanitizer
#
# Removes all tags from HTML4 but strips out scripts, forms and comments.
#
# full_sanitizer = Rails::HTML4::FullSanitizer.new
# full_sanitizer.sanitize("Bold no more! See more here...")
# # => "Bold no more! See more here..."
#
class FullSanitizer < Rails::HTML::Sanitizer
include HTML::Concern::ComposedSanitize
include HTML::Concern::Parser::HTML4
include HTML::Concern::Scrubber::Full
include HTML::Concern::Serializer::UTF8Encode
end
# == Rails::HTML4::LinkSanitizer
#
# Removes +a+ tags and +href+ attributes from HTML4 leaving only the link text.
#
# link_sanitizer = Rails::HTML4::LinkSanitizer.new
# link_sanitizer.sanitize('Only the link text will be kept.')
# # => "Only the link text will be kept."
#
class LinkSanitizer < Rails::HTML::Sanitizer
include HTML::Concern::ComposedSanitize
include HTML::Concern::Parser::HTML4
include HTML::Concern::Scrubber::Link
include HTML::Concern::Serializer::UTF8Encode
end
# == Rails::HTML4::SafeListSanitizer
#
# Sanitizes HTML4 and CSS from an extensive safe list.
#
# === Whitespace
#
# We can't make any guarantees about whitespace being kept or stripped. Loofah uses Nokogiri,
# which wraps either a C or Java parser for the respective Ruby implementation. Those two
# parsers determine how whitespace is ultimately handled.
#
# When the stripped markup will be rendered the users browser won't take whitespace into account
# anyway. It might be better to suggest your users wrap their whitespace sensitive content in
# pre tags or that you do so automatically.
#
# === Options
#
# Sanitizes both html and css via the safe lists found in
# Rails::HTML::Concern::Scrubber::SafeList
#
# SafeListSanitizer also accepts options to configure the safe list used when sanitizing html.
# There's a class level option:
#
# Rails::HTML4::SafeListSanitizer.allowed_tags = %w(table tr td)
# Rails::HTML4::SafeListSanitizer.allowed_attributes = %w(id class style)
#
# Tags and attributes can also be passed to +sanitize+. Passed options take precedence over the
# class level options.
#
# === Examples
#
# safe_list_sanitizer = Rails::HTML4::SafeListSanitizer.new
#
# # default: sanitize via a extensive safe list of allowed elements
# safe_list_sanitizer.sanitize(@article.body)
#
# # sanitize via the supplied tags and attributes
# safe_list_sanitizer.sanitize(
# @article.body,
# tags: %w(table tr td),
# attributes: %w(id class style),
# )
#
# # sanitize via a custom Loofah scrubber
# safe_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
#
# # prune nodes from the tree instead of stripping tags and leaving inner content
# safe_list_sanitizer = Rails::HTML4::SafeListSanitizer.new(prune: true)
#
# # the sanitizer can also sanitize CSS
# safe_list_sanitizer.sanitize_css('background-color: #000;')
#
class SafeListSanitizer < Rails::HTML::Sanitizer
include HTML::Concern::ComposedSanitize
include HTML::Concern::Parser::HTML4
include HTML::Concern::Scrubber::SafeList
include HTML::Concern::Serializer::UTF8Encode
end
end
module HTML5
class Sanitizer
class << self
def full_sanitizer
Rails::HTML5::FullSanitizer
end
def link_sanitizer
Rails::HTML5::LinkSanitizer
end
def safe_list_sanitizer
Rails::HTML5::SafeListSanitizer
end
def white_list_sanitizer # :nodoc:
safe_list_sanitizer
end
end
end
# == Rails::HTML5::FullSanitizer
#
# Removes all tags from HTML5 but strips out scripts, forms and comments.
#
# full_sanitizer = Rails::HTML5::FullSanitizer.new
# full_sanitizer.sanitize("Bold no more! See more here...")
# # => "Bold no more! See more here..."
#
class FullSanitizer < Rails::HTML::Sanitizer
include HTML::Concern::ComposedSanitize
include HTML::Concern::Parser::HTML5
include HTML::Concern::Scrubber::Full
include HTML::Concern::Serializer::UTF8Encode
end
# == Rails::HTML5::LinkSanitizer
#
# Removes +a+ tags and +href+ attributes from HTML5 leaving only the link text.
#
# link_sanitizer = Rails::HTML5::LinkSanitizer.new
# link_sanitizer.sanitize('Only the link text will be kept.')
# # => "Only the link text will be kept."
#
class LinkSanitizer < Rails::HTML::Sanitizer
include HTML::Concern::ComposedSanitize
include HTML::Concern::Parser::HTML5
include HTML::Concern::Scrubber::Link
include HTML::Concern::Serializer::UTF8Encode
end
# == Rails::HTML5::SafeListSanitizer
#
# Sanitizes HTML5 and CSS from an extensive safe list.
#
# === Whitespace
#
# We can't make any guarantees about whitespace being kept or stripped. Loofah uses Nokogiri,
# which wraps either a C or Java parser for the respective Ruby implementation. Those two
# parsers determine how whitespace is ultimately handled.
#
# When the stripped markup will be rendered the users browser won't take whitespace into account
# anyway. It might be better to suggest your users wrap their whitespace sensitive content in
# pre tags or that you do so automatically.
#
# === Options
#
# Sanitizes both html and css via the safe lists found in
# Rails::HTML::Concern::Scrubber::SafeList
#
# SafeListSanitizer also accepts options to configure the safe list used when sanitizing html.
# There's a class level option:
#
# Rails::HTML5::SafeListSanitizer.allowed_tags = %w(table tr td)
# Rails::HTML5::SafeListSanitizer.allowed_attributes = %w(id class style)
#
# Tags and attributes can also be passed to +sanitize+. Passed options take precedence over the
# class level options.
#
# === Examples
#
# safe_list_sanitizer = Rails::HTML5::SafeListSanitizer.new
#
# # default: sanitize via a extensive safe list of allowed elements
# safe_list_sanitizer.sanitize(@article.body)
#
# # sanitize via the supplied tags and attributes
# safe_list_sanitizer.sanitize(
# @article.body,
# tags: %w(table tr td),
# attributes: %w(id class style),
# )
#
# # sanitize via a custom Loofah scrubber
# safe_list_sanitizer.sanitize(@article.body, scrubber: ArticleScrubber.new)
#
# # prune nodes from the tree instead of stripping tags and leaving inner content
# safe_list_sanitizer = Rails::HTML5::SafeListSanitizer.new(prune: true)
#
# # the sanitizer can also sanitize CSS
# safe_list_sanitizer.sanitize_css('background-color: #000;')
#
class SafeListSanitizer < Rails::HTML::Sanitizer
include HTML::Concern::ComposedSanitize
include HTML::Concern::Parser::HTML5
include HTML::Concern::Scrubber::SafeList
include HTML::Concern::Serializer::UTF8Encode
end
end if Rails::HTML::Sanitizer.html5_support?
module HTML
Sanitizer.extend(HTML4::Sanitizer::VendorMethods) # :nodoc:
FullSanitizer = HTML4::FullSanitizer # :nodoc:
LinkSanitizer = HTML4::LinkSanitizer # :nodoc:
SafeListSanitizer = HTML4::SafeListSanitizer # :nodoc:
WhiteListSanitizer = SafeListSanitizer # :nodoc:
end
end
rails-rails-html-sanitizer-a8a0413/lib/rails/html/sanitizer/ 0000775 0000000 0000000 00000000000 15147370663 0024077 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/lib/rails/html/sanitizer/version.rb 0000664 0000000 0000000 00000000170 15147370663 0026107 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
module Rails
module HTML
class Sanitizer
VERSION = "1.7.0"
end
end
end
rails-rails-html-sanitizer-a8a0413/lib/rails/html/scrubbers.rb 0000664 0000000 0000000 00000015565 15147370663 0024422 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
module Rails
module HTML
# === Rails::HTML::PermitScrubber
#
# +Rails::HTML::PermitScrubber+ allows you to permit only your own tags and/or attributes.
#
# +Rails::HTML::PermitScrubber+ can be subclassed to determine:
# - When a node should be skipped via +skip_node?+.
# - When a node is allowed via +allowed_node?+.
# - When an attribute should be scrubbed via +scrub_attribute?+.
#
# Subclasses don't need to worry if tags or attributes are set or not.
# If tags or attributes are not set, Loofah's behavior will be used.
# If you override +allowed_node?+ and no tags are set, it will not be called.
# Instead Loofahs behavior will be used.
# Likewise for +scrub_attribute?+ and attributes respectively.
#
# Text and CDATA nodes are skipped by default.
# Unallowed elements will be stripped, i.e. element is removed but its subtree kept.
# Supplied tags and attributes should be Enumerables.
#
# +tags=+
# If set, elements excluded will be stripped.
# If not, elements are stripped based on Loofahs +HTML5::Scrub.allowed_element?+.
#
# +attributes=+
# If set, attributes excluded will be removed.
# If not, attributes are removed based on Loofahs +HTML5::Scrub.scrub_attributes+.
#
# class CommentScrubber < Rails::HTML::PermitScrubber
# def initialize
# super
# self.tags = %w(form script comment blockquote)
# end
#
# def skip_node?(node)
# node.text?
# end
#
# def scrub_attribute?(name)
# name == "style"
# end
# end
#
# See the documentation for +Nokogiri::XML::Node+ to understand what's possible
# with nodes: https://nokogiri.org/rdoc/Nokogiri/XML/Node.html
class PermitScrubber < Loofah::Scrubber
attr_reader :tags, :attributes, :prune
def initialize(prune: false)
@prune = prune
@direction = @prune ? :top_down : :bottom_up
@tags, @attributes = nil, nil
end
def tags=(tags)
@tags = validate!(tags.dup, :tags)
end
def attributes=(attributes)
@attributes = validate!(attributes.dup, :attributes)
end
def scrub(node)
if Loofah::HTML5::Scrub.cdata_needs_escaping?(node)
replacement = Loofah::HTML5::Scrub.cdata_escape(node)
node.replace(replacement)
return CONTINUE
end
return CONTINUE if skip_node?(node)
unless (node.element? || node.comment?) && keep_node?(node)
return STOP unless scrub_node(node) == CONTINUE
end
scrub_attributes(node)
CONTINUE
end
protected
def allowed_node?(node)
@tags.include?(node.name)
end
def skip_node?(node)
node.text?
end
def scrub_attribute?(name)
!@attributes.include?(name)
end
def keep_node?(node)
if @tags
allowed_node?(node)
else
Loofah::HTML5::Scrub.allowed_element?(node.name)
end
end
def scrub_node(node)
# If a node has a namespace, then it's a tag in either a `math` or `svg` foreign context,
# and we should always prune it to avoid namespace confusion and mutation XSS vectors.
unless prune || node.namespace
node.before(node.children)
end
node.remove
end
def scrub_attributes(node)
if @attributes
node.attribute_nodes.each do |attr|
if scrub_attribute?(attr.name)
attr.remove
else
scrub_attribute(node, attr)
end
end
scrub_css_attribute(node)
else
Loofah::HTML5::Scrub.scrub_attributes(node)
end
end
def scrub_css_attribute(node)
if Loofah::HTML5::Scrub.respond_to?(:scrub_css_attribute)
Loofah::HTML5::Scrub.scrub_css_attribute(node)
else
style = node.attributes["style"]
style.value = Loofah::HTML5::Scrub.scrub_css(style.value) if style
end
end
def validate!(var, name)
if var && !var.is_a?(Enumerable)
raise ArgumentError, "You should pass :#{name} as an Enumerable"
end
if var && name == :tags
if var.include?("mglyph")
warn("WARNING: 'mglyph' tags cannot be allowed by the PermitScrubber and will be scrubbed")
var.delete("mglyph")
end
if var.include?("malignmark")
warn("WARNING: 'malignmark' tags cannot be allowed by the PermitScrubber and will be scrubbed")
var.delete("malignmark")
end
if var.include?("noscript")
warn("WARNING: 'noscript' tags cannot be allowed by the PermitScrubber and will be scrubbed")
var.delete("noscript")
end
end
var
end
def scrub_attribute(node, attr_node)
attr_name = if attr_node.namespace
"#{attr_node.namespace.prefix}:#{attr_node.node_name}"
else
attr_node.node_name
end
return if Loofah::HTML5::SafeList::ATTR_VAL_IS_URI.include?(attr_name) && Loofah::HTML5::Scrub.scrub_uri_attribute(attr_node)
if Loofah::HTML5::SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
Loofah::HTML5::Scrub.scrub_attribute_that_allows_local_ref(attr_node)
end
if Loofah::HTML5::SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == "xlink:href" && attr_node.value =~ /^\s*[^#\s].*/m
attr_node.remove
end
node.remove_attribute(attr_node.name) if attr_name == "src" && attr_node.value !~ /[^[:space:]]/
Loofah::HTML5::Scrub.force_correct_attribute_escaping! node
end
end
# === Rails::HTML::TargetScrubber
#
# Where +Rails::HTML::PermitScrubber+ picks out tags and attributes to permit in
# sanitization, +Rails::HTML::TargetScrubber+ targets them for removal.
#
# +tags=+
# If set, elements included will be stripped.
#
# +attributes=+
# If set, attributes included will be removed.
class TargetScrubber < PermitScrubber
def allowed_node?(node)
!super
end
def scrub_attribute?(name)
!super
end
end
# === Rails::HTML::TextOnlyScrubber
#
# +Rails::HTML::TextOnlyScrubber+ allows you to permit text nodes.
#
# Unallowed elements will be stripped, i.e. element is removed but its subtree kept.
class TextOnlyScrubber < Loofah::Scrubber
def initialize
@direction = :bottom_up
end
def scrub(node)
if node.text?
CONTINUE
else
node.before node.children
node.remove
end
end
end
end
end
rails-rails-html-sanitizer-a8a0413/rails-html-sanitizer.gemspec 0000664 0000000 0000000 00000003223 15147370663 0024672 0 ustar 00root root 0000000 0000000 # coding: utf-8
# frozen_string_literal: true
require_relative "lib/rails/html/sanitizer/version"
Gem::Specification.new do |spec|
spec.name = "rails-html-sanitizer"
spec.version = Rails::HTML::Sanitizer::VERSION
spec.authors = ["Rafael Mendonça França", "Kasper Timm Hansen", "Mike Dalessio"]
spec.email = ["rafaelmfranca@gmail.com", "kaspth@gmail.com", "mike.dalessio@gmail.com"]
spec.description = "HTML sanitization for Rails applications"
spec.summary = "This gem is responsible to sanitize HTML fragments in Rails applications."
spec.homepage = "https://github.com/rails/rails-html-sanitizer"
spec.license = "MIT"
spec.required_ruby_version = ">= 2.7.0"
spec.metadata = {
"bug_tracker_uri" => "https://github.com/rails/rails-html-sanitizer/issues",
"changelog_uri" => "https://github.com/rails/rails-html-sanitizer/blob/v#{spec.version}/CHANGELOG.md",
"documentation_uri" => "https://www.rubydoc.info/gems/rails-html-sanitizer/#{spec.version}",
"source_code_uri" => "https://github.com/rails/rails-html-sanitizer/tree/v#{spec.version}",
}
spec.files = Dir["lib/**/*", "README.md", "MIT-LICENSE", "CHANGELOG.md"]
spec.test_files = Dir["test/**/*"]
spec.require_paths = ["lib"]
spec.add_dependency "loofah", "~> 2.25"
# A fix was shipped in nokogiri v1.15.7 and v1.16.8 without which there is a vulnerability in this gem.
spec.add_dependency "nokogiri", [">=1.15.7",
"!=1.16.0", "!=1.16.0.rc1", "!=1.16.1", "!=1.16.2", "!=1.16.3",
"!=1.16.4", "!=1.16.5", "!=1.16.6", "!=1.16.7"]
end
rails-rails-html-sanitizer-a8a0413/test/ 0000775 0000000 0000000 00000000000 15147370663 0020222 5 ustar 00root root 0000000 0000000 rails-rails-html-sanitizer-a8a0413/test/rails_api_test.rb 0000664 0000000 0000000 00000007644 15147370663 0023564 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
require_relative "test_helper"
class RailsApiTest < Minitest::Test
def test_html_module_name_alias
assert_equal(Rails::Html, Rails::HTML)
assert_equal("Rails::HTML", Rails::Html.name)
assert_equal("Rails::HTML", Rails::HTML.name)
end
def test_html_scrubber_class_names
assert(Rails::Html::PermitScrubber)
assert(Rails::Html::TargetScrubber)
assert(Rails::Html::TextOnlyScrubber)
assert(Rails::Html::Sanitizer)
end
def test_best_supported_vendor_when_html5_is_not_supported_returns_html4
Rails::HTML::Sanitizer.stub(:html5_support?, false) do
assert_equal(Rails::HTML4::Sanitizer, Rails::HTML::Sanitizer.best_supported_vendor)
end
end
def test_best_supported_vendor_when_html5_is_supported_returns_html5
skip("no HTML5 support on this platform") unless Rails::HTML::Sanitizer.html5_support?
Rails::HTML::Sanitizer.stub(:html5_support?, true) do
assert_equal(Rails::HTML5::Sanitizer, Rails::HTML::Sanitizer.best_supported_vendor)
end
end
def test_html4_sanitizer_alias_full
assert_equal(Rails::HTML4::FullSanitizer, Rails::HTML::FullSanitizer)
assert_equal("Rails::HTML4::FullSanitizer", Rails::HTML::FullSanitizer.name)
end
def test_html4_sanitizer_alias_link
assert_equal(Rails::HTML4::LinkSanitizer, Rails::HTML::LinkSanitizer)
assert_equal("Rails::HTML4::LinkSanitizer", Rails::HTML::LinkSanitizer.name)
end
def test_html4_sanitizer_alias_safe_list
assert_equal(Rails::HTML4::SafeListSanitizer, Rails::HTML::SafeListSanitizer)
assert_equal("Rails::HTML4::SafeListSanitizer", Rails::HTML::SafeListSanitizer.name)
end
def test_html4_full_sanitizer
assert_equal(Rails::HTML4::FullSanitizer, Rails::HTML::Sanitizer.full_sanitizer)
assert_equal(Rails::HTML4::FullSanitizer, Rails::HTML4::Sanitizer.full_sanitizer)
end
def test_html4_link_sanitizer
assert_equal(Rails::HTML4::LinkSanitizer, Rails::HTML::Sanitizer.link_sanitizer)
assert_equal(Rails::HTML4::LinkSanitizer, Rails::HTML4::Sanitizer.link_sanitizer)
end
def test_html4_safe_list_sanitizer
assert_equal(Rails::HTML4::SafeListSanitizer, Rails::HTML::Sanitizer.safe_list_sanitizer)
assert_equal(Rails::HTML4::SafeListSanitizer, Rails::HTML4::Sanitizer.safe_list_sanitizer)
end
def test_html4_white_list_sanitizer
assert_equal(Rails::HTML4::SafeListSanitizer, Rails::HTML::Sanitizer.white_list_sanitizer)
assert_equal(Rails::HTML4::SafeListSanitizer, Rails::HTML4::Sanitizer.white_list_sanitizer)
end
def test_html5_full_sanitizer
skip("no HTML5 support on this platform") unless Rails::HTML::Sanitizer.html5_support?
assert_equal(Rails::HTML5::FullSanitizer, Rails::HTML5::Sanitizer.full_sanitizer)
end
def test_html5_link_sanitizer
skip("no HTML5 support on this platform") unless Rails::HTML::Sanitizer.html5_support?
assert_equal(Rails::HTML5::LinkSanitizer, Rails::HTML5::Sanitizer.link_sanitizer)
end
def test_html5_safe_list_sanitizer
skip("no HTML5 support on this platform") unless Rails::HTML::Sanitizer.html5_support?
assert_equal(Rails::HTML5::SafeListSanitizer, Rails::HTML5::Sanitizer.safe_list_sanitizer)
end
def test_html5_white_list_sanitizer
skip("no HTML5 support on this platform") unless Rails::HTML::Sanitizer.html5_support?
assert_equal(Rails::HTML5::SafeListSanitizer, Rails::HTML5::Sanitizer.white_list_sanitizer)
end
def test_allowed_uri_returns_true_for_allowed_protocols
assert(Rails::HTML::Sanitizer.allowed_uri?("https://example.com"))
assert(Rails::HTML::Sanitizer.allowed_uri?("http://example.com"))
assert(Rails::HTML::Sanitizer.allowed_uri?("mailto:user@example.com"))
end
def test_allowed_uri_returns_false_for_disallowed_protocols
refute(Rails::HTML::Sanitizer.allowed_uri?("javascript:alert(1)"))
end
def test_allowed_uri_returns_true_for_relative_uris
assert(Rails::HTML::Sanitizer.allowed_uri?("/relative/path"))
end
end
rails-rails-html-sanitizer-a8a0413/test/sanitizer_test.rb 0000664 0000000 0000000 00000132572 15147370663 0023630 0 ustar 00root root 0000000 0000000 # frozen_string_literal: true
require_relative "test_helper"
#
# NOTE that many of these tests contain multiple acceptable results.
#
# In some cases, this is because of how the HTML4 parser's recovery behavior changed in libxml2
# 2.9.14 and 2.10.0. For more details, see:
#
# - https://github.com/sparklemotion/nokogiri/releases/tag/v1.13.5
# - https://gitlab.gnome.org/GNOME/libxml2/-/issues/380
#
# In other cases, multiple acceptable results are provided because Nokogiri's vendored libxml2 is
# patched to entity-escape server-side includes (aks "SSI", aka ``).
#
# In many other cases, it's because the parser used by Nokogiri on JRuby (xerces+nekohtml) parses
# slightly differently than libxml2 in edge cases.
#
module SanitizerTests
def self.loofah_html5_support?
Loofah.respond_to?(:html5_support?) && Loofah.html5_support?
end
class BaseSanitizerTest < Minitest::Test
class XpathRemovalTestSanitizer < Rails::HTML::Sanitizer
def sanitize(html, options = {})
fragment = Loofah.fragment(html)
remove_xpaths(fragment, options[:xpaths]).to_s
end
end
def test_sanitizer_sanitize_raises_not_implemented_error
assert_raises NotImplementedError do
Rails::HTML::Sanitizer.new.sanitize("asdf")
end
end
def test_remove_xpaths_removes_an_xpath
html = %(
hello
hello
hi'
result = full_sanitize(input)
acceptable_results = [
# libxml2 >= 2.9.14 and xerces+neko
%{<" hi},
# other libxml2
%{ hi},
]
assert_includes(acceptable_results, result)
end
def test_strip_invalid_html
assert_equal "<<", full_sanitize("<<It no longer contains any HTML.
This is a test.
") end def test_escape_tags_with_many_open_quotes assert_equal "<<", full_sanitize("<<foo) assert_equal text, safe_list_sanitize(text) end def test_should_allow_custom_tags_with_custom_attributes text = %(
Lorem ipsum) assert_equal text, safe_list_sanitize(text, attributes: ["foo"]) end def test_scrub_style_if_style_attribute_option_is_passed input = '' actual = safe_list_sanitize(input, attributes: %w(style)) assert_includes(['', ''], actual) end def test_should_raise_argument_error_if_tags_is_not_enumerable assert_raises ArgumentError do safe_list_sanitize("some html", tags: "foo") end end def test_should_raise_argument_error_if_attributes_is_not_enumerable assert_raises ArgumentError do safe_list_sanitize("some html", attributes: "foo") end end def test_should_not_accept_non_loofah_inheriting_scrubber scrubber = Object.new def scrubber.scrub(node); node.name = "h1"; end assert_raises Loofah::ScrubberNotFound do safe_list_sanitize("some html", scrubber: scrubber) end end def test_should_accept_loofah_inheriting_scrubber scrubber = Loofah::Scrubber.new def scrubber.scrub(node); node.replace("