mlevkov opened a new issue, #3802:
URL: https://github.com/apache/iggy/issues/3802
## Summary
The connectors runtime control API returns plugin configuration verbatim,
credentials included, and its authentication is disabled by default. The
default bind is loopback, so this is a hardening gap rather than a remote
disclosure — but nothing warns an operator who moves the listener off loopback,
which is a normal thing to do when running the runtime in a container.
Filing publicly rather than to the security list because of the loopback
default. Happy to move it if maintainers judge otherwise.
## Configuration returns secrets
`core/connectors/runtime/src/api/source.rs::get_source_plugin_config` serves
`source.config.plugin_config` as-is:
```rust
let (content_type, config) = map_connector_config(config, format)?;
```
`plugin_config` is the raw `serde_json::Value` parsed from TOML, so every
credential an operator configured comes back in the clear. `GET
/sources/{key}/configs` and `/configs/{version}` and `/configs/active` return
the enclosing `SourceConfig`, which carries the same field. The sink routes
mirror all of it. A repo-wide grep finds no redaction anywhere in
`core/connectors/runtime/src` — the only `redact` hits are log-line truncation
in `stream.rs`.
For most connectors that means a database connection string. For
`iggy_connector_http_source` (#3798) it also means a `management_token`, which
mints webhook endpoints, and each endpoint's HMAC secret.
## Authentication is off by default
`core/connectors/runtime/src/api/auth.rs::resolve_api_key`:
```rust
if context.api_key.expose_secret().is_empty() {
return Ok(next.run(request).await);
}
```
`core/connectors/runtime/config.toml` ships:
```toml
address = "127.0.0.1:8081"
api_key = "" # Optional API key for authentication to be passed as `api-key`
header
```
So out of the box the API is unauthenticated. Loopback confines that to
local processes, which is a defensible posture for an admin API — the gap is
that the two defaults compose into "any local process can read every connector
credential", and an operator who changes `address` to `0.0.0.0` to reach the
API from outside a container gets an unauthenticated endpoint serving
credentials with no warning at any layer.
## Suggested fixes, roughly in order of value
1. Redact credential-bearing fields in the config responses, or gate those
specific routes behind a configured `api_key` regardless of the global default.
2. Log a warning at startup when `api_key` is empty and `address` is not
loopback.
3. Document in the runtime README that the control API returns credentials
in plaintext and should be treated as privileged.
Related: #3801, which is why the plugin-side `SecretString` annotations do
not help here.
Found while preparing #3798, whose README now documents this exposure for
its own users.
--
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]