Skip to content

Commit 033acf8

Browse files
authored
Merge pull request rails#51279 from gabriel-amaral/gabriel-amaral/form_path-fix-fragment
Handling relative paths with extra URI parts.
2 parents 6e0b89c + 2cd7460 commit 033acf8

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

actionpack/lib/action_controller/metal/request_forgery_protection.rb

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -637,12 +637,18 @@ def normalize_action_path(action_path) # :doc:
637637
uri = URI.parse(action_path)
638638

639639
if uri.relative? && (action_path.blank? || !action_path.start_with?("/"))
640-
uri = URI.parse(request.path)
641-
# add the action path to the request.path
642-
uri.path += "/#{action_path}"
643-
# relative path with "./path"
644-
uri.path.gsub!("/./", "/")
640+
normalize_relative_action_path(uri.path)
641+
else
642+
uri.path.chomp("/")
645643
end
644+
end
645+
646+
def normalize_relative_action_path(rel_action_path) # :doc:
647+
uri = URI.parse(request.path)
648+
# add the action path to the request.path
649+
uri.path += "/#{rel_action_path}"
650+
# relative path with "./path"
651+
uri.path.gsub!("/./", "/")
646652

647653
uri.path.chomp("/")
648654
end

actionpack/test/controller/request_forgery_protection_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,32 @@ def test_handles_relative_paths_with_dot
11511151
assert_response :success
11521152
end
11531153

1154+
def test_handles_query_string
1155+
get :index, params: { form_path: "./post_one?a=b" }
1156+
1157+
form_token = assert_presence_and_fetch_form_csrf_token
1158+
1159+
# This is required because PATH_INFO isn't reset between requests.
1160+
@request.env["PATH_INFO"] = "/per_form_tokens/post_one"
1161+
assert_nothing_raised do
1162+
post :post_one, params: { custom_authenticity_token: form_token }
1163+
end
1164+
assert_response :success
1165+
end
1166+
1167+
def test_handles_fragment
1168+
get :index, params: { form_path: "./post_one#a" }
1169+
1170+
form_token = assert_presence_and_fetch_form_csrf_token
1171+
1172+
# This is required because PATH_INFO isn't reset between requests.
1173+
@request.env["PATH_INFO"] = "/per_form_tokens/post_one"
1174+
assert_nothing_raised do
1175+
post :post_one, params: { custom_authenticity_token: form_token }
1176+
end
1177+
assert_response :success
1178+
end
1179+
11541180
def test_ignores_origin_during_generation
11551181
get :index, params: { form_path: "https://example.com/per_form_tokens/post_one/" }
11561182

0 commit comments

Comments
 (0)