publify_core 9.2.1 → 9.2.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of publify_core might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b54212d5fc4e4291890a1aa527561a41dc19ad64d58841c0407e14f9e6ccebc
4
- data.tar.gz: 7ebc8493ba977031d7ebcb3ac4a659fcf248d419a97ee09418a618eb29cee2dc
3
+ metadata.gz: 8598a2b44749716a7bf3f75ab494ff6ba4ef327f29d6606ed3fd21ccce7df918
4
+ data.tar.gz: b3f58570a4180cb07bfa2852d3bf0c10160feb9f14039875d6e5182fbb56a368
5
5
  SHA512:
6
- metadata.gz: 8a16d3eeec887dec33e6733d7eab215f1677e808dcecde23ab7b4a8c8b65df748a71bdfe74312e491c48183b18ea0814aa859ca4ba3971303f652ef5adca9846
7
- data.tar.gz: 53d08aac3318179a27a067755546f88b80fc24555fcff1d4d4c76aad7b2b4284d2dad3cb246858e929781bce8fee1c608b922d8f2c017b1c7729c0d547bfe912
6
+ metadata.gz: 5ceafbc0b711d3c0d113e61e9339c9175b6cf18afb08fded9321148d2b3b7ddf1809a9de8de0428f5364820d15de19a58a4b0a811018e6cc210357ccb49e868f
7
+ data.tar.gz: 7e476032ad37744aee63a7f746c81f020684857fedd43ff6468648ce1133280fd3efc7b78bea560ffd69d34b250dc120e05c767a44361eb376d91de54ecd2c35
data/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## 9.2.5 / 2021-10-11
4
+
5
+ This release fixes several security issues:
6
+
7
+ * Block ability to switch themes using a GET request; use a POST instead
8
+ * Disallow user self-registration rather than hiding it
9
+ * Let the browser not cache admin pages
10
+ * Limit the set of allowed mime types for uploaded media
11
+ * Limit allowed HTML in articles, pages and notes
12
+
13
+ Additionally, it includes the following changes:
14
+
15
+ * Fix resource size display in admin resource list
16
+ * Trigger download of media in the Media Library in admin instead of displaying
17
+ them directly
18
+
19
+ ## 9.2.4 / 2021-10-02
20
+
21
+ * Explicitly require at least version 1.12.5 of nokogiri to avoid a security issue
22
+ * Drop support for Ruby 2.4 since it is incompatible with nokogiri 1.12.5
23
+
24
+ ## 9.2.3 / 2021-05-22
25
+
26
+ * Bump Rails dependency to 5.2.6
27
+ * Replace mimemagic with marcel
28
+
29
+ ## 9.2.2 / 2021-03-21
30
+
31
+ * No changes
32
+
3
33
  ## 9.2.1 / 2021-03-20
4
34
 
5
35
  * No changes
@@ -10,6 +10,7 @@ class Admin::BaseController < BaseController
10
10
  layout "administration"
11
11
 
12
12
  before_action :login_required, except: [:login, :signup]
13
+ before_action :no_caching
13
14
 
14
15
  private
15
16
 
@@ -24,4 +25,9 @@ class Admin::BaseController < BaseController
24
25
  name: controller_name.humanize)
25
26
  redirect_to action: "index"
26
27
  end
28
+
29
+ def no_caching
30
+ response.cache_control[:extras] =
31
+ ["no-cache", "max-age=0", "must-revalidate", "no-store"]
32
+ end
27
33
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Users::RegistrationsController < Devise::RegistrationsController
4
+ include BlogHelper
5
+ before_action :require_signup_allowed
6
+
7
+ private
8
+
9
+ def require_signup_allowed
10
+ render plain: "Not found", status: :not_found unless this_blog.allow_signup?
11
+ end
12
+ end
@@ -240,10 +240,15 @@ module BaseHelper
240
240
  end
241
241
 
242
242
  def nofollowify_links(string)
243
+ raise ArgumentError, "string", "must be html_safe" unless string.html_safe?
244
+
243
245
  if this_blog.dofollowify
244
246
  string
245
247
  else
