VYPR
Moderate severityNVD Advisory· Published Feb 2, 2021· Updated Aug 4, 2024

CVE-2020-29662

CVE-2020-29662

Description

In Harbor 2.0 before 2.0.5 and 2.1.x before 2.1.2 the catalog’s registry API is exposed on an unauthenticated path.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Harbor v2.0 before 2.0.5 and v2.1.x before 2.1.2 exposes the catalog registry API without authentication, allowing unauthorized access to repository listings.

Vulnerability

Harbor versions 2.0.0 through 2.0.4 and 2.1.0 through 2.1.1 expose the registry catalog API (/v2/_catalog) on an unauthenticated path [1][2][3]. The root cause is an improper URL pattern match in the authentication middleware; the regular expression didn't cover all variants of the catalog URL, allowing requests to bypass security checks [4].

Exploitation

An attacker with network access to the Harbor instance can query the catalog endpoint without any authentication. The vulnerability requires no special privileges or conditions; any unauthenticated HTTP request to /v2/_catalog returns the list of repositories.

Impact

Successful exploitation leaks the entire registry catalog, revealing the names of all repositories. While this is an information disclosure vulnerability, it can aid an attacker in targeting specific repositories for further attacks, such as pulling images or exploiting other vulnerabilities.

Mitigation

The issue is fixed in Harbor 2.0.5 and 2.1.2 [1][2]. The fix tightens the URL pattern to correctly require authentication for the catalog endpoint [4]. Users should upgrade to at least these versions. No workarounds are available.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/goharbor/harborGo
< 2.0.52.0.5
github.com/goharbor/harborGo
>= 2.1.0, < 2.1.22.1.2

Affected products

3

Patches

2
3481722f140e

Fix the pattern to match v2 catalog URI

https://github.com/goharbor/harborDaniel JiangDec 3, 2020via ghsa
2 files changed · +45 1
  • src/server/middleware/patterns.go+1 1 modified
    @@ -27,5 +27,5 @@ var (
     	// V2BlobUploadURLRe is the regular expression for matching the request to v2 handler to upload a blob, the upload uuid currently is not put into a group
     	V2BlobUploadURLRe = regexp.MustCompile(fmt.Sprintf(`^/v2/(?P<%s>%s)/blobs/uploads[/a-zA-Z0-9\-_\.=]*$`, RepositorySubexp, reference.NameRegexp.String()))
     	// V2CatalogURLRe is the regular expression for mathing the request to v2 handler to list catalog
    -	V2CatalogURLRe = regexp.MustCompile(`^/v2/_catalog$`)
    +	V2CatalogURLRe = regexp.MustCompile(`^/v2/_catalog/?$`)
     )
    
  • src/server/middleware/pattern_test.go+44 0 added
    @@ -0,0 +1,44 @@
    +// Copyright Project Harbor Authors
    +//
    +// Licensed under the Apache License, Version 2.0 (the "License");
    +// you may not use this file except in compliance with the License.
    +// You may obtain a copy of the License at
    +//
    +//    http://www.apache.org/licenses/LICENSE-2.0
    +//
    +// Unless required by applicable law or agreed to in writing, software
    +// distributed under the License is distributed on an "AS IS" BASIS,
    +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +// See the License for the specific language governing permissions and
    +// limitations under the License.
    +
    +package middleware
    +
    +import (
    +	"testing"
    +
    +	"github.com/stretchr/testify/assert"
    +)
    +
    +func TestMatchCatalogURLPattern(t *testing.T) {
    +	cases := []struct {
    +		url   string
    +		match bool
    +	}{
    +		{
    +			url:   "/v2/_catalog",
    +			match: true,
    +		},
    +		{
    +			url:   "/v2/_catalog/",
    +			match: true,
    +		},
    +		{
    +			url:   "/v2/_catalog/xxx",
    +			match: false,
    +		},
    +	}
    +	for _, c := range cases {
    +		assert.Equal(t, c.match, len(V2CatalogURLRe.FindStringSubmatch(c.url)) == 1)
    +	}
    +}
    
c7c409a8e5a8

Fix the pattern to match v2 catalog URI

https://github.com/goharbor/harborDaniel JiangDec 3, 2020via ghsa
2 files changed · +24 1
  • src/lib/patterns.go+1 1 modified
    @@ -27,7 +27,7 @@ var (
     	// V2BlobUploadURLRe is the regular expression for matching the request to v2 handler to upload a blob, the upload uuid currently is not put into a group
     	V2BlobUploadURLRe = regexp.MustCompile(fmt.Sprintf(`^/v2/(?P<%s>%s)/blobs/uploads[/a-zA-Z0-9\-_\.=]*$`, RepositorySubexp, reference.NameRegexp.String()))
     	// V2CatalogURLRe is the regular expression for mathing the request to v2 handler to list catalog
    -	V2CatalogURLRe = regexp.MustCompile(`^/v2/_catalog$`)
    +	V2CatalogURLRe = regexp.MustCompile(`^/v2/_catalog/?$`)
     )
     
     // MatchManifestURLPattern checks whether the provided path matches the manifest URL pattern,
    
  • src/lib/patterns_test.go+23 0 modified
    @@ -66,3 +66,26 @@ func TestMatchBlobUploadURLPattern(t *testing.T) {
     	assert.True(t, ok)
     	assert.Equal(t, "library/hello-world", repository)
     }
    +
    +func TestMatchCatalogURLPattern(t *testing.T) {
    +	cases := []struct {
    +		url   string
    +		match bool
    +	}{
    +		{
    +			url:   "/v2/_catalog",
    +			match: true,
    +		},
    +		{
    +			url:   "/v2/_catalog/",
    +			match: true,
    +		},
    +		{
    +			url:   "/v2/_catalog/xxx",
    +			match: false,
    +		},
    +	}
    +	for _, c := range cases {
    +		assert.Equal(t, c.match, len(V2CatalogURLRe.FindStringSubmatch(c.url)) == 1)
    +	}
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.