Skip to content

Commit 2894d70

Browse files
committed
Return 401 for invalid link-checker-api webhook signature
A correctly-formed request with the wrong signature is an authentication failure, not a malformed request.
1 parent 15a8c67 commit 2894d70

3 files changed

Lines changed: 28 additions & 11 deletions

File tree

app/controllers/admin/link_checker_api_controller.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ def verify_signature
2525

2626
body = request.raw_post
2727
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), webhook_secret_token, body)
28-
head :bad_request unless Rack::Utils.secure_compare(signature, given_signature)
28+
return if Rack::Utils.secure_compare(signature, given_signature)
29+
30+
# Opt out of gds-sso's Warden intercept_401, which would otherwise turn
31+
# this response into a redirect to /auth/gds.
32+
request.env["warden"].custom_failure!
33+
head :unauthorized
2934
end
3035

3136
def webhook_secret_token

test/functional/admin/link_checker_api_controller_test.rb

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,4 @@ def generate_signature(body, key)
5656

5757
assert_response :bad_request
5858
end
59-
60-
test "POST :callback returns 400 when the signature does not match the body" do
61-
LinkCheckerApiReport.any_instance.expects(:mark_report_as_completed).never
62-
63-
body = link_checker_api_batch_report_hash(id: 5, links: [{ uri: @link, status: "ok" }])
64-
request.headers["X-LinkCheckerApi-Signature"] = generate_signature(body.to_json, "wrong-secret")
65-
post :callback, params: body
66-
67-
assert_response :bad_request
68-
end
6959
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
require "test_helper"
2+
3+
class Admin::LinkCheckerApiCallbackTest < ActionDispatch::IntegrationTest
4+
test "returns 401 (not a redirect) when the signature is invalid" do
5+
post admin_link_checker_api_callback_path,
6+
params: { id: 5 }.to_json,
7+
headers: {
8+
"Content-Type" => "application/json",
9+
"X-LinkCheckerApi-Signature" => "invalid",
10+
}
11+
12+
assert_response :unauthorized
13+
end
14+
15+
test "returns 400 when the signature header is missing" do
16+
post admin_link_checker_api_callback_path,
17+
params: { id: 5 }.to_json,
18+
headers: { "Content-Type" => "application/json" }
19+
20+
assert_response :bad_request
21+
end
22+
end

0 commit comments

Comments
 (0)