luigidellaquila's Description of Work
PUT /_query/data_source/{name} exposed credentials (S3 access_key/secret_key/session_token, GCS credentials/access_token, Azure connection_string/key/sas_token) through two separate audit-log vectors:
Vector 1 β request body. With xpack.security.audit.logfile.events.emit_request_body: true, the authentication_success event recorded the full body including plaintext credential values.
Vector 2 β query string. The handler accepted the data source definition via the source/source_content_type query parameters. The query string is written unfiltered into url.query on authentication_failed events (audited by default), so credentials in the query string reached the audit log on any failed authentication attempt β regardless of emit_request_body.
Fix
Vector 1 β RestPutDataSourceAction now implements RestRequestFilter, returning credential field names as settings.<name> dotted paths. SecurityRestFilter strips these from the request body before the authentication_success audit event is written.
Vector 2 β The handler now calls contentParser() instead of contentOrSourceParamParser(), rejecting any request that carries the definition in source/source_content_type query parameters with HTTP 400. This mirrors the approach used by RestPutUserAction.
How secret field names flow to the handler
-
DataSourceValidatorgains adefault Set<String> secretSettingNames()(returns empty by default). -
FileDataSourceValidatorgains awithSecretFieldNames(Set<String>)builder method that stores the provider's credential field names. - Each provider plugin (
S3DataSourcePlugin,GcsDataSourcePlugin,AzureDataSourcePlugin) chains.withSecretFieldNames(...)when building its validator. -
EsqlPlugin.createComponents()collects all secret names from registered validators into avolatilefield. -
EsqlPlugin.getRestHandlers()passes the collected names toRestPutDataSourceAction.
Tests
-
AuditIT(integration): two new tests βtestFilteringOfDataSourceCredentialsasserts that credential values are absent from therequest.bodyfield of theauthentication_successaudit event;testDataSourceDefinitionInQueryStringRejectedasserts HTTP 400 when the definition is sent in query params. -
RestPutDataSourceActionTests(unit, new): asserts thatgetFilteredFields()produces the correctsettings.<name>paths for S3, GCS, and Azure credential sets.
Breaking change
Clients that currently send the data source definition in source/source_content_type query parameters will receive HTTP 400. The body-only constraint is intentional and mirrors PUT /_security/user/{name}.
Closes elastic/esql-planning#1990