246
- string.gsub(/<a(.*?)>/i, '<a\1 rel="nofollow">')
248
+ followify_scrubber = Loofah::Scrubber.new do |node|
249
+ node.set_attribute "rel", "nofollow" if node.name == "a"
250
+ end
251
+ sanitize h(string), scrubber: followify_scrubber
247
252
  end
248
253
  end
249
254
 
@@ -225,10 +225,6 @@ class Article < Content
225
225
  published_at.to_i > blog.sp_article_auto_close.days.ago.to_i
226
226
  end
227
227
 
228
- def content_fields
229
- [:body, :extended]
230
- end
231
-
232
228
  # The web interface no longer distinguishes between separate "body" and
233
229
  # "extended" fields, and instead edits everything in a single edit field,
234
230
  # separating the extended content using "\<!--more-->".
@@ -50,8 +50,4 @@ class Comment < Feedback
50
50
  def originator
51
51
  author
52
52
  end
53
-
54
- def content_fields
55
- [:body]
56
- end
57
53
  end
@@ -5,6 +5,12 @@ module ContentBase
5
5
  base.extend ClassMethods
6
6
  end
7
7
 
8
+ class ContentTextHelpers
9
+ include ActionView::Helpers::UrlHelper
10
+ include ActionView::Helpers::TextHelper
11
+ include ActionView::Helpers::SanitizeHelper
12
+ end
13
+
8
14
  attr_accessor :just_changed_published_status
9
15
  alias just_changed_published_status? just_changed_published_status
10
16
 
@@ -26,7 +32,7 @@ module ContentBase
26
32
  elsif html_map(field)
27
33
  generate_html(field)
28
34
  else
29
- raise "Unknown field: #{field.inspect} in content.html"
35
+ raise ArgumentError, "Field #{field.inspect} is not valid for #{self.class}"
30
36
  end
31
37
  end
32
38
 
@@ -39,10 +45,10 @@ module ContentBase
39
45
  html_postprocess(field, html).to_s
40
46
  end
41
47
 
42
- # Post-process the HTML. This is a noop by default, but Comment overrides it
43
- # to enforce HTML sanity.
48
+ # Post-process the HTML
44
49
  def html_postprocess(_field, html)
45
- html
50
+ helper = ContentTextHelpers.new
51
+ helper.sanitize html
46
52
  end
47
53
 
48
54
  def html_preprocess(_field, html)
@@ -11,12 +11,6 @@ class Feedback < ApplicationRecord
11
11
  include PublifyGuid
12
12
  include ContentBase
13
13
 
14
- class ContentTextHelpers
15
- include ActionView::Helpers::UrlHelper
16
- include ActionView::Helpers::TextHelper
17
- include ActionView::Helpers::SanitizeHelper
18
- end
19
-
20
14
  validate :feedback_not_closed, on: :create
21
15
  validates :article, presence: true
22
16
 
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "mimemagic"
3
+ require "marcel"
4
4
 
5
5
  class ResourceUploader < CarrierWave::Uploader::Base
6
6
  include CarrierWave::MiniMagick
7
7
  before :cache, :check_image_content_type!
8
8
 
9
+ def content_type_allowlist
10
+ [%r{image/}, %r{audio/}, %r{video/}, "text/plain"]
11
+ end
12
+
9
13
  def store_dir
10
14
  "files/#{model.class.to_s.underscore}/#{model.id}"
11
15
  end
@@ -50,14 +54,9 @@ class ResourceUploader < CarrierWave::Uploader::Base
50
54
  content_type = nil
51
55
 
52
56
  File.open(new_file.path) do |fd|
53
- content_type = MimeMagic.by_magic(fd).try(:type)
57
+ content_type = Marcel::MimeType.for(fd)
54
58
  end
55
59
 
56
60
  content_type
57
61
  end
58
-
59
- # NOTE: This method was copied from MagicMimeBlacklist from CarrierWave 1.0.0.
60
- def filemagic
61
- @filemagic ||= FileMagic.new(FileMagic::MAGIC_MIME_TYPE)
62
- end
63
62
  end
@@ -33,38 +33,34 @@
33
33
  </tr>
34
34
  <% end %>
35
35
 
36
- <% for upload in @resources %>
36
+ <% for resource in @resources %>
37
37
  <tr>
