Date of release: 19 August 2026 Severity: High Affected product: PMM Impacted versions: 3.9.0 and below Summary Percona has recently been made aware of a security vulnerability affecting PMM. We take the security of our products and the protection of our customers’ data with the utmost seriousness. This advisory describes the vulnerability, the immediate steps … Continued
The post Security Advisory: Privileged ClickHouse access through the Grafana data source in PMM appeared first on Percona.
Security Advisory: Privileged ClickHouse access through the Grafana data source in PMM appeared first on MariaDB.org
#!/bin/bash
# Create a least-privilege ClickHouse identity for Grafana and point the
# ClickHouse datasource at it, replacing the default superuser.
set -euo pipefail
CONTAINER=${CONTAINER:-pmm-server}
PMM_HOST=${PMM_HOST:-localhost}
PMM_PORT=${PMM_PORT:-443}
GRAFANA_URL="https://${PMM_HOST}:${PMM_PORT}"
ADMIN_PASS=${ADMIN_PASS:-$(cat /root/pmm-admin-password)}
# Drop-ins are loaded from users.d (users_config defaults to users.xml ->
# users.d), NOT default-users.d.
BOOTSTRAP_XML=/etc/clickhouse-server/users.d/zz-provision-bootstrap.xml
CH_PASS=$(openssl rand -hex 24)
CH_HASH=$(printf '%s' "$CH_PASS" | sha256sum | awk '{print $1}')
BOOT_PASS=$(openssl rand -hex 24)
BOOT_HASH=$(printf '%s' "$BOOT_PASS" | sha256sum | awk '{print $1}')
ch_wait () {
local user=$1 pass=$2 i
for i in $(seq 1 45); do
if docker exec -i "$CONTAINER" clickhouse-client --host 127.0.0.1 \
--user "$user" --password "$pass" -q "SELECT 1" >/dev/null 2>&1; then
return 0
fi
sleep 2
done
echo "ERROR: clickhouse did not accept $user within 90s" >&2
return 1
}
# PMM's ClickHouse default superuser has access_management disabled, so it
# cannot run CREATE USER / GRANT even with its known password. Install a
# short-lived admin to run the DDL instead. Drop-ins must live in users.d;
# and a plaintext <password> is rejected outright at startup because PMM
# ships allow_plaintext_password=0.
docker exec -u root "$CONTAINER" mkdir -p /etc/clickhouse-server/users.d
docker exec -u root -i "$CONTAINER" bash -c "cat > $BOOTSTRAP_XML" <<XMLEOF
<clickhouse>
<users>
<provision_admin>
<password_sha256_hex>$BOOT_HASH</password_sha256_hex>
<networks><ip>127.0.0.1</ip><ip>::1</ip></networks>
<profile>default</profile>
<quota>default</quota>
<access_management>1</access_management>
</provision_admin>
</users>
</clickhouse>
XMLEOF
docker exec -u root "$CONTAINER" chown pmm:root "$BOOTSTRAP_XML"
docker exec -u root "$CONTAINER" supervisorctl restart clickhouse
ch_wait provision_admin "$BOOT_PASS"
# grafana_ro holds SELECT and nothing else. Without the SOURCES family it
# cannot call url(), s3(), mongodb(), remote() or file(); readonly=1
# additionally prevents it overriding server settings such as
# max_http_get_redirects. ALTER runs unconditionally so that re-running
# this script rotates the password rather than failing.
docker exec -i "$CONTAINER" clickhouse-client --host 127.0.0.1 \
--user provision_admin --password "$BOOT_PASS" --multiquery <<SQLEOF
CREATE SETTINGS PROFILE IF NOT EXISTS grafana_ro_profile SETTINGS
readonly = 1, allow_ddl = 0, max_execution_time = 60;
CREATE USER IF NOT EXISTS grafana_ro IDENTIFIED WITH sha256_hash BY '$CH_HASH';
ALTER USER grafana_ro IDENTIFIED WITH sha256_hash BY '$CH_HASH'
SETTINGS PROFILE grafana_ro_profile;
REVOKE ALL ON *.* FROM grafana_ro;
GRANT SELECT ON pmm.* TO grafana_ro;
GRANT SELECT ON default.* TO grafana_ro;
GRANT SELECT ON system.tables TO grafana_ro;
GRANT SELECT ON system.columns TO grafana_ro;
GRANT SELECT ON system.databases TO grafana_ro;
GRANT SELECT ON system.one TO grafana_ro;
GRANT SELECT ON system.numbers TO grafana_ro;
SQLEOF
docker exec -u root "$CONTAINER" rm -f "$BOOTSTRAP_XML"
docker exec -u root "$CONTAINER" supervisorctl restart clickhouse
ch_wait grafana_ro "$CH_PASS"
# Repoint the datasource. The UID is assigned by PMM, so look it up.
DS_UID=$(curl -sk -u "admin:$ADMIN_PASS" "$GRAFANA_URL/graph/api/datasources" \
| jq -r '.[] | select(.type == "grafana-clickhouse-datasource") | .uid' | head -1)
if [ -z "$DS_UID" ]; then
echo "ERROR: no grafana-clickhouse-datasource found" >&2
exit 1
fi
# Transient files hold the CH password; keep them in a private dir and
# always remove them, even if a curl below fails.
umask 077
TMPD=$(mktemp -d)
trap 'rm -rf "$TMPD"' EXIT
curl -sk -u "admin:$ADMIN_PASS" \
"$GRAFANA_URL/graph/api/datasources/uid/$DS_UID" > "$TMPD/ds-ch.json"
jq --arg p "$CH_PASS" \
'.jsonData.username = "grafana_ro" | .secureJsonData.password = $p' \
"$TMPD/ds-ch.json" > "$TMPD/ds-ch.new.json"
curl -sk -u "admin:$ADMIN_PASS" -X PUT -H 'Content-Type: application/json' \
-d @"$TMPD/ds-ch.new.json" \
"$GRAFANA_URL/graph/api/datasources/uid/$DS_UID" >/dev/null
# Fail the build rather than come up believing this worked.
if docker exec -i "$CONTAINER" clickhouse-client --host 127.0.0.1 \
--user grafana_ro --password "$CH_PASS" \
-q "SELECT count() FROM url('http://169.254.169.254/latest/user-data','LineAsString','line String')" \
>/dev/null 2>&1; then
echo "FATAL: grafana_ro can still reach url()" >&2
exit 1
fi
if docker exec -i "$CONTAINER" clickhouse-client --host 127.0.0.1 \
--user grafana_ro --password "$CH_PASS" \
-q "CREATE TABLE default.zz_provision_check (x String) ENGINE=Memory" \
>/dev/null 2>&1; then
echo "FATAL: grafana_ro can still run DDL" >&2
exit 1
fi
unset CH_PASS BOOT_PASS ADMIN_PASS
echo "ClickHouse datasource now authenticates as grafana_ro."
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Percona Monitoring and Management 2.43.0 Preview Release | 0 | 8.39 | 12-09-2024 |
| 2 | Percona Monitoring and Management 3.0.0-Beta – Tech Preview | 0 | 6.72 | 02-12-2024 |
| 3 | How to replace `docker` with `podman` for PMM development | 0 | 5.69 | 27-12-2021 |
| 4 | ClickHouse Monitoring and Observability Decision Points | 0 | 6.12 | 17-04-2026 |
| 5 | ClusterControl 2.5.0 brings ClickHouse support to on-prem, cloud and hybrid environments | 0 | 8.26 | 05-08-2026 |
| 6 | Managing ClickHouse Resources in Multi-Tenant Environments | 0 | 10.48 | 09-06-2026 |
| 7 | ClickHouse Schema Design and Data Modeling | 0 | 5.5 | 17-07-2026 |
| 8 | Hackorum Update: What’s New Since February | 0 | 7.07 | 20-08-2026 |
| 9 | FromDual Performance Monitor 2.2.1 has been released | 0 | 5.36 | 19-02-2026 |
| 10 | Performance Progression of Percona Server for MySQL 8.4 | 0 | 10.72 | 27-08-2026 |