Skip to content

Commit 8bc7bb7

Browse files
authored
Restrict URL push payloads to http and https schemes (#4595)
Reject data:, javascript:, and other non-http(s) URI schemes when creating URL pushes. Prevents redirect-based XSS via trusted push links (GHSA-76c2-66pg-fj2f).
1 parent 7bc8ae5 commit 8bc7bb7

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

app/models/push.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ def set_default_attributes
224224
end
225225

226226
def valid_url?(url)
227-
!Addressable::URI.parse(url).scheme.nil?
227+
scheme = Addressable::URI.parse(url)&.scheme&.downcase
228+
%w[http https].include?(scheme)
228229
rescue Addressable::URI::InvalidURIError
229230
false
230231
end

test/models/url_test.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,52 @@ class UrlTest < ActiveSupport::TestCase
5757
json = JSON.parse(url.to_json({}))
5858
assert_not json.key?("name")
5959
end
60+
61+
test "should reject data uri payloads" do
62+
url = Push.new(
63+
kind: "url",
64+
payload: "data:text/html,<script>alert(1)</script>"
65+
)
66+
67+
assert_not url.valid?
68+
assert_includes url.errors[:payload], I18n._("must be a valid HTTP or HTTPS URL.")
69+
end
70+
71+
test "should reject javascript uri payloads" do
72+
url = Push.new(
73+
kind: "url",
74+
payload: "javascript:alert(1)"
75+
)
76+
77+
assert_not url.valid?
78+
assert_includes url.errors[:payload], I18n._("must be a valid HTTP or HTTPS URL.")
79+
end
80+
81+
test "should reject ftp uri payloads" do
82+
url = Push.new(
83+
kind: "url",
84+
payload: "ftp://example.com"
85+
)
86+
87+
assert_not url.valid?
88+
assert_includes url.errors[:payload], I18n._("must be a valid HTTP or HTTPS URL.")
89+
end
90+
91+
test "should accept http uri payloads" do
92+
url = Push.new(
93+
kind: "url",
94+
payload: "http://example.com"
95+
)
96+
97+
assert url.valid?
98+
end
99+
100+
test "should accept https uri payloads" do
101+
url = Push.new(
102+
kind: "url",
103+
payload: "https://example.com"
104+
)
105+
106+
assert url.valid?
107+
end
60108
end

0 commit comments

Comments
 (0)