38
38
  <td>
39
- <% if upload.mime =~ /image/ %>
40
- <a href="<%= upload.upload.medium.url %>" data-toggle="lightbox">
41
- <%= image_tag(upload.upload.thumb.url) %>
42
- </a>
39
+ <% if resource.mime =~ /image/ %>
40
+ <a href="<%= resource.upload.medium.url %>" data-toggle="lightbox">
41
+ <%= image_tag(resource.upload.thumb.url) %>
42
+ </a>
43
43
  <% else %>
44
- <%= link_to(upload.upload_url, upload.upload_url) %>
44
+ <%= link_to(resource.upload_url, resource.upload_url, download: resource.upload.identifier) %>
45
45
  <% end %>
46
46
  <p>
47
47
  <small>
48
- <% if upload.mime =~ /image/ %>
49
- <%= link_to(t('.thumbnail'), upload.upload.thumb.url) %> |
50
- <%= link_to(t('.medium_size'), upload.upload.medium.url) %> |
51
- <%= link_to(t('.original_size'), upload.upload.url) %> |
48
+ <% if resource.mime =~ /image/ %>
49
+ <%= link_to(t('.thumbnail'), resource.upload.thumb.url) %> |
50
+ <%= link_to(t('.medium_size'), resource.upload.medium.url) %> |
51
+ <%= link_to(t('.original_size'), resource.upload.url) %> |
52
52
  <% end %>
53
53
  <%= link_to(t('.delete'),
54
- { action: 'destroy', id: upload.id, search: params[:search], page: params[:page] },
54
+ { action: 'destroy', id: resource.id, search: params[:search], page: params[:page] },
55
55
  { confirm: t('.are_you_sure'), method: :delete }) %>
56
56
  </small>
57
57
  </p>
58
58
  </td>
59
59
  <td>
60
- <%= upload.mime %>
60
+ <%= resource.mime %>
61
61
  </td>
62
- <td><%= begin
63
- h upload.size
64
- rescue StandardError
65
- 0
66
- end %> bytes</td>
67
- <td><%= l(upload.created_at, format: :short) %></td>
62
+ <td><%= resource.upload.size %> bytes</td>
63
+ <td><%= l(resource.created_at, format: :short) %></td>
68
64
  </tr>
69
65
  <% end %>
70
66
  <%= display_pagination(@resources, 6) %>
@@ -16,10 +16,10 @@
16
16
  </div>
17
17
  <% else %>
18
18
  <div>
19
- <h3><%= link_to(theme.name, switch_url, title: t('.use_this_theme')) %></h3>
20
- <%= link_to(image_tag(preview_url, class: 'img-thumbnail'), switch_url, title: t('.use_this_theme')) %>
19
+ <h3><%= theme.name %></h3>
20
+ <%= image_tag(preview_url, class: 'img-thumbnail') %>
21
21
  <%= raw theme.description_html %>
22
- <p><%= link_to(t('.use_this_theme'), switch_url, class: 'btn btn-info') %></p>
22
+ <p><%= button_to(t('.use_this_theme'), switch_url, class: 'btn btn-info') %></p>
23
23
  </div>
24
24
  <% end %>
25
25
  </div>
@@ -5,7 +5,7 @@
5
5
  <p><%= link_to_permalink article, t('.continue_reading') %></p>
6
6
  </div>
7
7
  <% else %>
8
- <%= raw article.html(:body) %>
8
+ <%= article.html(:body) %>
9
9
  <% if article.extended? %>
10
10
  <div class="extended">
11
11
  <p><%= link_to_permalink article, t('.continue_reading') %></p>
@@ -1,4 +1,4 @@
1
1
  <% cache article do %>
2
- <%= raw article.html(:body) %>
3
- <%= raw article.html(:extended) %>
2
+ <%= article.html(:body) %>
3
+ <%= article.html(:extended) %>
4
4
  <% end %>
@@ -1,3 +1,3 @@
1
1
  <div id="viewpage">
2
- <%= raw html @page %>
2
+ <%= html @page %>
3
3
  </div>
@@ -6,7 +6,7 @@
6
6
  <%= t('.said') %> <%= display_date_and_time comment.created_at %>:
