Add fuzz tests for guest account endpoint

pull/1240/head
Rick Carlino 2019-06-17 11:33:34 -05:00
parent 8fbfc8290e
commit 5cacc3c205
2 changed files with 83 additions and 23 deletions

View File

@ -147,51 +147,68 @@ module Api
end
def username_param
@username ||= params["username"]
@username ||= params.fetch("username")
end
def password_param
@password ||= params["password"]
@password ||= params.fetch("password")
end
def routing_key_param
@routing_key ||= params["routing_key"]
@routing_key ||= params.fetch("routing_key")
end
def vhost_param
@vhost ||= params["vhost"]
@vhost ||= params.fetch("vhost")
end
def resource_param
@resource ||= params["resource"]
@resource ||= params.fetch("resource")
end
def permission_param
@permission ||= params["permission"]
@permission ||= params.fetch("permission")
end
def if_topic_is_safe
if !!DEVICE_SPECIFIC_CHANNELS.match(routing_key_param)
if farmbot_guest?
a, b, c = (routing_key_param || "").split(".")
if !["read"].include?(permission_param)
deny
return
end
unless a == GUEST_REGISTRY_ROOT
deny
return
end
if b.nil?
deny
return
end
if b.include?("*")
deny
return
end
if b.include?("#")
deny
return
end
if c.present?
deny
return
end
yield
return
end
if farmbot_guest?
a, b, c = routing_key_param.split(".")
# First check- is it the correct root level?
return if a != GUEST_REGISTRY_ROOT
# Second check- is the user maliciously
# trying to subscribe to
# wildcard topics?
return if b.include?("*")
return if b.include?("#")
# Third check- Ensure subscription is only
# 2 levels deep.
return if c.present?
if !!DEVICE_SPECIFIC_CHANNELS.match(routing_key_param)
yield
return
end

View File

@ -187,4 +187,47 @@ describe Api::RmqUtilsController do
".status_v8.*",
".status_v8"].map { |x| expect(random_channel(x).match(r)).to be }
end
sneaky_topics = ["guest_registry",
"guest_registry.#",
"guest_registry.*",
"guest_registry.#.#",
"guest_registry.*.*",
"guest_registry.#.*",
"guest_registry.*.#",
"guest_registry.#.d3f91ygdrajxn8jk",
"guest_registry.*.d3f91ygdrajxn8jk",
"guest_registry.d3f91ygdrajxn8jk.#",
"guest_registry.d3f91ygdrajxn8jk.*",
"guest_registry.d3f91ygdrajxn8jk.d3f91ygdrajxn8jk",
nil]
# it "invalidates sneaky guest topic names" do
device_8 = "device_#{FactoryBot.create(:device).id}"
possible_attackers = [
# ["username", "permission"]
["farmbot_guest", "read"],
["farmbot_guest", "write"],
["farmbot_guest", "configure"],
["farmbot_guest", nil],
[device_8, "read"],
[device_8, "write"],
[device_8, "configure"],
[device_8, nil],
]
TEST_NAME_TPL = "%{username} %{permission}-ing %{routing_key}"
possible_attackers.map do |(username, permission)|
sneaky_topics.map do |topic|
p = { username: username, permission: permission, routing_key: topic }
it(TEST_NAME_TPL % p) do
post :topic_action, params: p
if response.status == 422
expect(response.body).to(include("malformed"))
else
expect(response.body).to(eq("deny"))
expect(response.status).to eq(403)
end
end
end
end
end