Severity: Medium
Problem
src/extension/context.ts:59–66 passes every credential from the active context to every extension with no scoping by declared service need:
export function buildContextEnv (config: ResolvedConfig): EnvMap {
const env: EnvMap = {}
const { elasticsearch, kibana, cloud } = config.context
if (elasticsearch != null) Object.assign(env, serviceEnv('ELASTIC_ES', elasticsearch))
if (kibana != null) Object.assign(env, serviceEnv('ELASTIC_KIBANA', kibana))
if (cloud != null) Object.assign(env, serviceEnv('ELASTIC_CLOUD', cloud))
return env
}
When the active context contains a Cloud credential, every extension receives ELASTIC_CLOUD_API_KEY, even if it does not use the Cloud API.
Each credential carries the privileges assigned when it was issued. A Cloud API key may authorize organization- or deployment-management operations, while Elasticsearch and Kibana credentials may also be broadly privileged. Passing credentials for unrelated services therefore unnecessarily expands an extension's available authority.
The README documents six variables but context.ts exports up to ten — ELASTIC_ES_USERNAME, ELASTIC_ES_PASSWORD, ELASTIC_KIBANA_USERNAME, and ELASTIC_KIBANA_PASSWORD are omitted. Extension authors who rely solely on the README do not know their process environment contains basic-auth passwords.
Fix
Short-term: Require extensions to declare the services they need in their manifest or extension registry entry. Only pass credentials for declared services:
{
"elastic": {
"services": ["elasticsearch"]
}
}
buildContextEnv reads this declaration and omits ELASTIC_CLOUD_* and ELASTIC_KIBANA_* entirely for an extension declaring only "elasticsearch".
At installation, display the requested credential scopes, require confirmation, and persist the approved scopes in the registry. On upgrade, require renewed consent before granting additional services. Fix the README table to document all ten exported variables.
- Provide an
elastic extension inspect <name> command showing: source, installed version or commit, entrypoint, declared credential scopes, and the environment variables the extension will receive.
- Fail closed when the extension manifest has no credential declaration. Do not treat absence as a grant of all credentials.
Risk
Medium. A compromised extension receives the Cloud credential and whatever management-plane privileges that credential carries. Least-privilege gap, not privilege escalation.
Copied from the security review in elastic/infosec#27626 (ECLI-006).
Severity: Medium
Problem
src/extension/context.ts:59–66 passes every credential from the active context to every extension with no scoping by declared service need:
When the active context contains a Cloud credential, every extension receives
ELASTIC_CLOUD_API_KEY, even if it does not use the Cloud API.Each credential carries the privileges assigned when it was issued. A Cloud API key may authorize organization- or deployment-management operations, while Elasticsearch and Kibana credentials may also be broadly privileged. Passing credentials for unrelated services therefore unnecessarily expands an extension's available authority.
The README documents six variables but
context.tsexports up to ten —ELASTIC_ES_USERNAME,ELASTIC_ES_PASSWORD,ELASTIC_KIBANA_USERNAME, andELASTIC_KIBANA_PASSWORDare omitted. Extension authors who rely solely on the README do not know their process environment contains basic-auth passwords.Fix
Short-term: Require extensions to declare the services they need in their manifest or extension registry entry. Only pass credentials for declared services:
{ "elastic": { "services": ["elasticsearch"] } }buildContextEnvreads this declaration and omitsELASTIC_CLOUD_*andELASTIC_KIBANA_*entirely for an extension declaring only"elasticsearch".At installation, display the requested credential scopes, require confirmation, and persist the approved scopes in the registry. On upgrade, require renewed consent before granting additional services. Fix the README table to document all ten exported variables.
elastic extension inspect <name>command showing: source, installed version or commit, entrypoint, declared credential scopes, and the environment variables the extension will receive.Risk
Medium. A compromised extension receives the Cloud credential and whatever management-plane privileges that credential carries. Least-privilege gap, not privilege escalation.
Copied from the security review in elastic/infosec#27626 (ECLI-006).