Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a2f385b

Browse files
committed
Prohibit STOMP clients sending directly to topic/q
Signed-off-by: Josh Kim <[email protected]>
1 parent 2c98104 commit a2f385b

File tree

3 files changed

+43
-19
lines changed

3 files changed

+43
-19
lines changed

stompserver/errors.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const (
1111
invalidSubscriptionError = stompErrorMessage("invalid subscription")
1212
invalidFrameError = stompErrorMessage("invalid frame")
1313
invalidHeaderError = stompErrorMessage("invalid frame header")
14+
invalidSendDestinationError = stompErrorMessage("invalid send destination")
1415
)
1516

1617
type stompErrorMessage string

stompserver/stomp_connection.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,16 +359,22 @@ func (conn *stompConn) handleSend(f *frame.Frame) error {
359359
return unsupportedStompCommandError
360360
}
361361

362-
err := conn.sendReceiptResponse(f)
363-
if err != nil {
364-
return err
365-
}
366-
362+
// no destination triggers an error
367363
dest, ok := f.Header.Contains(frame.Destination)
368364
if !ok {
369365
return invalidFrameError
370366
}
371367

368+
// reject SENDing directly to non-request channels by clients
369+
if !conn.config.IsAppRequestDestination(f.Header.Get(frame.Destination)) {
370+
return invalidSendDestinationError
371+
}
372+
373+
err := conn.sendReceiptResponse(f)
374+
if err != nil {
375+
return err
376+
}
377+
372378
f.Command = frame.MESSAGE
373379
conn.events <- &ConnEvent{
374380
ConnId: conn.GetId(),

stompserver/stomp_connection_test.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -415,20 +415,16 @@ func TestStompConn_Subscribe(t *testing.T) {
415415
frame.Id, "sub-id",
416416
frame.Destination, "/topic/test")
417417

418-
rawConn.incomingFrames <- frame.New(frame.SEND, frame.Destination, "/topic/dest")
419-
420-
// verify that there will be no SubscribeToTopic con event for the
421-
// the second request.
422-
e = <- events
423-
assert.Equal(t, e.eventType, IncomingMessage)
418+
// verify that there was no second subscription created for the same subscription id
419+
assert.Equal(t, e.sub, stompConn.subscriptions["sub-id"])
424420
}
425421

426422
func TestStompConn_SendNotConnected(t *testing.T) {
427-
_, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil)
423+
_, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil)
428424

429425
rawConn.incomingFrames <- frame.New(
430426
frame.SEND,
431-
frame.Destination, "/topic/test")
427+
frame.Destination, "/pub/test")
432428

433429
e := <- events
434430
assert.Equal(t, e.eventType, ConnectionClosed)
@@ -439,7 +435,7 @@ func TestStompConn_SendNotConnected(t *testing.T) {
439435
}
440436

441437
func TestStompConn_SendMissingDestinationHeader(t *testing.T) {
442-
stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil)
438+
stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil)
443439

444440
rawConn.SendConnectFrame()
445441

@@ -458,15 +454,36 @@ func TestStompConn_SendMissingDestinationHeader(t *testing.T) {
458454
assert.Equal(t, stompConn.state, closed)
459455
}
460456

457+
func TestStompConn_Send_InvalidSend(t *testing.T) {
458+
_, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil)
459+
460+
rawConn.SendConnectFrame()
461+
462+
e := <- events
463+
assert.Equal(t, e.eventType, ConnectionEstablished)
464+
assert.Equal(t, len(rawConn.sentFrames), 1)
465+
verifyFrame(t, rawConn.sentFrames[0], frame.New(frame.CONNECTED), false)
466+
467+
// try sending a frame to a topic channel directly not request channel
468+
rawConn.incomingFrames <- frame.New(frame.SEND,
469+
frame.Destination, "/topic/test")
470+
e = <- events
471+
472+
assert.Equal(t, e.eventType, ConnectionClosed)
473+
assert.Equal(t, len(rawConn.sentFrames), 2)
474+
verifyFrame(t, rawConn.sentFrames[1], frame.New(frame.ERROR,
475+
frame.Message, invalidSendDestinationError.Error()), true)
476+
}
477+
461478
func TestStompConn_Send(t *testing.T) {
462-
_, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil)
479+
_, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil)
463480

464481
rawConn.SendConnectFrame()
465482

466483
e := <- events
467484
assert.Equal(t, e.eventType, ConnectionEstablished)
468485

469-
msgF := frame.New(frame.SEND, frame.Destination, "/topic/test")
486+
msgF := frame.New(frame.SEND, frame.Destination, "/pub/test")
470487

471488
rawConn.incomingFrames <- msgF
472489

@@ -476,7 +493,7 @@ func TestStompConn_Send(t *testing.T) {
476493
assert.Equal(t, e.frame.Command, frame.MESSAGE)
477494

478495
rawConn.incomingFrames <- frame.New(frame.SEND,
479-
frame.Destination, "/topic/test", frame.Receipt, "receipt-id")
496+
frame.Destination, "/pub/test", frame.Receipt, "receipt-id")
480497

481498
e = <- events
482499
assert.Equal(t, e.eventType, IncomingMessage)
@@ -710,7 +727,7 @@ func TestStompConn_WriteErrorDuringConnect(t *testing.T) {
710727
}
711728

712729
func TestStompConn_WriteErrorDuringSend(t *testing.T) {
713-
stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{}), nil)
730+
stompConn, rawConn, events := getTestStompConn(NewStompConfig(0, []string{"/pub/"}), nil)
714731

715732
rawConn.SendConnectFrame()
716733

@@ -720,7 +737,7 @@ func TestStompConn_WriteErrorDuringSend(t *testing.T) {
720737
rawConn.nextWriteErr = errors.New("write error")
721738
rawConn.incomingFrames <- frame.New(
722739
frame.SEND,
723-
frame.Destination, "/topic",
740+
frame.Destination, "/pub/",
724741
frame.Receipt, "receipt-id")
725742

726743
e = <- events

0 commit comments

Comments
 (0)