Reject unauthorized access with GitHub PATs
Description
Vela CI/CD framework 0.7.0–0.7.4 allows malicious users to obtain secrets via injected credentials in the ~/.netrc file.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Vela CI/CD framework 0.7.0–0.7.4 allows malicious users to obtain secrets via injected credentials in the ~/.netrc file.
Vulnerability
Vela is a Pipeline Automation (CI/CD) framework written in Golang. In version 0.7.0, an authentication mechanism was added that could allow a malicious user to obtain secrets by leveraging injected credentials stored in the ~/.netrc file. This vulnerability affects Vela server versions 0.7.0 through 0.7.4. The fix was introduced in version 0.7.5 [1][2].
Exploitation
An attacker with the ability to trigger a build pipeline and inject malicious credentials into the ~/.netrc file can exploit this flaw. The authentication mechanism in affected versions processes the .netrc file and may inadvertently expose secrets to unauthorized users. The exact exploitation steps are not detailed in the available references, but the vulnerability requires some level of access to the Vela instance to launch a build [2][3].
Impact
Successful exploitation allows an attacker to obtain secrets that are typically protected within Vela's CI/CD pipelines. This could lead to unauthorized access to sensitive data, including credentials for external services. The privilege level of the compromise is that of a user who can trigger builds, potentially escalating to broader system compromise if the exposed secrets grant elevated permissions [1][2].
Mitigation
The vulnerability is fixed in Vela server version 0.7.5. Users should upgrade to this version or later. No workarounds are mentioned in the available references. The advisory does not indicate that this CVE is listed in the Known Exploited Vulnerabilities (KEV) catalog [2][3].
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.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/go-vela/serverGo | >= 0.7.0, < 0.7.5 | 0.7.5 |
Affected products
2Patches
1cb4352918b8efix: add check for token (#337)
4 files changed · +85 −1
go.mod+1 −0 modified@@ -16,6 +16,7 @@ require ( github.com/go-vela/types v0.7.4 github.com/google/go-cmp v0.5.4 github.com/google/go-github/v29 v29.0.3 + github.com/google/go-github/v33 v33.0.0 github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.2.0 github.com/hashicorp/go-hclog v0.10.0 // indirect
go.sum+2 −0 modified@@ -233,6 +233,8 @@ github.com/google/go-github/v24 v24.0.1 h1:KCt1LjMJEey1qvPXxa9SjaWxwTsCWSq6p2Ju5 github.com/google/go-github/v24 v24.0.1/go.mod h1:CRqaW1Uns1TCkP0wqTpxYyRxRjxwvKU/XSS44u6X74M= github.com/google/go-github/v29 v29.0.3 h1:IktKCTwU//aFHnpA+2SLIi7Oo9uhAzgsdZNbcAqhgdc= github.com/google/go-github/v29 v29.0.3/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= +github.com/google/go-github/v33 v33.0.0 h1:qAf9yP0qc54ufQxzwv+u9H0tiVOnPJxo0lI/JXqw3ZM= +github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
source/github/authentication.go+46 −1 modified@@ -9,10 +9,12 @@ import ( "errors" "fmt" "net/http" + "net/url" + "strings" "github.com/go-vela/server/random" - "github.com/go-vela/types/library" + "github.com/google/go-github/v33/github" "github.com/sirupsen/logrus" ) @@ -110,6 +112,49 @@ func (c *client) AuthenticateToken(r *http.Request) (*library.User, error) { return nil, errors.New("no token provided") } + // create http client to connect to GitHub + // + // nolint: lll // ignore long line length due to variable names + transport := github.BasicAuthTransport{Username: c.OConfig.ClientID, Password: c.OConfig.ClientSecret} + // create client to connect to GitHub API + client := github.NewClient(transport.Client()) + // check if github url was set + if c.URL != "" && c.URL != "https://github.com" { + // check if address has trailing slash + if !strings.HasSuffix(c.URL, "/") { + // add trailing slash + c.URL = c.URL + "/api/v3/" + } + // parse the provided url into url type + enterpriseURL, err := url.Parse(c.URL) + if err != nil { + return nil, err + } + // set the base and upload url + client.BaseURL = enterpriseURL + client.UploadURL = enterpriseURL + } + // check if the provided token was created by Vela + _, resp, err := client.Authorizations.Check(context.Background(), c.OConfig.ClientID, token) + // check if the error is of type ErrorResponse + if gerr, ok := err.(*github.ErrorResponse); ok { + // check the status code + switch gerr.Response.StatusCode { + // 404 is expected when non vela token is used + case http.StatusNotFound: + break + default: + return nil, err + } + } else if err != nil { + return nil, err + } + + // return error if the token was created by Vela + if resp.StatusCode != http.StatusNotFound { + return nil, errors.New("token must not be created by vela") + } + u, err := c.Authorize(token) if err != nil { return nil, err
source/github/authentication_test.go+36 −0 modified@@ -384,6 +384,42 @@ func TestGithub_Authenticate_Invalid_Token(t *testing.T) { } } +func TestGithub_Authenticate_Vela_Token(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodPost, "/authenticate/token", nil) + context.Request.Header.Set("Token", "vela") + + engine.GET("/api/v3/user", func(c *gin.Context) { + c.Header("Content-Type", "application/json") + c.Status(http.StatusOK) + c.File("testdata/user.json") + }) + + engine.POST("/api/v3/applications/foo/token", func(c *gin.Context) { + c.Header("Content-Type", "application/json") + c.Status(http.StatusOK) + }) + + s := httptest.NewServer(engine) + defer s.Close() + + client, _ := NewTest(s.URL) + + // run test + _, err := client.AuthenticateToken(context.Request) + if resp.Code != http.StatusOK { + t.Errorf("Authenticate returned %v, want %v", resp.Code, http.StatusOK) + } + + if err == nil { + t.Error("Authenticate should have returned err") + } +} + func TestGithub_LoginWCreds(t *testing.T) { // setup context gin.SetMode(gin.TestMode)
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-8j3f-mhq8-gmh4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21432ghsaADVISORY
- github.com/go-vela/server/commit/cb4352918b8ecace9fe969b90404d337b0744d46ghsax_refsource_MISCWEB
- github.com/go-vela/server/pull/337ghsax_refsource_MISCWEB
- github.com/go-vela/server/releases/tag/v0.7.5ghsax_refsource_MISCWEB
- github.com/go-vela/server/security/advisories/GHSA-8j3f-mhq8-gmh4ghsax_refsource_CONFIRMWEB
- pkg.go.dev/github.com/go-vela/serverghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.