publify_core 9.2.4 → 9.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a656e67eabdbc775b90db037ea087c2bc27b179f7d2078ce24eee88d24db874
4
- data.tar.gz: b241a29fbb8b5a942acac80e5a774271f31298d0d5add64b77134988902daf3b
3
+ metadata.gz: 8598a2b44749716a7bf3f75ab494ff6ba4ef327f29d6606ed3fd21ccce7df918
4
+ data.tar.gz: b3f58570a4180cb07bfa2852d3bf0c10160feb9f14039875d6e5182fbb56a368
5
5
  SHA512:
6
- metadata.gz: f201fcc55b9caa48cee99651b6820aeecbf8d5fc655ce475da6d4b42d9e1741222d2611428bf98f5952e8a0df21d47ecba1733dd864eea9851fda3f996d7ec85
7
- data.tar.gz: 749dea0ae5d68830f3de9a49ae216465be1d9542656fb9980896e029e74089aa9335559214ce05eb8f8646e17bc609fe2f626e0b599ae081278649b16bc915b3
6
+ metadata.gz: 5ceafbc0b711d3c0d113e61e9339c9175b6cf18afb08fded9321148d2b3b7ddf1809a9de8de0428f5364820d15de19a58a4b0a811018e6cc210357ccb49e868f
7
+ data.tar.gz: 7e476032ad37744aee63a7f746c81f020684857fedd43ff6468648ce1133280fd3efc7b78bea560ffd69d34b250dc120e05c767a44361eb376d91de54ecd2c35
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
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
+
3
19
  ## 9.2.4 / 2021-10-02
4
20
 
5
21
  * Explicitly require at least version 1.12.5 of nokogiri to avoid a security issue
@@ -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
 
@@ -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
 
@@ -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
 
@@ -6,6 +6,10 @@ 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
@@ -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.4"
4
+ VERSION = "9.2.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: publify_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.2.4
4
+ version: 9.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matijs van Zuijlen
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2021-10-02 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
@@ -694,6 +694,7 @@ files:
694
694
  - app/controllers/text_controller.rb
695
695
  - app/controllers/textfilter_controller.rb
696
696
  - app/controllers/theme_controller.rb
697
+ - app/controllers/users/registrations_controller.rb
697
698
  - app/controllers/xml_controller.rb
698
699
  - app/helpers/admin/base_helper.rb
699
700
  - app/helpers/admin/feedback_helper.rb
@@ -968,6 +969,7 @@ files:
968
969
  - lib/publify_core/testing_support/feed_assertions.rb
969
970
  - lib/publify_core/testing_support/fixtures/exploit.svg
970
971
  - lib/publify_core/testing_support/fixtures/fakepng.png
972
+ - lib/publify_core/testing_support/fixtures/just_some.html
971
973
  - lib/publify_core/testing_support/fixtures/otherfile.txt
972
974
  - lib/publify_core/testing_support/fixtures/testfile.png
973
975
  - lib/publify_core/testing_support/fixtures/testfile.txt