security: redact username and password in Request::toArray()#37
security: redact username and password in Request::toArray()#37LukasZemanNiceCZ wants to merge 1 commit intomasterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens logging/debug serialization of Elastica\Request by redacting credentials from Request::toArray() so that ES auth details don’t leak into application logs (including slow-query logs that serialize requests).
Changes:
- Redacts
usernameandpasswordfields from the connection parameters returned byRequest::toArray(). - Ensures
Request::toString()/__toString()inherit the same redacted output viatoArray().
Comments suppressed due to low confidence (1)
lib/Elastica/Request.php:213
- Add a unit test to lock in the new behavior (e.g., in
test/Elastica/RequestTest.php) asserting that when aConnectionhasusername/passwordset,Request::toArray()(andtoString()) return***for those fields while leaving non-sensitive connection fields intact. This helps prevent accidental regressions that could reintroduce credential logging.
public function toArray()
{
$data = $this->getParams();
if ($this->_connection) {
$connectionParams = $this->_connection->getParams();
foreach (['username', 'password'] as $sensitiveKey) {
if (isset($connectionParams[$sensitiveKey])) {
$connectionParams[$sensitiveKey] = '***';
}
}
$data['connection'] = $connectionParams;
}
return $data;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $connectionParams = $this->_connection->getParams(); | ||
| foreach (['username', 'password'] as $sensitiveKey) { | ||
| if (isset($connectionParams[$sensitiveKey])) { | ||
| $connectionParams[$sensitiveKey] = '***'; | ||
| } | ||
| } | ||
| $data['connection'] = $connectionParams; |
There was a problem hiding this comment.
Request::toArray() still returns the full connection params array including config (e.g., config['url'], config['headers'], and config['curl']). If config['url'] contains userinfo (e.g. https://user:pass@host) or headers/curl options contain credentials/tokens, those will still be logged even after redacting username/password. Consider redacting sensitive values inside config as well (at least strip userinfo from config['url'] and redact common auth headers/options).
| foreach (['username', 'password'] as $sensitiveKey) { | ||
| if (isset($connectionParams[$sensitiveKey])) { | ||
| $connectionParams[$sensitiveKey] = '***'; | ||
| } | ||
| } |
There was a problem hiding this comment.
This redaction list omits other secret connection params supported by the library, such as aws_secret_access_key / aws_session_token used by Transport\AwsAuthV4 (see lib/Elastica/Transport/AwsAuthV4.php). If those are set directly on the Connection, they will still appear in logs via Request::toArray(). Consider extending the sensitive key list (or using a centralized sanitizer) to cover these keys too.
Description: Redact username and password with
***inRequest::toArray()to prevent credentials from appearing in logsPossible impact: Logging output, any code that relies on
toArray()ortoString()returning real credentialsProblem
Request::toArray()includes the full connection params, includingusernameandpasswordin plaintext. This method is called in two places insideClient::_log():ConnectionExceptionpath — logged aserror:$context->getRequest()->toArray()debug:$context->toArray()Additionally, platform-backend's custom slow query logger also calls
toArray()when logging slow ES requests. This causes ES credentials to appear in application logs (e.g. Kibana) for every slow query.Decision: always redact, no opt-out parameter
We considered adding a
$hideSensitiveData = trueparameter to allow theConnectionExceptionpath to log credentials (potentially useful for debugging which connection failed). This was rejected because:errorlogs in production has the same access as anyone reading slow query logs — the security boundary is the samepasswordshould never appear in logs regardless of contextusernamevisible inConnectionExceptionlogs (while redactingpassword) would add complexity for minimal gainChange
In
Request::toArray(), replaceusernameandpasswordin the connection params with***:Notes
Requestobject, they should callgetConnection()->getParams()directly🤖 Generated with Claude Code