mirror of
https://github.com/we-promise/sure.git
synced 2026-05-24 04:54:56 +00:00
Constrain Lunchflow base URL to trusted endpoint (#1768)
* Constrain Lunchflow base URL to trusted endpoint Prevent SSRF by ignoring user-provided Lunchflow base_url values unless they match the canonical Lunchflow HTTPS endpoint. Add model tests covering invalid host/scheme and valid canonicalization behavior. * Linter
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
class LunchflowItem < ApplicationRecord
|
||||
include Syncable, Provided, Unlinking, Encryptable
|
||||
|
||||
DEFAULT_BASE_URL = "https://lunchflow.app/api/v1".freeze
|
||||
|
||||
enum :status, { good: "good", requires_update: "requires_update" }, default: :good
|
||||
|
||||
# Encrypt sensitive credentials and raw payloads if ActiveRecord encryption is configured
|
||||
@@ -154,6 +156,17 @@ class LunchflowItem < ApplicationRecord
|
||||
end
|
||||
|
||||
def effective_base_url
|
||||
base_url.presence || "https://lunchflow.app/api/v1"
|
||||
return DEFAULT_BASE_URL if base_url.blank?
|
||||
|
||||
uri = URI.parse(base_url)
|
||||
return DEFAULT_BASE_URL unless uri.is_a?(URI::HTTPS)
|
||||
return DEFAULT_BASE_URL unless uri.host == "lunchflow.app"
|
||||
return DEFAULT_BASE_URL unless [ "", "/", "/api/v1", "/api/v1/" ].include?(uri.path)
|
||||
return DEFAULT_BASE_URL unless uri.query.blank?
|
||||
return DEFAULT_BASE_URL unless uri.fragment.blank?
|
||||
|
||||
DEFAULT_BASE_URL
|
||||
rescue URI::InvalidURIError
|
||||
DEFAULT_BASE_URL
|
||||
end
|
||||
end
|
||||
|
||||
31
test/models/lunchflow_item_test.rb
Normal file
31
test/models/lunchflow_item_test.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
require "test_helper"
|
||||
|
||||
class LunchflowItemTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
@lunchflow_item = lunchflow_items(:one)
|
||||
end
|
||||
|
||||
test "effective_base_url returns default when base_url blank" do
|
||||
@lunchflow_item.base_url = nil
|
||||
|
||||
assert_equal LunchflowItem::DEFAULT_BASE_URL, @lunchflow_item.effective_base_url
|
||||
end
|
||||
|
||||
test "effective_base_url returns default for non-lunchflow host" do
|
||||
@lunchflow_item.base_url = "https://169.254.169.254/latest/meta-data"
|
||||
|
||||
assert_equal LunchflowItem::DEFAULT_BASE_URL, @lunchflow_item.effective_base_url
|
||||
end
|
||||
|
||||
test "effective_base_url returns default for non-https scheme" do
|
||||
@lunchflow_item.base_url = "http://lunchflow.app/api/v1"
|
||||
|
||||
assert_equal LunchflowItem::DEFAULT_BASE_URL, @lunchflow_item.effective_base_url
|
||||
end
|
||||
|
||||
test "effective_base_url returns canonical default for valid lunchflow url" do
|
||||
@lunchflow_item.base_url = "https://lunchflow.app/api/v1/"
|
||||
|
||||
assert_equal LunchflowItem::DEFAULT_BASE_URL, @lunchflow_item.effective_base_url
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user