liaoxin01 opened a new pull request, #68462:
URL: https://github.com/apache/doris/pull/68462

   ### What problem does this PR solve?
   
   Problem Summary:
   
   A single raw request to the BE HTTP port takes the whole BE process down:
   
       PUT /api/_http_stream HTTP/1.1
       Host: <be>
       group_commit: async_mode
       Content-Length: not_a_number
   
   The client gets no response and times out, FE then fails queries with
   `No backend available as scan node`, and `SHOW BACKENDS` reports the BE as
   not alive until it is restarted.
   
   Root cause: `HttpStreamAction::_handle_group_commit()` parsed 
`Content-Length`
   with a bare `std::stoll()`. libevent invokes the header hook from its own C
   frames, so the `std::invalid_argument` thrown there unwinds through C code 
and
   terminates the process. `StreamLoadAction::_can_group_commit()` already 
guards
   the same parse - the http stream path was missed. Two more attacker 
controlled
   headers on the same request path have the same defect: `wal_id` in
   `HttpStreamAction::on_chunk_data()`, and the deprecated `auth_code` in
   `parse_basic_auth()`, which every load action calls.
   
   The fix:
   
   - Add `safe_stoll()` next to the existing `safe_stoi()` in `string_util`, and
     parse `Content-Length`, `wal_id` and `auth_code` with it. A malformed value
     now fails the request with `INVALID_ARGUMENT`; a malformed `auth_code` is
     simply an invalid credential, so authentication fails instead.
   - Guard the three libevent hooks in `ev_http_server.cpp`. Handlers are 
expected
     to report failures through `Status`; this is the last resort that keeps a
     missed one from taking the process down - the exception is logged and that
     single request is failed, never the BE. It also covers the numeric parses 
that
     are still unguarded behind other endpoints, for example `segment_index_id` 
in
     `download_binlog_action.cpp` and `reset_value` in `jeprofile_actions.cpp`.
   
   After the fix the request above is answered with an `INVALID_ARGUMENT` status
   and the BE stays alive.
   
   ### Release note
   
   Fix a BE crash that could be triggered remotely by a malformed 
`Content-Length`,
   `wal_id` or `auth_code` header sent to the BE HTTP stream load endpoint.
   
   ### Check List (For Author)
   
   - Test: Unit Test
       - `be/test/util/string_util_test.cpp`: `StringUtilTest.safe_stoll`
       - `be/test/service/http/stream_load_test.cpp`:
         `HttpStreamMalformedContentLengthIsRejected`, 
`HttpStreamMalformedWalIdIsRejected`
       - `be/test/service/http/http_utils_test.cpp`: 
`HttpUtilsTest.parse_auth_code`
       - These cases are new and have been compile verified locally; the BE UT 
run
         itself is left to CI.
   - Behavior changed: Yes. A malformed numeric header is rejected with
     `INVALID_ARGUMENT` (authentication failure for `auth_code`) instead of
     crashing the BE.
   - Does this need documentation: No
   


-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to