How to save an image from a url with rails active storage?
Just found the answer to my own question. My first instinct was pretty close...
require 'open-uri'class User < ApplicationRecord has_one_attached :avatar before_save :grab_image def grab_image downloaded_image = open("http://www.example.com/image.jpg") self.avatar.attach(io: downloaded_image , filename: "foo.jpg") endend
Update: please note comment below, "you have to be careful not to pass user input to open, it can execute arbitrary code, e.g. open("|date")"
using the down
gem to avoid the security issues of using open-uri:
image = Down.download(image_url)user.image.attach(io: image, filename: "image.jpg")
Like said in the comments, the use of open
or URI.open
is very dangerous, since it can not only access files but also process invocation by prefixing a pipe symbol (e.g. open("| ls")
).
Kernel#open
andURI.open
enable not only file access but also process invocation by prefixing a pipe symbol (e.g.,open("| ls")
). So, it may lead to a serious security risk by using variable input to the argument ofKernel#open
andURI.open
. It would be better to useFile.open
,IO.popen
orURI.parse#open
explicitly.
Extracted from the Rubocop documentation: https://docs.rubocop.org/rubocop/1.8/cops_security.html#securityopen
So, a safer solution would be:
class User < ApplicationRecord has_one_attached :avatar before_save :grab_image def grab_image downloaded_image = URI.parse("http://www.example.com/image.jpg").open avatar.attach(io: downloaded_image, filename: "foo.jpg") endend