gemirro 3.0.0 → 3.0.1
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 +4 -4
- data/Gemfile.lock +1 -1
- data/MANIFEST +1 -0
- data/lib/gemirro/utils.rb +27 -0
- data/lib/gemirro/version.rb +1 -1
- data/spec/gemirro/server_spec.rb +33 -0
- data/spec/gemirro/utils_spec.rb +43 -0
- data/views/gem.erb +6 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bb35f2d2c69224e8bebd764161f0c855af924b03ab98eb0089473d11489a6ec9
|
|
4
|
+
data.tar.gz: 4fb54e6dcce8923151dd273f4e5b45f8f64e90a6ad28cc8c06d8ed3c10085893
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e5bb871e3788098502d5f76a6b6b568910c511392d21c53b13b6e069e2c1fc85329bea413d6ae6c02efd55a0a0d3a6c5d432d4dccfb2487c1b607136188286f2
|
|
7
|
+
data.tar.gz: bc363cf380cb471dddac0c68717112d3c15169175c2aba17503e46e566bc9a170e49ebf810a3c3e9c761acee1e65dcd4c9379fb833aeabc0b4ade2a3bb7749b1
|
data/Gemfile.lock
CHANGED
data/MANIFEST
CHANGED
|
@@ -45,6 +45,7 @@ spec/gemirro/mirror_directory_spec.rb
|
|
|
45
45
|
spec/gemirro/mirror_file_spec.rb
|
|
46
46
|
spec/gemirro/server_spec.rb
|
|
47
47
|
spec/gemirro/source_spec.rb
|
|
48
|
+
spec/gemirro/utils_spec.rb
|
|
48
49
|
spec/gemirro/versions_fetcher_spec.rb
|
|
49
50
|
spec/gemirro/versions_file_spec.rb
|
|
50
51
|
spec/spec_helper.rb
|
data/lib/gemirro/utils.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'addressable/uri'
|
|
3
4
|
require 'gemirro/gem_version'
|
|
4
5
|
|
|
5
6
|
module Gemirro
|
|
@@ -25,6 +26,7 @@ module Gemirro
|
|
|
25
26
|
URI_REGEXP = /^(.*)-(\d+(?:\.\d+){1,4}.*?)(?:-(x86-(?:(?:mswin|mingw)(?:32|64)).*?|java))?\.(gem(?:spec\.rz)?)$/
|
|
26
27
|
GEMSPEC_TYPE = 'gemspec.rz'
|
|
27
28
|
GEM_TYPE = 'gem'
|
|
29
|
+
SAFE_HOMEPAGE_SCHEMES = %w[http https].freeze
|
|
28
30
|
|
|
29
31
|
##
|
|
30
32
|
# Generate Gems collection from Marshal dump - always the .local file
|
|
@@ -156,6 +158,31 @@ module Gemirro
|
|
|
156
158
|
end
|
|
157
159
|
end
|
|
158
160
|
|
|
161
|
+
##
|
|
162
|
+
# Return a normalized homepage URL that is safe to use as a link target,
|
|
163
|
+
# or nil when it is missing, unparsable or not an http(s) URL with a host.
|
|
164
|
+
# Gem metadata comes from upstream sources and must not be trusted.
|
|
165
|
+
#
|
|
166
|
+
# @param [String] homepage
|
|
167
|
+
# @return [String, nil]
|
|
168
|
+
#
|
|
169
|
+
def self.safe_homepage(homepage)
|
|
170
|
+
return if homepage.nil?
|
|
171
|
+
|
|
172
|
+
# Browsers ignore control characters and whitespace inside a scheme
|
|
173
|
+
# (e.g. "java\tscript:"), so drop them before validating.
|
|
174
|
+
value = homepage.to_s.gsub(/[[:cntrl:][:space:]]/, '')
|
|
175
|
+
return if value.empty?
|
|
176
|
+
|
|
177
|
+
uri = Addressable::URI.parse(value).normalize
|
|
178
|
+
return unless SAFE_HOMEPAGE_SCHEMES.include?(uri.scheme&.downcase)
|
|
179
|
+
return if uri.host.nil? || uri.host.empty?
|
|
180
|
+
|
|
181
|
+
uri.to_s
|
|
182
|
+
rescue Addressable::URI::InvalidURIError, ArgumentError, TypeError
|
|
183
|
+
nil
|
|
184
|
+
end
|
|
185
|
+
|
|
159
186
|
##
|
|
160
187
|
# Try to fetch gem and download its if it's possible, and
|
|
161
188
|
# build and install indicies.
|
data/lib/gemirro/version.rb
CHANGED
data/spec/gemirro/server_spec.rb
CHANGED
|
@@ -81,6 +81,39 @@ module Gemirro
|
|
|
81
81
|
expect(last_response.status).to eq(200)
|
|
82
82
|
expect(last_response).to be_ok
|
|
83
83
|
end
|
|
84
|
+
|
|
85
|
+
it 'should not link a javascript: homepage from gem metadata' do
|
|
86
|
+
MirrorFile.new('/var/www/gemirro/versions.md5.aaa256.list').write(%(created_at: 2025-01-01T00:00:00Z\n---\nvolay 0.1.0 checksum))
|
|
87
|
+
spec = ::Gem::Specification.new do |s|
|
|
88
|
+
s.name = 'volay'
|
|
89
|
+
s.version = '0.1.0'
|
|
90
|
+
s.authors = ['Mallory']
|
|
91
|
+
s.homepage = 'javascript:alert(1)'
|
|
92
|
+
end
|
|
93
|
+
allow(Utils).to receive(:spec_for).and_return(spec)
|
|
94
|
+
|
|
95
|
+
get '/gem/volay'
|
|
96
|
+
|
|
97
|
+
expect(last_response).to be_ok
|
|
98
|
+
expect(last_response.body).to include('Mallory')
|
|
99
|
+
expect(last_response.body).not_to include('javascript:')
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'should link an https homepage from gem metadata' do
|
|
103
|
+
MirrorFile.new('/var/www/gemirro/versions.md5.aaa256.list').write(%(created_at: 2025-01-01T00:00:00Z\n---\nvolay 0.1.0 checksum))
|
|
104
|
+
spec = ::Gem::Specification.new do |s|
|
|
105
|
+
s.name = 'volay'
|
|
106
|
+
s.version = '0.1.0'
|
|
107
|
+
s.authors = ['Alice']
|
|
108
|
+
s.homepage = 'https://example.com/volay'
|
|
109
|
+
end
|
|
110
|
+
allow(Utils).to receive(:spec_for).and_return(spec)
|
|
111
|
+
|
|
112
|
+
get '/gem/volay'
|
|
113
|
+
|
|
114
|
+
expect(last_response).to be_ok
|
|
115
|
+
expect(last_response.body).to include('href="https://example.com/volay"')
|
|
116
|
+
end
|
|
84
117
|
|
|
85
118
|
it 'responds to compact_index /names' do
|
|
86
119
|
MirrorFile.new('/var/www/gemirro/names.md5.aaa256.list').write(%(---\nvolay))
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'gemirro/utils'
|
|
5
|
+
|
|
6
|
+
# Utils tests
|
|
7
|
+
module Gemirro
|
|
8
|
+
describe Utils do
|
|
9
|
+
describe '.safe_homepage' do
|
|
10
|
+
it 'keeps http and https URLs' do
|
|
11
|
+
expect(Utils.safe_homepage('http://example.com')).to eq('http://example.com/')
|
|
12
|
+
expect(Utils.safe_homepage('https://example.com/foo?a=1')).to eq('https://example.com/foo?a=1')
|
|
13
|
+
expect(Utils.safe_homepage('HTTPS://Example.com/x')).to eq('https://example.com/x')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'rejects missing or empty values' do
|
|
17
|
+
expect(Utils.safe_homepage(nil)).to be_nil
|
|
18
|
+
expect(Utils.safe_homepage('')).to be_nil
|
|
19
|
+
expect(Utils.safe_homepage(" \n")).to be_nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
[
|
|
23
|
+
'javascript:alert(1)',
|
|
24
|
+
'JavaScript:alert(1)',
|
|
25
|
+
' javascript:alert(1)',
|
|
26
|
+
"java\tscript:alert(1)",
|
|
27
|
+
"java\nscript:alert(1)",
|
|
28
|
+
"\u0000javascript:alert(1)",
|
|
29
|
+
'data:text/html,<script>alert(1)</script>',
|
|
30
|
+
'vbscript:msgbox(1)',
|
|
31
|
+
'file:///etc/passwd',
|
|
32
|
+
'javascript%3Aalert(1)',
|
|
33
|
+
'//evil.example.com',
|
|
34
|
+
'/relative/path',
|
|
35
|
+
'https://'
|
|
36
|
+
].each do |value|
|
|
37
|
+
it "rejects #{value.inspect}" do
|
|
38
|
+
expect(Utils.safe_homepage(value)).to be_nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/views/gem.erb
CHANGED
|
@@ -34,12 +34,17 @@
|
|
|
34
34
|
<% end %>
|
|
35
35
|
|
|
36
36
|
<% if spec.authors.size > 0 %>
|
|
37
|
+
<% homepage = Gemirro::Utils.safe_homepage(spec.homepage) %>
|
|
37
38
|
<dd class="authors">
|
|
38
39
|
<h3>Authors</h3>
|
|
39
40
|
<ul>
|
|
40
41
|
<% spec.authors.each do |author| %>
|
|
41
42
|
<li class="list-group-item">
|
|
42
|
-
|
|
43
|
+
<% if homepage %>
|
|
44
|
+
<a href="<%= Rack::Utils.escape_html(homepage) %>" rel="noopener noreferrer nofollow"><%= Rack::Utils.escape_html(author) %></a>
|
|
45
|
+
<% else %>
|
|
46
|
+
<%= Rack::Utils.escape_html(author) %>
|
|
47
|
+
<% end %>
|
|
43
48
|
</li>
|
|
44
49
|
<% end %>
|
|
45
50
|
</ul>
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gemirro
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pierre Rambaud
|
|
@@ -245,6 +245,7 @@ files:
|
|
|
245
245
|
- spec/gemirro/mirror_file_spec.rb
|
|
246
246
|
- spec/gemirro/server_spec.rb
|
|
247
247
|
- spec/gemirro/source_spec.rb
|
|
248
|
+
- spec/gemirro/utils_spec.rb
|
|
248
249
|
- spec/gemirro/versions_fetcher_spec.rb
|
|
249
250
|
- spec/gemirro/versions_file_spec.rb
|
|
250
251
|
- spec/spec_helper.rb
|