andrewt-8x8 opened a new issue, #25708:
URL: https://github.com/apache/pulsar/issues/25708

   ### Search before reporting
   
   - [x] I searched in the [issues](https://github.com/apache/pulsar/issues) 
and found nothing similar.
   
   
   ### Read release policy
   
   - [x] I understand that [unsupported 
versions](https://pulsar.apache.org/contribute/release-policy/#supported-versions)
 don't get bug fixes. I will attempt to reproduce the issue on a supported 
version of Pulsar client and Pulsar broker.
   
   
   ### User environment
   
   Broker Version 4.0.7
   Any broker OS
   Any broker Java version
   Any WebSocket client
   
   
   ### Issue Description
   
   ### Minimal reproduction steps
   
   Connect to the WebSocket reader endpoint with an invalid `messageId` query 
parameter.
   
   Two examples that both trigger the bug:
   
   1. An improperly URL-encoded base64 message ID that includes a `+` which the 
server interprets as a space (e.g. `CJCj6QEQ+UQwAA==` becomes `CJCj6QEQ 
UQwAA==`).
   
   2. An arbitrary non-base64 string: `?messageId=invalidMessageId`
   
   ### What did you expect to see?
   
   HTTP 400 Bad Request.
   
   ### What did you see instead?
   
   HTTP 500 Internal Server Error in both cases.
   
   **Case 1** — `IllegalArgumentException` from `Base64.getDecoder().decode()`:
   
   ```
   WARN  org.apache.pulsar.websocket.ReaderHandler - [REDACTED] Failed in 
creating reader on topic persistent://REDACTED/REDACTED/REDACTED
   java.lang.IllegalArgumentException: Illegal base64 character 20
        at java.base/java.util.Base64$Decoder.decode0(Unknown Source) ~[?:?]
        at java.base/java.util.Base64$Decoder.decode(Unknown Source) ~[?:?]
        at java.base/java.util.Base64$Decoder.decode(Unknown Source) ~[?:?]
        at 
org.apache.pulsar.websocket.ReaderHandler.getMessageId(ReaderHandler.java:348) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.ReaderHandler.<init>(ReaderHandler.java:95) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.WebSocketReaderServlet.lambda$configure$0(WebSocketReaderServlet.java:44)
 ~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
   ```
   
   **Case 2** — `IOException` wrapping `IndexOutOfBoundsException` from 
`MessageIdImpl.fromByteArray()`:
   
   ```
   WARN  org.apache.pulsar.websocket.ReaderHandler - [REDACTED] Failed in 
creating reader on topic persistent://REDACTED/REDACTED/REDACTED
   java.io.IOException: java.lang.IndexOutOfBoundsException: readerIndex(5) + 
length(641882) exceeds writerIndex(12): UnpooledHeapByteBuf(ridx: 5, widx: 12, 
cap: 12/12)
        at 
org.apache.pulsar.client.impl.MessageIdImpl.fromByteArray(MessageIdImpl.java:93)
 ~[org.apache.pulsar-pulsar-client-original-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.ReaderHandler.getMessageId(ReaderHandler.java:348) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.ReaderHandler.<init>(ReaderHandler.java:95) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.WebSocketReaderServlet.lambda$configure$0(WebSocketReaderServlet.java:44)
 ~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
   Caused by: java.lang.IndexOutOfBoundsException: readerIndex(5) + 
length(641882) exceeds writerIndex(12): UnpooledHeapByteBuf(ridx: 5, widx: 12, 
cap: 12/12)
        at 
io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1442) 
~[io.netty-netty-buffer-4.1.127.Final.jar:4.1.127.Final]
        at 
io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1428) 
~[io.netty-netty-buffer-4.1.127.Final.jar:4.1.127.Final]
        at io.netty.buffer.AbstractByteBuf.skipBytes(AbstractByteBuf.java:971) 
~[io.netty-netty-buffer-4.1.127.Final.jar:4.1.127.Final]
        at 
org.apache.pulsar.common.api.proto.LightProtoCodec.skipUnknownField(LightProtoCodec.java:264)
 ~[org.apache.pulsar-pulsar-common-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.common.api.proto.MessageIdData.parseFrom(MessageIdData.java:304)
 ~[org.apache.pulsar-pulsar-common-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.client.impl.MessageIdImpl.fromByteArray(MessageIdImpl.java:91)
 ~[org.apache.pulsar-pulsar-client-original-4.0.7.jar:4.0.7]
   ```
   
   ### Details
   
   `ReaderHandler.getMessageId()` performs no validation on the `messageId` 
query parameter before passing it to `Base64.getDecoder().decode()` and 
`MessageIdImpl.fromByteArray()`.
   
   `ReaderHandler`'s constructor catches `Exception` during setup but hardcodes 
`HttpServletResponse.SC_INTERNAL_SERVER_ERROR` in the error response. 
`ConsumerHandler` and `ProducerHandler` both call 
`AbstractWebSocketHandler.getErrorCode(e)` instead, which maps 
`IllegalArgumentException` to `SC_BAD_REQUEST` (400).
   
   ### Error messages
   
   ```text
   **Case 1** — `IllegalArgumentException` from `Base64.getDecoder().decode()`:
   
   WARN  org.apache.pulsar.websocket.ReaderHandler - [REDACTED] Failed in 
creating reader on topic persistent://REDACTED/REDACTED/REDACTED
   java.lang.IllegalArgumentException: Illegal base64 character 20
        at java.base/java.util.Base64$Decoder.decode0(Unknown Source) ~[?:?]
        at java.base/java.util.Base64$Decoder.decode(Unknown Source) ~[?:?]
        at java.base/java.util.Base64$Decoder.decode(Unknown Source) ~[?:?]
        at 
org.apache.pulsar.websocket.ReaderHandler.getMessageId(ReaderHandler.java:348) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.ReaderHandler.<init>(ReaderHandler.java:95) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.WebSocketReaderServlet.lambda$configure$0(WebSocketReaderServlet.java:44)
 ~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
   
   
   **Case 2** — `IOException` wrapping `IndexOutOfBoundsException` from 
`MessageIdImpl.fromByteArray()`:
   
   WARN  org.apache.pulsar.websocket.ReaderHandler - [REDACTED] Failed in 
creating reader on topic persistent://REDACTED/REDACTED/REDACTED
   java.io.IOException: java.lang.IndexOutOfBoundsException: readerIndex(5) + 
length(641882) exceeds writerIndex(12): UnpooledHeapByteBuf(ridx: 5, widx: 12, 
cap: 12/12)
        at 
org.apache.pulsar.client.impl.MessageIdImpl.fromByteArray(MessageIdImpl.java:93)
 ~[org.apache.pulsar-pulsar-client-original-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.ReaderHandler.getMessageId(ReaderHandler.java:348) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.ReaderHandler.<init>(ReaderHandler.java:95) 
~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.websocket.WebSocketReaderServlet.lambda$configure$0(WebSocketReaderServlet.java:44)
 ~[org.apache.pulsar-pulsar-websocket-4.0.7.jar:4.0.7]
   Caused by: java.lang.IndexOutOfBoundsException: readerIndex(5) + 
length(641882) exceeds writerIndex(12): UnpooledHeapByteBuf(ridx: 5, widx: 12, 
cap: 12/12)
        at 
io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1442) 
~[io.netty-netty-buffer-4.1.127.Final.jar:4.1.127.Final]
        at 
io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1428) 
~[io.netty-netty-buffer-4.1.127.Final.jar:4.1.127.Final]
        at io.netty.buffer.AbstractByteBuf.skipBytes(AbstractByteBuf.java:971) 
~[io.netty-netty-buffer-4.1.127.Final.jar:4.1.127.Final]
        at 
org.apache.pulsar.common.api.proto.LightProtoCodec.skipUnknownField(LightProtoCodec.java:264)
 ~[org.apache.pulsar-pulsar-common-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.common.api.proto.MessageIdData.parseFrom(MessageIdData.java:304)
 ~[org.apache.pulsar-pulsar-common-4.0.7.jar:4.0.7]
        at 
org.apache.pulsar.client.impl.MessageIdImpl.fromByteArray(MessageIdImpl.java:91)
 ~[org.apache.pulsar-pulsar-client-original-4.0.7.jar:4.0.7]
   ```
   
   ### Reproducing the issue
   
   Connect to the WebSocket reader endpoint with an invalid `messageId` query 
parameter.
   
   Two examples that both trigger the bug:
   
   1. An improperly URL-encoded base64 message ID that includes a `+` which the 
server interprets as a space (e.g. `CJCj6QEQ+UQwAA==` becomes `CJCj6QEQ 
UQwAA==`).
   
   2. An arbitrary non-base64 string: `?messageId=invalidMessageId`
   
   ### Additional information
   
   `ReaderHandler.getMessageId()` performs no validation on the `messageId` 
query parameter before passing it to `Base64.getDecoder().decode()` and 
`MessageIdImpl.fromByteArray()`.
   
   `ReaderHandler`'s constructor catches `Exception` during setup but hardcodes 
`HttpServletResponse.SC_INTERNAL_SERVER_ERROR` in the error response. 
`ConsumerHandler` and `ProducerHandler` both call 
`AbstractWebSocketHandler.getErrorCode(e)` instead, which maps 
`IllegalArgumentException` to `SC_BAD_REQUEST` (400).
   
   ### Are you willing to submit a PR?
   
   - [ ] I'm willing to submit a PR!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to