publify_core 9.2.4 → 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: 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