FIX: Mitigate issue where legacy pre-secure hotlinked media would not be redownloaded (#8802)

Basically, say you had already downloaded a certain image from a certain URL
using pull_hotlinked_images and the onebox. The upload would be stored
by its sha as an upload record. Whenever you linked to the same URL again
in a post (e.g. in our case an og:image on review.discourse) we would
would reuse the original upload record because of the sha1.

However when you turned on secure media this could cause problems as
the first post that uses that upload after secure media is enabled
will set the access control post for the upload to the new post.
Then if the post is deleted every single onebox/link to that same image
URL will fail forever with 403 as the secure-media-uploads URL fails
if the access control post has been deleted.

To fix this when cooking posts and pulling hotlinked images, we only
allow using an original upload by URL if its access control post
matches the current post, and if the original_sha1 is filled in,
meaning it was uploaded AFTER secure media was enabled. otherwise
we just redownload the media again to be safe, as the URL will always
be new then.
This commit is contained in:
Martin Brennan
2020-01-29 10:11:38 +10:00
committed by GitHub
parent 20e7fb1c95
commit ab3bda6cd0
9 changed files with 183 additions and 28 deletions

View File

@@ -56,7 +56,7 @@ module Jobs
src = original_src = node['src'] || node['href']
src = "#{SiteSetting.force_https ? "https" : "http"}:#{src}" if src.start_with?("//")
if should_download_image?(src)
if should_download_image?(src, post)
begin
# have we already downloaded that file?
schemeless_src = remove_scheme(original_src)
@@ -89,6 +89,7 @@ module Jobs
has_new_broken_image = true
end
end
# have we successfully downloaded that file?
if downloaded_urls[src].present?
escaped_src = Regexp.escape(original_src)
@@ -163,7 +164,7 @@ module Jobs
doc.css(".lightbox img[src]")
end
def should_download_image?(src)
def should_download_image?(src, post = nil)
# make sure we actually have a url
return false unless src.present?
@@ -174,7 +175,15 @@ module Jobs
# Someone could hotlink a file from a different site on the same CDN,
# so check whether we have it in this database
return !Upload.get_from_url(src)
#
# if the upload already exists and is attached to a different post,
# or the original_sha1 is missing meaning it was created before secure
# media was enabled, then we definitely want to redownload again otherwise
# we end up reusing existing uploads which may be linked to many posts
# already.
upload = Upload.consider_for_reuse(Upload.get_from_url(src), post)
return !upload.present?
end
# Don't download non-local images unless site setting enabled