7
7
  </p>
8
8
  <div class="content">
9
- <%= raw nofollowify_links comment.generate_html(:body) %>
9
+ <%= nofollowify_links comment.generate_html(:body) %>
10
10
  <% unless comment.published? %>
11
11
  <div class="spamwarning">
12
12
  <%= t('.this_comment_has_been_flagged_for_moderator_approval') %>
@@ -1,7 +1,7 @@
1
1
  <% cache [note, note.user] do %>
2
2
  <article class='status'>
3
3
  <%= author_picture note %>
4
- <div class='p-name entry-title e-content entry-content article'><%= raw note.html(:body) %></div>
4
+ <div class='p-name entry-title e-content entry-content article'><%= note.html(:body) %></div>
5
5
  <footer>
6
6
  <small>
7
7
  <%= link_to_permalink(note, display_date_and_time(note.published_at)) %> |
@@ -2,7 +2,7 @@
2
2
  <% for note in @notes %>
3
3
  <div class='h-entry hentry h-as-note'>
4
4
  <article>
5
- <p class='p-name entry-title e-content entry-content article'><%= raw note.html(:body) %></p>
5
+ <p class='p-name entry-title e-content entry-content article'><%= note.html(:body) %></p>
6
6
  <footer>
7
7
  <small><%= link_to_permalink(note, display_date_and_time(note.published_at)) %></small>
8
8
  </footer>
data/config/routes.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Rails.application.routes.draw do
4
- devise_for :users
4
+ devise_for :users, controllers: { registrations: "users/registrations" }
5
+
5
6
  # TODO: use only in archive sidebar. See how made other system
6
7
  get ":year/:month", to: "articles#index", year: /\d{4}/, month: /\d{1,2}/,
7
8
  as: "articles_by_month", format: false
@@ -144,7 +145,7 @@ Rails.application.routes.draw do
144
145
  resources :themes, only: [:index], format: false do
145
146
  collection do
146
147
  get "preview"
147
- get "switchto"
148
+ post "switchto"
148
149
  end
149
150
  end
150
151
 
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <p>Hello!</p>
4
+ </body>
5
+ </html>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PublifyCore
4
- VERSION = "9.2.1"
4
+ VERSION = "9.2.5"
5
5
  end
@@ -82,16 +82,14 @@ class SpamProtection
82
82
  def query_rbls(rbls, *subdomains)
83
83
  rbls.each do |rbl|
84
84
  subdomains.uniq.each do |d|
85
- begin
86
- response = IPSocket.getaddress([d, rbl].join("."))
87
- if response.start_with?("127.0.0.")
88
- throw :hit,
89
- "#{rbl} positively resolved subdomain #{d} => #{response}"
90
- end
91
- rescue SocketError
92
- # NXDOMAIN response => negative: d is not in RBL
93
- next
85
+ response = IPSocket.getaddress([d, rbl].join("."))
86
+ if response.start_with?("127.0.0.")
87
+ throw :hit,
88
+ "#{rbl} positively resolved subdomain #{d} => #{response}"
94
89
  end
90
+ rescue SocketError
91
+ # NXDOMAIN response => negative: d is not in RBL
92
+ next
95
93
  end
96
94
  end
97
95
  false
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: publify_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.2.1
4
+ version: 9.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matijs van Zuijlen
8
8
  - Yannick François
9
9
  - Thomas Lecavellier
10
10
  - Frédéric de Villamil
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2021-03-20 00:00:00.000000000 Z
14
+ date: 2021-10-11 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: aasm
@@ -202,39 +202,39 @@ dependencies:
202
202
  - !ruby/object:Gem::Version
203
203
  version: 1.2.1
204
204
  - !ruby/object:Gem::Dependency
205
- name: mimemagic
205
+ name: mini_magick
206
206
  requirement: !ruby/object:Gem::Requirement
207
207
  requirements:
208
208
  - - "~>"
209
209
  - !ruby/object:Gem::Version
210
- version: 0.3.2
210
+ version: '4.9'
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: 4.9.4
211
214
  type: :runtime
212
215
  prerelease: false
213
216
  version_requirements: !ruby/object:Gem::Requirement
