SECURITY: Reduce maximum size of SVG sprite cache to prevent DoS

Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
This commit is contained in:
Daniel Waterworth
2023-09-01 12:22:58 -05:00
committed by Roman Rizzi
parent e3a2446874
commit 290306a932
6 changed files with 137 additions and 26 deletions

View File

@ -244,6 +244,8 @@ module SvgSprite
THEME_SPRITE_VAR_NAME = "icons-sprite"
MAX_THEME_SPRITE_SIZE = 512.kilobytes
def self.preload
settings_icons
group_icons
@ -298,37 +300,45 @@ module SvgSprite
def self.theme_svgs(theme_id)
if theme_id.present?
theme_ids = Theme.transform_ids(theme_id)
cache
.defer_get_set_bulk(
Theme.transform_ids(theme_id),
lambda { |theme_id| "theme_svg_sprites_#{theme_id}" },
) do |theme_ids|
theme_field_uploads =
ThemeField.where(
type_id: ThemeField.types[:theme_upload_var],
name: THEME_SPRITE_VAR_NAME,
theme_id: theme_ids,
).pluck(:upload_id)
get_set_cache("theme_svg_sprites_#{theme_ids.join(",")}") do
theme_field_uploads =
ThemeField.where(
type_id: ThemeField.types[:theme_upload_var],
name: THEME_SPRITE_VAR_NAME,
theme_id: theme_ids,
).pluck(:upload_id)
theme_sprites =
ThemeSvgSprite.where(theme_id: theme_ids).pluck(:theme_id, :upload_id, :sprite)
missing_sprites = (theme_field_uploads - theme_sprites.map(&:second))
theme_sprites = ThemeSvgSprite.where(theme_id: theme_ids).pluck(:upload_id, :sprite)
missing_sprites = (theme_field_uploads - theme_sprites.map(&:first))
if missing_sprites.present?
Rails.logger.warn(
"Missing ThemeSvgSprites for theme #{theme_id}, uploads #{missing_sprites.join(", ")}",
)
end
theme_sprites.reduce({}) do |symbols, (upload_id, sprite)|
begin
symbols.merge!(symbols_for("theme_#{theme_id}_#{upload_id}.svg", sprite, strict: false))
rescue => e
if missing_sprites.present?
Rails.logger.warn(
"Bad XML in custom sprite in theme with ID=#{theme_id}. Error info: #{e.inspect}",
"Missing ThemeSvgSprites for theme #{theme_id}, uploads #{missing_sprites.join(", ")}",
)
end
symbols
theme_sprites
.map do |(theme_id, upload_id, sprite)|
begin
[theme_id, symbols_for("theme_#{theme_id}_#{upload_id}.svg", sprite, strict: false)]
rescue => e
Rails.logger.warn(
"Bad XML in custom sprite in theme with ID=#{theme_id}. Error info: #{e.inspect}",
)
end
end
.compact
.to_h
.values_at(*theme_ids)
end
end
.values
.compact
.reduce({}) { |a, b| a.merge!(b) }
else
{}
end