On 6 October 2026 the Harbor maintainers released v2.15.3, v2.14.5 and v2.13.6 and published a batch of security advisories against the registry. The serious ones share a theme: robot accounts and project admins could do more than their permissions said. A system robot with "User: Update" could make any user a system administrator, and anyone with push rights could pull images that the vulnerability and signing policies were supposed to block.
The five advisories in the table below had no CVE ID when this was written, so they are tracked by their GitHub advisory IDs.
What's affected
The advisories below list Harbor versions before the fixed releases as affected, and the webhook SSRF goes back to 1.7.0, the first release with webhooks. The fix is v2.15.3, v2.14.5, v2.13.6, or v2.16.0 and later.
| Advisory | Severity | Issue |
|---|---|---|
| GHSA-w5fq-xrhj-j7g2 | High | A system robot with User: Update can set or remove the system administrator flag on any user |
| GHSA-xq2m-cj8w-56v5 | High | A "Cover all projects" robot with a Project permission gets that action on every resource inside every project, including other robots |
| GHSA-2phj-cp9f-qq6w | High | Webhook SSRF: a project admin can point webhooks at internal addresses and the metadata endpoint, and read back error bodies |
| GHSA-wrw5-gmvj-gf23 | Moderate | Pull policies skipped when the puller has push permission and sends a User-Agent containing "cosign" or "notation" |
| GHSA-27f2-qg57-2gwg | Moderate | Immutable tag rules only evaluate their first repository and tag selector |
The same release fixes several lower-impact issues: unbounded decompression of webhook error responses in jobservice, an oracle that let a project admin recover a scanner's credential one character at a time through list filters, a scanner token request that skipped TLS verification, and replication uploads that followed an unvalidated Location header to any host.
Two details make the robot bugs worse in practice. The webhook SSRF and scanner oracle need the project admin role, and with Harbor's default "Project Creation: Everyone", every registered user can create a project and become its admin. And the "Cover all projects" bug let a robot with only "Project: Update" change other projects' robot permissions and reset their secrets, which takes those robots over and locks out their owners.
How to check if you're exposed
Check the version:
curl -s -u "admin:$HARBOR_ADMIN_PASSWORD" \
https://harbor.example.com/api/v2.0/systeminfo | jq -r .harbor_version
The advisories include SQL you can run against Harbor's database. Find system robots that can update users:
SELECT r.id, r.name
FROM robot r
JOIN role_permission rp ON rp.role_type = 'robotaccount' AND rp.role_id = r.id
JOIN permission_policy pp ON pp.id = rp.permission_policy_id
WHERE pp.resource = 'user' AND pp.action = 'update';
Find cover-all robots with Project permissions:
SELECT r.id, r.name, pp.action
FROM robot r
JOIN role_permission rp ON rp.role_type = 'robotaccount' AND rp.role_id = r.id
JOIN permission_policy pp ON pp.id = rp.permission_policy_id
WHERE pp.scope = '/project/*' AND pp.resource = 'project';
Confirm every administrator is expected:
SELECT user_id, username, update_time FROM harbor_user WHERE sysadmin_flag = true;
And review webhook targets for internal addresses:
SELECT id, project_id, name, creator, targets FROM notification_policy;
Look for private IP ranges, localhost, 169.254.169.254 or internal service names.
What to do now
- Upgrade to v2.15.3, v2.14.5, v2.13.6, or v2.16.0 or later.
- Expect behavior changes and plan for them. After the upgrade, webhooks to private, loopback and link-local addresses are rejected and existing ones stop delivering. If you send webhooks to an in-cluster CI system on purpose, the advisory documents
network.allow_private_network_access: trueinharbor.yml, orHARBOR_ALLOW_PRIVATE_NETWORK_ACCESS=trueon both core and jobservice for Helm. That turns the protection off, so only use it if you trust every project admin. - Check content trust signing flows. The User-Agent exemption is gone. In a project that enforces content trust, cosign and notation need to read the manifest before the first signature, and that read is now blocked. The advisory documents
CONTENT_TRUST_LEGACY_SIGNER_PULL_ENABLED=trueon core to restore the old behavior for content trust only. - Review immutable tag rules created through the API or Terraform. The UI stores one pattern per rule, but automation can create several. After the upgrade, the second and later selectors take effect, so pipelines that overwrite those tags will start failing.
- Set Project Creation to Admin Only unless you have a reason not to. It closes off the project admin paths in several of these advisories.
- Split push and pull identities. Give Kubernetes image pull secrets and CD pipelines pull-only robots. The advisory recommends this, plus enforcing signature and vulnerability checks at deploy time with an admission controller.
- Restrict jobservice egress with a NetworkPolicy so it can only reach the webhook destinations you use, block
169.254.169.254, and require IMDSv2 or your provider's equivalent.
Why it matters
A registry sits on the path from build to production, and the controls people trust most are policy settings: "only signed images", "no critical CVEs", "tags can't change". Each of those was quietly weaker than it looked. A policy that a client can skip by changing its User-Agent is a convenience, not a gate. That's why the advisory itself suggests checking signatures again at deploy time.
The robot bugs are the other lesson. Machine identities tend to get broad scopes because it's easier, and their tokens live in CI systems that see a lot of code. When the scope model has a hole, the token that leaks first is usually a robot's.
Try it yourself
Run the cover-all robot query above against a staging Harbor database. For each robot it returns, write down which projects and actions it actually needs, then recreate it with those specific permissions. Repeat for any robot with User: Update, and remove that permission unless it is part of a provisioning job you can name.
Click through it at your own pace, or open it full screen.
Quick check
Who can exploit the webhook SSRF on a default Harbor install?
Any project admin, and with the default Project Creation: Everyone setting, any registered user can create a project and become its admin.
Were users with pull-only permission able to bypass the vulnerability and content trust policies?
No. The advisory says the bypass needed push permission on the project plus a User-Agent containing cosign or notation. Pull-only users were still checked.
Are immutable tag rules created in the Harbor web UI affected?
No. The UI stores each rule with a single pattern. Only rules created or edited through the API, Terraform or other automation can carry several selectors.
Sources
- GHSA-w5fq-xrhj-j7g2: system robot with user:update makes itself a system administrator
- GHSA-xq2m-cj8w-56v5: cover-all robot scope collapses into a global wildcard
- GHSA-2phj-cp9f-qq6w: SSRF in webhook delivery
- GHSA-wrw5-gmvj-gf23: pull policies bypassable via User-Agent
- GHSA-27f2-qg57-2gwg: immutable tag rule matcher
- Harbor v2.15.3 release
- Harbor security advisories