govspeak 5.5.0 → 5.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/govspeak/html_sanitizer.rb +10 -13
- data/lib/govspeak/version.rb +1 -1
- data/test/html_sanitizer_test.rb +15 -4
- metadata +4 -7
- data/lib/with_deep_merge.rb +0 -11
- data/test/with_deep_merge_test.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e0eb446c6565462c24ad3f78801c202917e9b20
|
4
|
+
data.tar.gz: 16455957358cc36b9e743974e885c61b48259227
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e89a5cc8e001699815ea701efef079fbf2ede8a25b99a0493f880135919c913f2186a3a2745fb4bd9bfa2331da156ba0b86da7e5b5a206eca4665dcf55a94a0
|
7
|
+
data.tar.gz: e5295b34106249a7bc73751852688f0e00a80242380eaa6a09c94b2e185f6d5648132881148fdbc2d6658cbadd5b4352da340a7c89e5cdadf3b990b7654fa41b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 5.6.0
|
2
|
+
|
3
|
+
* Update sanitize version to 4.6.x [#127](https://github.com/alphagov/govspeak/issues/127)
|
4
|
+
|
1
5
|
## 5.5.0
|
2
6
|
* Ignore links with blank or missing `href`s when extracting links from a document with `Govspeak::Document#extracted_links` [#124](https://github.com/alphagov/govspeak/pull/124)
|
3
7
|
|
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'addressable/uri'
|
2
2
|
require 'sanitize'
|
3
|
-
require 'with_deep_merge'
|
4
3
|
|
5
4
|
class Govspeak::HtmlSanitizer
|
6
|
-
include WithDeepMerge
|
7
5
|
|
8
6
|
class ImageSourceWhitelister
|
9
7
|
def initialize(allowed_image_hosts)
|
@@ -48,13 +46,12 @@ class Govspeak::HtmlSanitizer
|
|
48
46
|
if @allowed_image_hosts && @allowed_image_hosts.any?
|
49
47
|
transformers << ImageSourceWhitelister.new(@allowed_image_hosts)
|
50
48
|
end
|
51
|
-
Sanitize.clean(@dirty_html,
|
49
|
+
Sanitize.clean(@dirty_html, Sanitize::Config.merge(sanitize_config, transformers: transformers))
|
52
50
|
end
|
53
51
|
|
54
52
|
def sanitize_without_images
|
55
53
|
config = sanitize_config
|
56
|
-
config[:elements]
|
57
|
-
Sanitize.clean(@dirty_html, config)
|
54
|
+
Sanitize.clean(@dirty_html, Sanitize::Config.merge(config, elements: config[:elements] - ["img"]))
|
58
55
|
end
|
59
56
|
|
60
57
|
def button_sanitize_config
|
@@ -66,14 +63,14 @@ class Govspeak::HtmlSanitizer
|
|
66
63
|
end
|
67
64
|
|
68
65
|
def sanitize_config
|
69
|
-
|
66
|
+
Sanitize::Config.merge(
|
67
|
+
Sanitize::Config::RELAXED,
|
70
68
|
attributes: {
|
71
|
-
:all => Sanitize::Config::RELAXED[:attributes][:all] + [
|
72
|
-
"a" => Sanitize::Config::RELAXED[:attributes]["a"] +
|
73
|
-
"th" => Sanitize::Config::RELAXED[:attributes]["th"] + [
|
74
|
-
"td" => Sanitize::Config::RELAXED[:attributes]["td"] + [
|
75
|
-
}
|
76
|
-
|
77
|
-
})
|
69
|
+
:all => Sanitize::Config::RELAXED[:attributes][:all] + ["role", "aria-label"],
|
70
|
+
"a" => Sanitize::Config::RELAXED[:attributes]["a"] + button_sanitize_config,
|
71
|
+
"th" => Sanitize::Config::RELAXED[:attributes]["th"] + ["style"],
|
72
|
+
"td" => Sanitize::Config::RELAXED[:attributes]["td"] + ["style"],
|
73
|
+
}
|
74
|
+
)
|
78
75
|
end
|
79
76
|
end
|
data/lib/govspeak/version.rb
CHANGED
data/test/html_sanitizer_test.rb
CHANGED
@@ -53,13 +53,24 @@ class HtmlSanitizerTest < Minitest::Test
|
|
53
53
|
end
|
54
54
|
|
55
55
|
test "allows table cells and table headings without a style attribute" do
|
56
|
-
html = "<th>thing</th><td>thing</td>"
|
56
|
+
html = "<table><thead><tr><th>thing</th></tr></thead><tbody><tr><td>thing</td></tr></tbody></table>"
|
57
57
|
assert_equal html, Govspeak::HtmlSanitizer.new(html).sanitize
|
58
58
|
end
|
59
59
|
|
60
|
+
test "strips table cells and headings that appear outside a table" do
|
61
|
+
html = "<th>thing</th></tr><tr><td>thing</td>"
|
62
|
+
assert_equal 'thingthing', Govspeak::HtmlSanitizer.new(html).sanitize
|
63
|
+
end
|
64
|
+
|
65
|
+
test "normalizes table tags to inject missing rows and bodies like a browser does" do
|
66
|
+
html = "<table><th>thing</th><td>thing</td></table>"
|
67
|
+
assert_equal '<table><tbody><tr><th>thing</th><td>thing</td></tr></tbody></table>', Govspeak::HtmlSanitizer.new(html).sanitize
|
68
|
+
end
|
69
|
+
|
70
|
+
|
60
71
|
test "allows valid text-align properties on the style attribute for table cells and table headings" do
|
61
72
|
["left", "right", "center"].each do |alignment|
|
62
|
-
html = "<th style=\"text-align: #{alignment}\">thing</th><td style=\"text-align: #{alignment}\">thing</td>"
|
73
|
+
html = "<table><thead><tr><th style=\"text-align: #{alignment}\">thing</th></tr></thead><tbody><tr><td style=\"text-align: #{alignment}\">thing</td></tr></tbody></table>"
|
63
74
|
assert_equal html, Govspeak::HtmlSanitizer.new(html).sanitize
|
64
75
|
end
|
65
76
|
|
@@ -70,8 +81,8 @@ class HtmlSanitizerTest < Minitest::Test
|
|
70
81
|
"background-image: url(javascript:alert('XSS'))",
|
71
82
|
"expression(alert('XSS'));"
|
72
83
|
].each do |style|
|
73
|
-
html = "<th style=\"#{style}\">thing</th><td style=\"#{style}\">thing</td>"
|
74
|
-
assert_equal '<th>thing</th><td>thing</td>', Govspeak::HtmlSanitizer.new(html).sanitize
|
84
|
+
html = "<table><thead><tr><th style=\"#{style}\">thing</th></tr></thead><tbody><tr><td style=\"#{style}\">thing</td></tr></tbody></table>"
|
85
|
+
assert_equal '<table><thead><tr><th>thing</th></tr></thead><tbody><tr><td>thing</td></tr></tbody></table>', Govspeak::HtmlSanitizer.new(html).sanitize
|
75
86
|
end
|
76
87
|
end
|
77
88
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: govspeak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GOV.UK Dev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kramdown
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '4.6'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '4.6'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: nokogiri
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -279,7 +279,6 @@ files:
|
|
279
279
|
- lib/templates/attachment.html.erb
|
280
280
|
- lib/templates/contact.html.erb
|
281
281
|
- lib/templates/inline_attachment.html.erb
|
282
|
-
- lib/with_deep_merge.rb
|
283
282
|
- test/blockquote_extra_quote_remover_test.rb
|
284
283
|
- test/govspeak_attachments_image_test.rb
|
285
284
|
- test/govspeak_attachments_inline_test.rb
|
@@ -295,7 +294,6 @@ files:
|
|
295
294
|
- test/html_validator_test.rb
|
296
295
|
- test/presenters/h_card_presenter_test.rb
|
297
296
|
- test/test_helper.rb
|
298
|
-
- test/with_deep_merge_test.rb
|
299
297
|
homepage: http://github.com/alphagov/govspeak
|
300
298
|
licenses: []
|
301
299
|
metadata: {}
|
@@ -323,7 +321,6 @@ test_files:
|
|
323
321
|
- test/govspeak_link_extractor_test.rb
|
324
322
|
- test/govspeak_structured_headers_test.rb
|
325
323
|
- test/govspeak_button_test.rb
|
326
|
-
- test/with_deep_merge_test.rb
|
327
324
|
- test/blockquote_extra_quote_remover_test.rb
|
328
325
|
- test/govspeak_test_helper.rb
|
329
326
|
- test/govspeak_link_test.rb
|
data/lib/with_deep_merge.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
module WithDeepMerge
|
2
|
-
def deep_merge(base_object, other_object)
|
3
|
-
if base_object.is_a?(Hash) && other_object.is_a?(Hash)
|
4
|
-
base_object.merge(other_object) { |_, base_value, other_value|
|
5
|
-
deep_merge(base_value, other_value)
|
6
|
-
}
|
7
|
-
else
|
8
|
-
other_object
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'with_deep_merge'
|
2
|
-
|
3
|
-
class WithDeepMergeTest < Minitest::Test
|
4
|
-
include WithDeepMerge
|
5
|
-
|
6
|
-
def test_simple_merge
|
7
|
-
base_hash = { "a" => "b" }
|
8
|
-
other_hash = { "c" => "d" }
|
9
|
-
assert_equal({ "a" => "b", "c" => "d" }, deep_merge(base_hash, other_hash))
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_recursive_merge
|
13
|
-
base_hash = { "a" => { "b" => "c", "d" => "e" } }
|
14
|
-
other_hash = { "a" => { "b" => "z", "f" => "g" } }
|
15
|
-
assert_equal({ "a" => { "b" => "z", "d" => "e", "f" => "g" } },
|
16
|
-
deep_merge(base_hash, other_hash))
|
17
|
-
end
|
18
|
-
end
|