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

   ### What problem does this PR solve?
   
   Issue Number: close #xxx
   
   Related PR: #xxx
   
   Problem Summary:
   
   Two independent gaps found while surveying the FE/BE HTTP operations APIs, 
both of which are prerequisites for adding a BE-local operations token later. 
Neither changes any authorization decision.
   
   **1. The config update endpoints write secrets to the log in the clear.**
   
   `/api/update_config` takes its argument as `<config name>=<new value>` in 
the query string, and logs the request unconditionally on entry. Three places 
wrote the value out:
   
   - `HttpRequest::debug_string()` masked headers but not query parameters — 
and not the `uri:` line either, which is the raw request URI, query string and 
all. This reaches past the config API: the cluster token travels as the `token` 
parameter of the download endpoints, and `debug_string()` is also what 
`HttpHandlerWithAuth::on_header` logs on every auth failure.
   - `/api/show_config` masked exactly one config, `tls_private_key_password`, 
by name. The BE had no notion of a config being a secret at all.
   - Neither side recorded who changed a config. The BE logged `set_config k=v` 
with no identity; the FE logged nothing on success and printed the value in the 
clear on failure.
   
   **2. `/api/injection_point/{op}` never reached the auth gate.**
   
   `InjectionPointAction` inherited `HttpHandler` directly, whose `on_header()` 
is a plain `return 0`. Six handlers inherit `HttpHandler` directly; the three 
stream load ones parse Basic credentials themselves and forward them to the FE, 
which is deliberate. This one had no authentication code of any kind. It only 
registers under `ENABLE_INJECTION_POINT`, which `build.sh` defaults to `OFF`, 
so production builds do not carry the endpoint — the reason to fix it is to 
leave one shape of handler in the tree, so that a rule against inheriting 
`HttpHandler` directly is easier to state and to review against.
   
   #### How
   
   The BE now marks a config as holding a secret at its declaration, the way it 
already marks one as mutable:
   
   ```cpp
   DECLARE_String_Sensitive(tls_private_key_password);    // config.h
   DEFINE_String_Sensitive(tls_private_key_password, ""); // config.cpp
   ```
   
   Only strings can hold a secret, so only strings get the variant. 
`Register::Field` carries the bit through a defaulted parameter, so no existing 
`DEFINE_FIELD` site changes.
   
   Three configs are marked: `tls_private_key_password` (the one that was 
special-cased) plus `test_s3_ak` / `test_s3_sk`. Everything else in `config.h` 
that matches on name turns out to be a path or a switch, and a `*_key` pattern 
would catch far more ordinary configs than secrets.
   
   `get_config_info()` now runs every value through `mask_config_value()`, 
which also covers `information_schema.backend_configuration`. The rendered mask 
is the same `******` the special case used, so what those two report is 
byte-for-byte unchanged.
   
   Both sides write one audit line per config, whether the update took effect 
or not, at the level the outcome was reported at before (INFO on success, 
WARNING/WARN on failure):
   
   ```
   update_config: remote=127.0.0.1, user=root, config=..., old=..., new=..., 
persist=false, result=OK
   set_config:    remote=127.0.0.1, user=root, config=..., old=..., new=..., 
persist=false, result=OK
   ```
   
   The old value is read before the update and masked like the new one. `user` 
is the identity the caller *presented*: with `enable_all_http_auth` off the 
request is never authenticated, so the field is a claim, and the code says so 
in as many words rather than letting a reader of the log assume otherwise.
   
   Two adjacent defects fixed in passing, both called out so they are not 
mistaken for part of the masking work:
   
   - `handle_update_config` dereferenced the `end()` iterator of the parameter 
map when the request carried no `persist` parameter.
   - `InjectionPointAction`'s header had no include guard.
   
   ### Release note
   
   None
   
   ### Check List (For Author)
   
   - Test
       - [x] Unit Test
       - [x] Manual test (add detailed scripts or steps below)
   
   Unit tests, all green locally on macOS/arm64 (`BUILD_TYPE_UT=Debug`):
   
   ```
   ConfigTest.SensitiveConfigsAreMasked                                OK
   HttpRequestTest.sensitive_query_params_are_masked                   OK
   HttpRequestTest.sensitive_config_names_are_masked_as_query_params   OK
   HttpRequestTest.non_sensitive_query_params_are_untouched            OK
   HttpRequestTest.uri_masking_handles_query_string_edge_cases         OK
   ```
   
   `uri_masking_handles_query_string_edge_cases` covers the shapes a query 
string can take: no query, empty query, a parameter with no value, a trailing 
`&`, an empty value, a url-encoded parameter name (`%74oken`), and a value 
containing `=`.
   
   Manual check that the `ENABLE_INJECTION_POINT` registration still compiles: 
that line is inside `#ifdef ENABLE_INJECTION_POINT`, so a default build does 
not see it. `http_service.cpp` was compiled standalone with 
`-DENABLE_INJECTION_POINT -fsyntax-only`, as were the other six changed 
translation units — the tree builds with unity enabled, which can mask 
incomplete-type errors in a merged TU.
   
   - Behavior changed:
       - [x] Yes.
   
   The log format changes: anything grepping the BE log for `set_config k=v` 
will need to follow the new `update_config:` line. No API response changes, no 
system table changes, and no authorization decision changes anywhere.
   
   - Does this need documentation?
       - [x] No.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   
   https://claude.ai/code/session_012tTm4UwDp7rZ1tjMfDx1Ho
   


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