Uh oh!
There was an error while loading. Please reload this page.
[improvement](log) Log the user name of HTTP requests for auditing - #66745
Conversation
hello-stephen
commented
Aug 13, 2026
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
liaoxin01
commented
Aug 13, 2026
/review |
liaoxin01
commented
Aug 13, 2026
run buildall |
Uh oh!
There was an error while loading. Please reload this page.
PR approved by at least one committer and no changes requested. |
PR approved by anyone and no changes requested. |
fd652da to
2a7c34bCompare2a7c34b to
3e76017Compareliaoxin01
commented
Aug 14, 2026
run buildall |
hello-stephen
commented
Aug 14, 2026
FE UT Coverage ReportIncrement line coverage |
hello-stephen
commented
Aug 14, 2026
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
hello-stephen
commented
Aug 14, 2026
FE Regression Coverage ReportIncrement line coverage |
hello-stephen
commented
Aug 14, 2026
TPC-H: Total hot run time: 17763 ms |
hello-stephen
commented
Aug 14, 2026
TPC-DS: Total hot run time: 86588 ms |
hello-stephen
commented
Aug 14, 2026
ClickBench: Total hot run time: 14.76 s |
HttpRequest::debug_string() masks the whole Authorization header, so the BE request log records that a request carried credentials but not whose. An operation such as /api/update_config therefore leaves no trace of who issued it. Keep the user name of HTTP Basic credentials and mask only the password, rendering "<user>:***MASKED***". Every other sensitive header (token, auth-token, auth_code, proxy-authorization), every non-Basic scheme, and any credential that cannot be decoded stays masked in full. The result is a rendering, not the header value: the real one is base64 encoded. FE's BaseController also logged the raw Authorization header at INFO level when it failed to parse it, that is base64(user:password). This is a parse failure rather than an authentication failure, so it runs before the password is verified and the header often carries valid credentials. Only whether the header was absent or malformed is logged now.
3e76017 to
d7ce500Compareliaoxin01
commented
Aug 27, 2026
run buildall |
hello-stephen
commented
Aug 27, 2026
TPC-H: Total hot run time: 16919 ms |
hello-stephen
commented
Aug 27, 2026
TPC-DS: Total hot run time: 81525 ms |
hello-stephen
commented
Aug 27, 2026
ClickBench: Total hot run time: 14.56 s |
hello-stephen
commented
Aug 27, 2026
FE UT Coverage ReportIncrement line coverage |
hello-stephen
commented
Aug 27, 2026
BE UT Coverage ReportIncrement line coverage Increment coverage report
|
hello-stephen
commented
Aug 27, 2026
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
hello-stephen
commented
Aug 27, 2026
FE Regression Coverage ReportIncrement line coverage |
liaoxin01
commented
Aug 28, 2026
run buildall |
hello-stephen
commented
Aug 28, 2026
FE UT Coverage ReportIncrement line coverage |
hello-stephen
commented
Aug 28, 2026
TPC-H: Total hot run time: 17024 ms |
hello-stephen
commented
Aug 28, 2026
TPC-DS: Total hot run time: 83721 ms |
hello-stephen
commented
Aug 28, 2026
ClickBench: Total hot run time: 14.93 s |
hello-stephen
commented
Aug 28, 2026
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
hello-stephen
commented
Aug 28, 2026
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
hello-stephen
commented
Aug 28, 2026
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
hello-stephen
commented
Aug 30, 2026
BE Regression && UT Coverage ReportIncrement line coverage Increment coverage report
|
Uh oh!
There was an error while loading. Please reload this page.
…66745) ### What problem does this PR solve? Problem Summary: `HttpRequest::debug_string()` masks the whole `Authorization` header, so the BE request log shows that a request carried credentials but not whose, leaving operations such as `/api/update_config` without an audit trail. Keep the user name of HTTP Basic credentials and mask only the password, rendering `<user>:***MASKED***`. Every other sensitive header (`token`, `auth-token`, `auth_code`, `proxy-authorization`), every non-Basic scheme, and any credential that cannot be decoded stays masked in full. What is emitted is a rendering, not the header value: the real one is base64 encoded. One more path wrote credentials to the logs in clear text and is fixed as well: FE's `BaseController` logged the raw `Authorization` header, that is `base64(user:password)`, at INFO level when parsing failed. This is a parse failure rather than an authentication failure, so it runs before the password is verified and the header often carries valid credentials. Only whether the header was absent or malformed is logged now. Note: an earlier revision of this PR also rewrote the `permission verification failed` log in `HttpHandlerWithAuth`, which streamed `TCheckAuthRequest` and let the thrift-generated `printTo()` dump `passwd`. #66618 has since landed a fix for that same leak, so this PR was rebased onto it and no longer touches that file. ### Release note None ### Check List (For Author) - Test - [x] Unit Test - [x] Manual test (add detailed scripts or steps below) `HttpRequestTest` covers the rendering of the `Authorization` header: the user name is kept for Basic credentials (including a password containing colons and a case insensitive scheme), while a malformed, undecodable or non-Basic credential and every other sensitive header stay masked in full. Also verified on a single FE + BE cluster that no credential appears in `fe.log`, `be.INFO` or `be.WARNING`. - Behavior changed: - [x] No. - Does this need documentation? - [x] No.
…66745) ### What problem does this PR solve? Problem Summary: `HttpRequest::debug_string()` masks the whole `Authorization` header, so the BE request log shows that a request carried credentials but not whose, leaving operations such as `/api/update_config` without an audit trail. Keep the user name of HTTP Basic credentials and mask only the password, rendering `<user>:***MASKED***`. Every other sensitive header (`token`, `auth-token`, `auth_code`, `proxy-authorization`), every non-Basic scheme, and any credential that cannot be decoded stays masked in full. What is emitted is a rendering, not the header value: the real one is base64 encoded. One more path wrote credentials to the logs in clear text and is fixed as well: FE's `BaseController` logged the raw `Authorization` header, that is `base64(user:password)`, at INFO level when parsing failed. This is a parse failure rather than an authentication failure, so it runs before the password is verified and the header often carries valid credentials. Only whether the header was absent or malformed is logged now. Note: an earlier revision of this PR also rewrote the `permission verification failed` log in `HttpHandlerWithAuth`, which streamed `TCheckAuthRequest` and let the thrift-generated `printTo()` dump `passwd`. #66618 has since landed a fix for that same leak, so this PR was rebased onto it and no longer touches that file. ### Release note None ### Check List (For Author) - Test - [x] Unit Test - [x] Manual test (add detailed scripts or steps below) `HttpRequestTest` covers the rendering of the `Authorization` header: the user name is kept for Basic credentials (including a password containing colons and a case insensitive scheme), while a malformed, undecodable or non-Basic credential and every other sensitive header stay masked in full. Also verified on a single FE + BE cluster that no credential appears in `fe.log`, `be.INFO` or `be.WARNING`. - Behavior changed: - [x] No. - Does this need documentation? - [x] No.
What problem does this PR solve?
Problem Summary:
HttpRequest::debug_string()masks the wholeAuthorizationheader, so the BE request log shows that a request carried credentials but not whose, leaving operations such as/api/update_configwithout an audit trail. Keep the user name of HTTP Basic credentials and mask only the password, rendering<user>:***MASKED***. Every other sensitive header (token,auth-token,auth_code,proxy-authorization), every non-Basic scheme, and any credential that cannot be decoded stays masked in full. What is emitted is a rendering, not the header value: the real one is base64 encoded.One more path wrote credentials to the logs in clear text and is fixed as well: FE's
BaseControllerlogged the rawAuthorizationheader, that isbase64(user:password), at INFO level when parsing failed. This is a parse failure rather than an authentication failure, so it runs before the password is verified and the header often carries valid credentials. Only whether the header was absent or malformed is logged now.Note: an earlier revision of this PR also rewrote the
permission verification failedlog inHttpHandlerWithAuth, which streamedTCheckAuthRequestand let the thrift-generatedprintTo()dumppasswd. #66618 has since landed a fix for that same leak, so this PR was rebased onto it and no longer touches that file.Release note
None
Check List (For Author)
Test
HttpRequestTestcovers the rendering of theAuthorizationheader: the user name is kept for Basic credentials (including a password containing colons and a case insensitive scheme), while a malformed, undecodable or non-Basic credential and every other sensitive header stay masked in full.Also verified on a single FE + BE cluster that no credential appears in
fe.log,be.INFOorbe.WARNING.Behavior changed:
Does this need documentation?