214
217
  requirements:
215
218
  - - "~>"
216
219
  - !ruby/object:Gem::Version
217
- version: 0.3.2
220
+ version: '4.9'
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: 4.9.4
218
224
  - !ruby/object:Gem::Dependency
219
- name: mini_magick
225
+ name: nokogiri
220
226
  requirement: !ruby/object:Gem::Requirement
221
227
  requirements:
222
- - - "~>"
223
- - !ruby/object:Gem::Version
224
- version: '4.9'
225
228
  - - ">="
226
229
  - !ruby/object:Gem::Version
227
- version: 4.9.4
230
+ version: 1.12.5
228
231
  type: :runtime
229
232
  prerelease: false
230
233
  version_requirements: !ruby/object:Gem::Requirement
231
234
  requirements:
232
- - - "~>"
233
- - !ruby/object:Gem::Version
234
- version: '4.9'
235
235
  - - ">="
236
236
  - !ruby/object:Gem::Version
237
- version: 4.9.4
237
+ version: 1.12.5
238
238
  - !ruby/object:Gem::Dependency
239
239
  name: rack
240
240
  requirement: !ruby/object:Gem::Requirement
@@ -255,20 +255,14 @@ dependencies:
255
255
  requirements:
256
256
  - - "~>"
257
257
  - !ruby/object:Gem::Version
258
- version: 5.2.4
259
- - - ">="
260
- - !ruby/object:Gem::Version
261
- version: 5.2.4.3
258
+ version: 5.2.6
262
259
  type: :runtime
263
260
  prerelease: false
264
261
  version_requirements: !ruby/object:Gem::Requirement
265
262
  requirements:
266
263
  - - "~>"
267
264
  - !ruby/object:Gem::Version
268
- version: 5.2.4
269
- - - ">="
270
- - !ruby/object:Gem::Version
271
- version: 5.2.4.3
265
+ version: 5.2.6
272
266
  - !ruby/object:Gem::Dependency
273
267
  name: rails_autolink
274
268
  requirement: !ruby/object:Gem::Requirement
@@ -700,6 +694,7 @@ files:
700
694
  - app/controllers/text_controller.rb
701
695
  - app/controllers/textfilter_controller.rb
702
696
  - app/controllers/theme_controller.rb
697
+ - app/controllers/users/registrations_controller.rb
703
698
  - app/controllers/xml_controller.rb
704
699
  - app/helpers/admin/base_helper.rb
705
700
  - app/helpers/admin/feedback_helper.rb
@@ -974,6 +969,7 @@ files:
974
969
  - lib/publify_core/testing_support/feed_assertions.rb
975
970
  - lib/publify_core/testing_support/fixtures/exploit.svg
976
971
  - lib/publify_core/testing_support/fixtures/fakepng.png
972
+ - lib/publify_core/testing_support/fixtures/just_some.html
977
973
  - lib/publify_core/testing_support/fixtures/otherfile.txt
978
974
  - lib/publify_core/testing_support/fixtures/testfile.png
979
975
  - lib/publify_core/testing_support/fixtures/testfile.txt
@@ -1004,7 +1000,7 @@ homepage: https://publify.github.io/
1004
1000
  licenses:
1005
1001
  - MIT
1006
1002
  metadata: {}
1007
- post_install_message:
1003
+ post_install_message:
1008
1004
  rdoc_options: []
1009
1005
  require_paths:
1010
1006
  - lib
@@ -1012,15 +1008,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
1012
1008
  requirements:
1013
1009
  - - ">="
1014
1010
  - !ruby/object:Gem::Version
1015
- version: 2.4.0
1011
+ version: 2.5.0
1016
1012
  required_rubygems_version: !ruby/object:Gem::Requirement
1017
1013
  requirements:
1018
1014
  - - ">="
1019
1015
  - !ruby/object:Gem::Version
1020
1016
  version: '0'
1021
1017
  requirements: []
1022
- rubygems_version: 3.2.3
1023
- signing_key:
1018
+ rubygems_version: 3.1.6
1019
+ signing_key:
1024
1020
  specification_version: 4
1025
1021
  summary: Core engine for the Publify blogging system.
1026
1022
  test_files: []