FIX: Rate limit and hijack certificate generation. (#8215)

To eliminate a DDOS attack vector, we're taking the following measures:

The endpoint will be rate-limited to 3 requests every 60 seconds (per user).
A 24 hours max-age cache header is sent with the response.
The route will be hijacked to generate the certificate in the background.
This commit is contained in:
Roman Rizzi
2019-10-21 13:14:15 -03:00
committed by GitHub
parent d5121e5ddb
commit 835d2be4da
4 changed files with 53 additions and 39 deletions

View File

@ -2,8 +2,9 @@
module DiscourseNarrativeBot
class CertificateGenerator
def initialize(user, date)
def initialize(user, date, avatar_url)
@user = user
@avatar_url = avatar_url
date =
begin
@ -21,29 +22,36 @@ module DiscourseNarrativeBot
end
def new_user_track
width = 538.583 # Default width for the SVG
ApplicationController.render(inline: File.read(File.expand_path('../templates/new_user.svg.erb', __FILE__)),
assigns: { width: width,
discobot_user: @discobot_user,
date: @date,
avatar_url: base64_image_link(avatar_url),
logo_group: logo_group(55, width, 350),
name: name })
svg_default_width = 538.583
logo_container = logo_group(55, svg_default_width, 350)
ApplicationController.render(inline: read_template('new_user'), assigns: assign_options(svg_default_width, logo_container))
end
def advanced_user_track
width = 722.8 # Default width for the SVG
ApplicationController.render(inline: File.read(File.expand_path('../templates/advanced_user.svg.erb', __FILE__)),
assigns: { width: width,
discobot_user: @discobot_user,
date: @date,
avatar_url: base64_image_link(avatar_url),
logo_group: logo_group(40, width, 280),
name: name })
svg_default_width = 722.8
logo_container = logo_group(40, svg_default_width, 280)
ApplicationController.render(inline: read_template('advanced_user'), assigns: assign_options(svg_default_width, logo_container))
end
private
def read_template(filename)
File.read(File.expand_path("../templates/#{filename}.svg.erb", __FILE__))
end
def assign_options(width, logo_group)
{
width: width,
discobot_user: @discobot_user,
date: @date,
avatar_url: base64_image_link(@avatar_url),
logo_group: logo_group,
name: name
}
end
def name
@user.username.titleize
end
@ -84,9 +92,5 @@ module DiscourseNarrativeBot
rescue OpenURI::HTTPError
# Ignore if fetching image returns a non 200 response
end
def avatar_url
UrlHelper.absolute(Discourse.base_uri + @user.avatar_template.gsub('{size}', '250'))
end
end
end