【Ruby / Rails】URI.openを使うと、RuboCopで警告が出た

Railsで開発をしている際に、外部から画像データを参照するためにopen-uriを使用しました。

require 'open-uri'

image_url = "https://example.com/image.jpg"
image_data = URI.open(image_url).read

しかし、RuboCopで警告が出たので、最終的にNet::HTTPに切り替えました。

1. RuboCopの警告内容

警告内容は以下の通りです。

C: Security/Open: The use of URI.open is a serious security risk.

この警告は、URI.openの使用が重大なセキュリティリスクを持つ可能性があるため、注意が必要であることを示しています。

2. なぜURI.openはリスクがあるのか?

open-uriは非常に便利なライブラリですが、特に外部からの入力をそのままURI.openに渡すと、意図しないファイルやリソースが開かれる可能性があります。

これにより、悪意のある攻撃者によってサーバが危険にさらされる可能性があります。

参考:https://qiita.com/jabba/items/7e018139fff586b4a06d

3. URI.parse#openを使用する

ドキュメントを確認すると、URI.parse#openを使用すれば警告は解除されるようでした。

require 'open-uri'

image_url = "https://example.com/image.jpg"
image_data = URI.parse(image_url).open.read

これで実際に警告は解除されました。

4. Net::HTTPを使用する

open-uriではなく、Net::HTTPを使用してデータを取得します。

元のopen-uriを使用したコード:

require 'open-uri'

image_url = "https://example.com/image.jpg"
image_data = URI.open(image_url).read

Net::HTTPを使用したコードへの変更:

require 'net/http'
require 'uri'

image_url = "https://example.com/image.jpg"
url = URI.parse(image_url)

response = Net::HTTP.get_response(url)
if response.is_a?(Net::HTTPSuccess)
  image_data = response.body
else
  puts "Failed to download image: #{response.message}"
end

上記の変更により、URLからのデータのダウンロードはNet::HTTPを使用して行われるようになります。

4. まとめ

Rails開発において、外部の画像データを取得する際にopen-uriを使用すると便利ですが、URI.openの使用にはセキュリティ上のリスクがあるとの警告がRuboCopから示されることがあります。

この警告は、外部からの入力をそのまま使用すると、意図しないリソースのアクセスが生じる可能性があるためです。

安全な取得のための代替策として、URI.parse#openNet::HTTPがありました。