fix: Do not allow invalid pubsub topic subscription via relay REST api (#3559)

* Check input pubsub topics for REST /relay/v1/subscriptions endpoint
This commit is contained in:
NagyZoltanPeter 2025-09-09 14:04:10 +02:00 committed by GitHub
parent 82926f9dd6
commit a36601ab0d
3 changed files with 36 additions and 4 deletions

View File

@ -44,6 +44,7 @@ suite "Waku v2 Rest API - Relay":
assert false, "Failed to mount relay"
var restPort = Port(0)
let restAddress = parseIpAddress("0.0.0.0")
let restServer = WakuRestServerRef.init(restAddress, restPort).tryGet()
@ -61,8 +62,23 @@ suite "Waku v2 Rest API - Relay":
let shards = @[$shard0, $shard1, $shard2]
# When
let invalidTopic = "/test/2/this/is/a/content/topic/1"
var containsIncorrect = shards
containsIncorrect.add(invalidTopic)
# When contains incorrect pubsub topics, subscribe shall fail
let client = newRestHttpClient(initTAddress(restAddress, restPort))
let errorResponse = await client.relayPostSubscriptionsV1(containsIncorrect)
# Then
check:
errorResponse.status == 400
$errorResponse.contentType == $MIMETYPE_TEXT
errorResponse.data ==
"Invalid pubsub topic(s): @[\"/test/2/this/is/a/content/topic/1\"]"
# when all pubsub topics are correct, subscribe shall succeed
let response = await client.relayPostSubscriptionsV1(shards)
# Then

View File

@ -129,9 +129,10 @@ proc getShardsGetter(node: WakuNode): GetShards =
# fetch pubsubTopics subscribed to relay and convert them to shards
if node.wakuRelay.isNil():
return @[]
let subTopics = node.wakuRelay.subscribedTopics()
let relayShards = topicsToRelayShards(subTopics).valueOr:
error "could not convert relay topics to shards", error = $error
let subscribedTopics = node.wakuRelay.subscribedTopics()
let relayShards = topicsToRelayShards(subscribedTopics).valueOr:
error "could not convert relay topics to shards",
error = $error, topics = subscribedTopics
return @[]
if relayShards.isSome():
let shards = relayShards.get().shardIds

View File

@ -41,6 +41,15 @@ const ROUTE_RELAY_AUTO_SUBSCRIPTIONSV1* = "/relay/v1/auto/subscriptions"
const ROUTE_RELAY_AUTO_MESSAGESV1* = "/relay/v1/auto/messages/{contentTopic}"
const ROUTE_RELAY_AUTO_MESSAGESV1_NO_TOPIC* = "/relay/v1/auto/messages"
proc validatePubSubTopics(topics: seq[PubsubTopic]): Result[void, RestApiResponse] =
let badPubSubTopics = topics.filterIt(RelayShard.parseStaticSharding(it).isErr())
if badPubSubTopics.len > 0:
error "Invalid pubsub topic(s)", PubSubTopics = $badPubSubTopics
return
err(RestApiResponse.badRequest("Invalid pubsub topic(s): " & $badPubSubTopics))
return ok()
proc installRelayApiHandlers*(
router: var RestRouter, node: WakuNode, cache: MessageCache
) =
@ -61,6 +70,9 @@ proc installRelayApiHandlers*(
let req: seq[PubsubTopic] = decodeRequestBody[seq[PubsubTopic]](contentBody).valueOr:
return error
validatePubSubTopics(req).isOkOr:
return error
# Only subscribe to topics for which we have no subscribed topic handlers yet
let newTopics = req.filterIt(not cache.isPubsubSubscribed(it))
@ -87,6 +99,9 @@ proc installRelayApiHandlers*(
let req: seq[PubsubTopic] = decodeRequestBody[seq[PubsubTopic]](contentBody).valueOr:
return error
validatePubSubTopics(req).isOkOr:
return error
# Unsubscribe all handlers from requested topics
for pubsubTopic in req:
cache.pubsubUnsubscribe(pubsubTopic)